summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_charset.result42
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_charset.test68
-rw-r--r--sql/field.cc5
-rw-r--r--sql/rpl_utility.cc16
4 files changed, 120 insertions, 11 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_row_charset.result b/mysql-test/suite/rpl/r/rpl_row_charset.result
new file mode 100644
index 00000000000..b7ef02b93bb
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_charset.result
@@ -0,0 +1,42 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+SET SQL_LOG_BIN=0;
+CREATE TABLE t1 (c1 char(255) DEFAULT NULL, KEY c1 (c1)) DEFAULT CHARSET=utf32;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 1000 bytes
+SET SQL_LOG_BIN=1;
+SET @saved_slave_type_conversions= @@global.slave_type_conversions;
+include/stop_slave.inc
+SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY';
+include/start_slave.inc
+SET SQL_LOG_BIN=0;
+CREATE TABLE t1 ( c1 varchar(255) DEFAULT NULL, KEY c1 (c1)) DEFAULT CHARSET=utf32;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 1000 bytes
+SET SQL_LOG_BIN=1;
+INSERT INTO t1(c1) VALUES ('insert into t1');
+DROP TABLE t1;
+SET GLOBAL SLAVE_TYPE_CONVERSIONS= @saved_slave_type_conversions;
+include/stop_slave.inc
+include/start_slave.inc
+CREATE TABLE t1(c1 CHAR(10) CHARACTER SET utf16 DEFAULT 'ola');
+INSERT INTO t1 VALUES ('abc');
+INSERT INTO t1 VALUES ();
+#### ON MASTER
+SELECT c1, hex(c1) from t1; ;
+c1 abc
+hex(c1) 006100620063
+c1 ola
+hex(c1) 006F006C0061
+#### ON SLAVE
+SELECT c1, hex(c1) FROM t1; ;
+c1 abc
+hex(c1) 006100620063
+c1 ola
+hex(c1) 006F006C0061
+Comparing tables master:test.t1 and slave:test.t1
+DROP TABLE t1;
diff --git a/mysql-test/suite/rpl/t/rpl_row_charset.test b/mysql-test/suite/rpl/t/rpl_row_charset.test
new file mode 100644
index 00000000000..b5108541b6f
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_charset.test
@@ -0,0 +1,68 @@
+-- source include/master-slave.inc
+-- source include/have_binlog_format_row.inc
+
+#
+# BUG#51787 Assertion `(n % 4) == 0' on slave upon INSERT into a table with UTF32
+#
+
+SET SQL_LOG_BIN=0;
+CREATE TABLE t1 (c1 char(255) DEFAULT NULL, KEY c1 (c1)) DEFAULT CHARSET=utf32;
+SET SQL_LOG_BIN=1;
+
+-- connection slave
+
+-- let $reset_slave_type_conversions= 0
+
+SET @saved_slave_type_conversions= @@global.slave_type_conversions;
+
+#
+# Force test to cover conversion execution path in the
+# slave, which also makes use of sql_type method, thence
+# can ultimately trigger the assertion.
+#
+-- source include/stop_slave.inc
+SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY';
+-- source include/start_slave.inc
+
+SET SQL_LOG_BIN=0;
+CREATE TABLE t1 ( c1 varchar(255) DEFAULT NULL, KEY c1 (c1)) DEFAULT CHARSET=utf32;
+SET SQL_LOG_BIN=1;
+
+-- connection master
+
+INSERT INTO t1(c1) VALUES ('insert into t1');
+DROP TABLE t1;
+
+--sync_slave_with_master
+
+# assertion: the slave woul hit an/several assertions:
+# before and during slave conversion procedure
+# Now that is fixed, it wont.
+
+SET GLOBAL SLAVE_TYPE_CONVERSIONS= @saved_slave_type_conversions;
+-- source include/stop_slave.inc
+-- source include/start_slave.inc
+-- connection master
+
+#
+# BUG#51716: Char column with utf16 character set gives wrong padding on slave
+#
+
+CREATE TABLE t1(c1 CHAR(10) CHARACTER SET utf16 DEFAULT 'ola');
+INSERT INTO t1 VALUES ('abc'); # explicit value is inserted and encoded correctly
+INSERT INTO t1 VALUES (); # default value is inserted and encoded correctly
+
+-- echo #### ON MASTER
+--query_vertical SELECT c1, hex(c1) from t1;
+
+-- sync_slave_with_master
+
+-- echo #### ON SLAVE
+--query_vertical SELECT c1, hex(c1) FROM t1;
+
+# assertion: tables don't differ
+-- let $diff_table_1=master:test.t1
+-- let $diff_table_2=slave:test.t1
+-- source include/diff_tables.inc
+
+DROP TABLE t1;
diff --git a/sql/field.cc b/sql/field.cc
index 51235d9f0e8..e339b0f071a 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6613,8 +6613,7 @@ uchar *Field_string::pack(uchar *to, const uchar *from,
local_char_length= my_charpos(field_charset, from, from+length,
local_char_length);
set_if_smaller(length, local_char_length);
- while (length && from[length-1] == field_charset->pad_char)
- length--;
+ length= field_charset->cset->lengthsp(field_charset, (const char*) from, length);
// Length always stored little-endian
*to++= (uchar) length;
@@ -6680,7 +6679,7 @@ Field_string::unpack(uchar *to,
memcpy(to, from, length);
// Pad the string with the pad character of the fields charset
- bfill(to + length, field_length - length, field_charset->pad_char);
+ field_charset->cset->fill(field_charset, (char*) to + length, field_length - length, field_charset->pad_char);
return from+length;
}
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index feb35527b62..8171d028326 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -340,7 +340,7 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
/**
*/
-void show_sql_type(enum_field_types type, uint16 metadata, String *str)
+void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_INFO *field_cs)
{
DBUG_ENTER("show_sql_type");
DBUG_PRINT("enter", ("type: %d, metadata: 0x%x", type, metadata));
@@ -489,7 +489,7 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str)
uint bytes= (((metadata >> 4) & 0x300) ^ 0x300) + (metadata & 0x00ff);
uint32 length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
- "char(%d)", bytes / cs->mbmaxlen);
+ "char(%d)", bytes / field_cs->mbmaxlen);
str->length(length);
}
break;
@@ -579,7 +579,7 @@ can_convert_field_to(Field *field,
DBUG_ENTER("can_convert_field_to");
#ifndef DBUG_OFF
char field_type_buf[MAX_FIELD_WIDTH];
- String field_type(field_type_buf, sizeof(field_type_buf), field->charset());
+ String field_type(field_type_buf, sizeof(field_type_buf), &my_charset_latin1);
field->sql_type(field_type);
DBUG_PRINT("enter", ("field_type: %s, target_type: %d, source_type: %d, source_metadata: 0x%x",
field_type.c_ptr_safe(), field->real_type(), source_type, metadata));
@@ -822,9 +822,9 @@ table_def::compatible_with(THD *thd, Relay_log_info *rli,
const char *tbl_name= table->s->table_name.str;
char source_buf[MAX_FIELD_WIDTH];
char target_buf[MAX_FIELD_WIDTH];
- String source_type(source_buf, sizeof(source_buf), field->charset());
- String target_type(target_buf, sizeof(target_buf), field->charset());
- show_sql_type(type(col), field_metadata(col), &source_type);
+ String source_type(source_buf, sizeof(source_buf), &my_charset_latin1);
+ String target_type(target_buf, sizeof(target_buf), &my_charset_latin1);
+ show_sql_type(type(col), field_metadata(col), &source_type, field->charset());
field->sql_type(target_type);
rli->report(ERROR_LEVEL, ER_SLAVE_CONVERSION_FAILED,
ER(ER_SLAVE_CONVERSION_FAILED),
@@ -842,8 +842,8 @@ table_def::compatible_with(THD *thd, Relay_log_info *rli,
{
char source_buf[MAX_FIELD_WIDTH];
char target_buf[MAX_FIELD_WIDTH];
- String source_type(source_buf, sizeof(source_buf), table->field[col]->charset());
- String target_type(target_buf, sizeof(target_buf), table->field[col]->charset());
+ String source_type(source_buf, sizeof(source_buf), &my_charset_latin1);
+ String target_type(target_buf, sizeof(target_buf), &my_charset_latin1);
tmp_table->field[col]->sql_type(source_type);
table->field[col]->sql_type(target_type);
DBUG_PRINT("debug", ("Field %s - conversion required."