From 1508c9d4472edf649add42aae9058143efba69d2 Mon Sep 17 00:00:00 2001 From: bsrikanth-mariadb Date: Wed, 20 May 2026 15:05:08 +0530 Subject: [PATCH] MDEV-39410: ucs2 data not stored correctly in the context For constant tables, the rows are stored in the context using the charset my_charset_utf8mb4_bin. However, that is not correct, as every field in the row could use its own charset. This leads to a replay failure, as the data that gets read from the sql_script file is different from the original row data. This PR addresses uses field's own charset instead of my_charset_utf8mb4_bin. --- .../main/opt_context_replay_basic.result | 20 ++++++++++++++ mysql-test/main/opt_context_replay_basic.test | 26 +++++++++++++++++++ sql/filesort.cc | 5 ++-- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/opt_context_replay_basic.result b/mysql-test/main/opt_context_replay_basic.result index 0d94b6f9b54b0..e7b541a9115cb 100644 --- a/mysql-test/main/opt_context_replay_basic.result +++ b/mysql-test/main/opt_context_replay_basic.result @@ -295,4 +295,24 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL 3 Deleting all rows set optimizer_replay_context=''; drop table t1; +# +# MDEV-39410: ucs2 data not stored correctly in the context +# +create table t1 (a varchar(5) character set ucs2 collate ucs2_bin); +insert into t1 values (0x00410000); +set optimizer_record_context=1; +explain select hex(a) from t1 where a like 'A_'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +select context into dumpfile "../../tmp/dump1.sql" +from information_schema.optimizer_context; +set optimizer_record_context=0; +drop table t1; +set optimizer_replay_context='opt_context'; +# Same query as above, must have same explain: +explain select hex(a) from t1 where a like 'A_'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +set optimizer_replay_context=''; +drop table t1; drop database db1; diff --git a/mysql-test/main/opt_context_replay_basic.test b/mysql-test/main/opt_context_replay_basic.test index e9bbaee984526..7e987b202ff6f 100644 --- a/mysql-test/main/opt_context_replay_basic.test +++ b/mysql-test/main/opt_context_replay_basic.test @@ -147,4 +147,30 @@ set optimizer_replay_context=''; --remove_file "$MYSQLTEST_VARDIR/tmp/dump1.sql" drop table t1; +--echo # +--echo # MDEV-39410: ucs2 data not stored correctly in the context +--echo # +create table t1 (a varchar(5) character set ucs2 collate ucs2_bin); +insert into t1 values (0x00410000); + +set optimizer_record_context=1; +explain select hex(a) from t1 where a like 'A_'; + +select context into dumpfile "../../tmp/dump1.sql" +from information_schema.optimizer_context; +set optimizer_record_context=0; +drop table t1; +--disable_query_log +--disable_result_log +--source "$MYSQLTEST_VARDIR/tmp/dump1.sql" +--enable_query_log +--enable_result_log +set optimizer_replay_context='opt_context'; +--echo # Same query as above, must have same explain: +explain select hex(a) from t1 where a like 'A_'; + +set optimizer_replay_context=''; +--remove_file "$MYSQLTEST_VARDIR/tmp/dump1.sql" +drop table t1; + drop database db1; diff --git a/sql/filesort.cc b/sql/filesort.cc index 1f6dca1e1681b..9d885928fb55a 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -3039,7 +3039,8 @@ void format_and_store_row(TABLE *table, const uchar *rec, bool print_names, { Field **pfield; char row_buff_tmp[512]; - String tmp(row_buff_tmp, sizeof(row_buff_tmp), &my_charset_bin); + // charset will be overwritten below using field's charset + String tmp(row_buff_tmp, sizeof(row_buff_tmp), &my_charset_utf8mb4_bin); auto move_back_lambda= [table, rec]() mutable { table->move_fields(table->field, table->record[0], rec); @@ -3136,7 +3137,7 @@ void format_and_store_row(TABLE *table, const uchar *rec, bool print_names, if (require_quote) output.append('\''); output.append_for_single_quote_opt_convert(tmp.ptr(), tmp.length(), - &my_charset_utf8mb4_bin); + field->charset()); if (require_quote) output.append('\''); }