mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
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
This commit is contained in:
parent
2f8518856c
commit
7399eef281
4 changed files with 11 additions and 49 deletions
|
@ -2508,6 +2508,8 @@ retry:
|
|||
prebuilt = row_create_prebuilt(ib_table);
|
||||
|
||||
prebuilt->mysql_row_len = table->s->reclength;
|
||||
prebuilt->default_rec = table->s->default_values;
|
||||
ut_ad(prebuilt->default_rec);
|
||||
|
||||
/* Looks like MySQL-3.23 sometimes has primary key number != 0 */
|
||||
|
||||
|
|
|
@ -594,6 +594,8 @@ struct row_prebuilt_struct {
|
|||
byte* ins_upd_rec_buff;/* buffer for storing data converted
|
||||
to the Innobase format from the MySQL
|
||||
format */
|
||||
const byte* default_rec; /* the default values of all columns
|
||||
(a "default row") in MySQL format */
|
||||
ulint hint_need_to_fetch_extra_cols;
|
||||
/* normally this is set to 0; if this
|
||||
is set to ROW_RETRIEVE_PRIMARY_KEY,
|
||||
|
|
|
@ -620,6 +620,7 @@ row_create_prebuilt(
|
|||
prebuilt->ins_node = NULL;
|
||||
|
||||
prebuilt->ins_upd_rec_buff = NULL;
|
||||
prebuilt->default_rec = NULL;
|
||||
|
||||
prebuilt->upd_node = NULL;
|
||||
prebuilt->ins_graph = NULL;
|
||||
|
|
|
@ -2597,6 +2597,7 @@ row_sel_store_mysql_rec(
|
|||
ulint i;
|
||||
|
||||
ut_ad(prebuilt->mysql_template);
|
||||
ut_ad(prebuilt->default_rec);
|
||||
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
||||
|
||||
if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
|
||||
|
@ -2683,58 +2684,14 @@ row_sel_store_mysql_rec(
|
|||
&= ~(byte) templ->mysql_null_bit_mask;
|
||||
}
|
||||
} else {
|
||||
/* MySQL seems to assume the field for an SQL NULL
|
||||
value is set to zero or space. Not taking this into
|
||||
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 assumes that the field for an SQL
|
||||
NULL value is set to the default value. */
|
||||
|
||||
mysql_rec[templ->mysql_null_byte_offset]
|
||||
|= (byte) templ->mysql_null_bit_mask;
|
||||
switch (templ->type) {
|
||||
case DATA_VARCHAR:
|
||||
case DATA_BINARY:
|
||||
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);
|
||||
memcpy(mysql_rec + templ->mysql_col_offset,
|
||||
prebuilt->default_rec + templ->mysql_col_offset,
|
||||
templ->mysql_col_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue