Commit faaa9e08 authored by Satya B's avatar Satya B

Applying InnoDB snashot 5.0-ss5406, part 2. Fixes BUG#40565

BUG#40565 - Update Query Results in "1 Row Affected" But Should Be "Zero Rows"

Detailed revision comments:

r5232 | marko | 2009-06-03 14:31:04 +0300 (Wed, 03 Jun 2009) | 21 lines
branches/5.0: Merge r3590 from branches/5.1 in order to fix Bug #40565
(Update Query Results in "1 Row Affected" But Should Be "Zero Rows").

Also, add a test case for Bug #40565.

rb://128 approved by Heikki Tuuri
  ------------------------------------------------------------------------
  r3590 | marko | 2008-12-18 15:33:36 +0200 (Thu, 18 Dec 2008) | 11 lines

  branches/5.1: When converting a record to MySQL format, copy the default
  column values for columns that are SQL NULL.  This addresses failures in
  row-based replication (Bug #39648).

  row_prebuilt_t: Add default_rec, for the default values of the columns in
  MySQL format.

  row_sel_store_mysql_rec(): Use prebuilt->default_rec instead of
  padding columns.

  rb://64 approved by Heikki Tuuri
  ------------------------------------------------------------------------
parent 0158cafa
...@@ -581,6 +581,8 @@ struct row_prebuilt_struct { ...@@ -581,6 +581,8 @@ struct row_prebuilt_struct {
byte* ins_upd_rec_buff;/* buffer for storing data converted byte* ins_upd_rec_buff;/* buffer for storing data converted
to the Innobase format from the MySQL to the Innobase format from the MySQL
format */ format */
const void* default_rec; /* the default values of all columns
(a "default row") in MySQL format */
ulint hint_need_to_fetch_extra_cols; ulint hint_need_to_fetch_extra_cols;
/* normally this is set to 0; if this /* normally this is set to 0; if this
is set to ROW_RETRIEVE_PRIMARY_KEY, is set to ROW_RETRIEVE_PRIMARY_KEY,
......
...@@ -626,6 +626,8 @@ row_create_prebuilt( ...@@ -626,6 +626,8 @@ row_create_prebuilt(
prebuilt->ins_upd_rec_buff = NULL; prebuilt->ins_upd_rec_buff = NULL;
prebuilt->default_rec = NULL;
prebuilt->hint_need_to_fetch_extra_cols = 0; prebuilt->hint_need_to_fetch_extra_cols = 0;
prebuilt->upd_node = NULL; prebuilt->upd_node = NULL;
......
...@@ -2425,6 +2425,7 @@ row_sel_store_mysql_rec( ...@@ -2425,6 +2425,7 @@ row_sel_store_mysql_rec(
ulint i; ulint i;
ut_ad(prebuilt->mysql_template); ut_ad(prebuilt->mysql_template);
ut_ad(prebuilt->default_rec);
ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec_offs_validate(rec, NULL, offsets));
if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) { if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
...@@ -2520,58 +2521,14 @@ row_sel_store_mysql_rec( ...@@ -2520,58 +2521,14 @@ row_sel_store_mysql_rec(
~(byte) (templ->mysql_null_bit_mask); ~(byte) (templ->mysql_null_bit_mask);
} }
} else { } else {
/* MySQL seems to assume the field for an SQL NULL /* MySQL assumes that the field for an SQL
value is set to zero or space. Not taking this into NULL value is set to the default value. */
account caused seg faults with NULL BLOB fields, and
bug number 154 in the MySQL bug database: GROUP BY
and DISTINCT could treat NULL values inequal. */
int pad_char;
mysql_rec[templ->mysql_null_byte_offset] |= mysql_rec[templ->mysql_null_byte_offset] |=
(byte) (templ->mysql_null_bit_mask); (byte) (templ->mysql_null_bit_mask);
switch (templ->type) { memcpy(mysql_rec + templ->mysql_col_offset,
case DATA_VARCHAR: prebuilt->default_rec + templ->mysql_col_offset,
case DATA_BINARY: templ->mysql_col_len);
case DATA_VARMYSQL:
if (templ->mysql_type
== DATA_MYSQL_TRUE_VARCHAR) {
/* This is a >= 5.0.3 type
true VARCHAR. Zero the field. */
pad_char = 0x00;
break;
}
/* Fall through */
case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_MYSQL:
/* MySQL pads all string types (except
BLOB, TEXT and true VARCHAR) with space. */
if (UNIV_UNLIKELY(templ->mbminlen == 2)) {
/* Treat UCS2 as a special case. */
data = mysql_rec
+ templ->mysql_col_offset;
len = templ->mysql_col_len;
/* There are two UCS2 bytes per char,
so the length has to be even. */
ut_a(!(len & 1));
/* Pad with 0x0020. */
while (len) {
*data++ = 0x00;
*data++ = 0x20;
len -= 2;
}
continue;
}
pad_char = 0x20;
break;
default:
pad_char = 0x00;
break;
}
ut_ad(!pad_char || templ->mbminlen == 1);
memset(mysql_rec + templ->mysql_col_offset,
pad_char, templ->mysql_col_len);
} }
} }
......
create table bug40565(value decimal(4,2)) engine=innodb;
insert into bug40565 values (1), (null);
update bug40565 set value=NULL;
affected rows: 1
info: Rows matched: 2 Changed: 1 Warnings: 0
update bug40565 set value=NULL;
affected rows: 0
info: Rows matched: 2 Changed: 0 Warnings: 0
drop table bug40565;
# Bug #40565 Update Query Results in "1 Row Affected" But Should Be "Zero Rows"
-- source include/have_innodb.inc
create table bug40565(value decimal(4,2)) engine=innodb;
insert into bug40565 values (1), (null);
--enable_info
update bug40565 set value=NULL;
update bug40565 set value=NULL;
--disable_info
drop table bug40565;
...@@ -2253,6 +2253,9 @@ ha_innobase::open( ...@@ -2253,6 +2253,9 @@ ha_innobase::open(
((row_prebuilt_t*)innobase_prebuilt)->mysql_row_len = ((row_prebuilt_t*)innobase_prebuilt)->mysql_row_len =
table->s->reclength; table->s->reclength;
((row_prebuilt_t*)innobase_prebuilt)->default_rec
= table->s->default_values;
ut_ad(table->s->default_values);
/* Looks like MySQL-3.23 sometimes has primary key number != 0 */ /* Looks like MySQL-3.23 sometimes has primary key number != 0 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment