From a39be6d515b0cf969f128ca0a60cb2b5c33b28c6 Mon Sep 17 00:00:00 2001 From: Yura Sorokin Date: Fri, 26 Jul 2024 19:18:50 +0200 Subject: [PATCH 1/8] PS-9237 feature: Include support for utf8mb4_0900_ai_ci in MySQL 5.7 (connection) https://perconadev.atlassian.net/browse/PS-9237 Extended the behavior of the 'default_collation_for_utf8mb4' system variable. Now, when 'default_collation_for_utf8mb4' is set to 'utf8mb4_general_ci', its value also affects the value of the 'character_set_client', 'collation_connection' and 'character_set_results' variables. This helps in cases when a 8.0 mysql client (for instance, 'mysql' command line utility or 'mysqldump' utility) that is used with the '--default-character-set' command line option explicitly set to 'utf8mb4' or not set at all is trying to connect to a 8.0 server with 'default_collation_for_utf8mb4' set to 'utf8mb4_general_ci'. In both cases 'MYSQL_SET_CHARSET_NAME' API option will be set to 255 and sent to the server as part of the protocol, and without the fix, the value of the 'character_set_client' variable will be 'utf8mb4_0900_ai_ci' (255). This behavior is not desired as it has a lot of negative side effects, especially for the binary logging intended to be compatible with 5.7 (where there is no 'utf8mb4_0900_ai_ci' collation). --- sql/sql_connect.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index c5256a63c19c..82c6d2f36b59 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -670,6 +670,24 @@ void reset_mqh(THD *thd, LEX_USER *lu, bool get_them = false) { bool thd_init_client_charset(THD *thd, uint cs_number) { CHARSET_INFO *cs; + + // if the 8.0 client sets 'MYSQL_SET_CHARSET_NAME' option to 'utf8mb4' or + // leaves it empty, basically meaning the same, this function will be called + // with 'cs_number' equal to 255 (meaning 'utf8mb4_0900_ai_ci') + + // at the same time, if 'default_collation_for_utf8mb4' is set to something + // other than default 'utf8mb4' collation ('utf8mb4_0900_ai_ci', number 255), + // we need to fix 'cs_number' here by setting it to the corresponding number + // of 'default_collation_for_utf8mb4' (currently only 'utf8mb4_general_ci', + // number 45, is supported) + const auto *primary_utf8mb4_collation = + get_charset_by_csname("utf8mb4", MY_CS_PRIMARY, MYF(0)); + if (thd->variables.default_collation_for_utf8mb4 != + primary_utf8mb4_collation) { + if (cs_number == primary_utf8mb4_collation->number) { + cs_number = thd->variables.default_collation_for_utf8mb4->number; + } + } /* Use server character set and collation if - opt_character_set_client_handshake is not set From 873c1eb5c73eacdd65f9a840966589a15b87f8a7 Mon Sep 17 00:00:00 2001 From: Yura Sorokin Date: Fri, 26 Jul 2024 19:34:42 +0200 Subject: [PATCH 2/8] PS-9237 feature: Include support for utf8mb4_0900_ai_ci in MySQL 5.7 (set_var) https://perconadev.atlassian.net/browse/PS-9237 Extended the behavior of the 'default_collation_for_utf8mb4' system variable. Now, when user sets one of the charset-related variables (for instance, 'character_set_client') to 'utf8mb4', the value written to the binary log for the subsequent QUERY event will have 'SET @@session.character_set_client=...' set to a value based on the value of 'default_collation_for_utf8mb4' (45 for 'utf8mb4_general_ci') instead of pre-defined 255 ('utf8mb4_0900_ai_ci'). This helps in scenarios when an sql file generated by the 'mysqldump' utility has explicit 'SET character_set_client = utf8mb4;' statements and is executed on a server running with 'default_collation_for_utf8mb4' set to 'utf8mb4_general_ci'. With the fix this the default collation for the 'utf8mb4' will be identified as 'utf8mb4_general_ci' (45) instead of `utf8mb4_0900_ai_ci` (255) and will help the generated binary log to be backward compatible with 5.7. --- sql/sys_vars.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index cb53a389781e..f37faf79c37e 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1869,6 +1869,21 @@ static bool check_charset(sys_var *, THD *thd, set_var *var) { my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), err.ptr()); return true; } + // if 'default_collation_for_utf8mb4' is set to something other than + // default 'utf8mb4' collation ('utf8mb4_0900_ai_ci') and if the value + // returned by 'get_charset_by_csname()' is also default 'utf8mb4' + // collation ('utf8mb4_0900_ai_ci'), meaning that were requesting for + // 'utf8mb4', we need to fix the returned value depending on the value of + // 'default_collation_for_utf8mb4' (currently, only 'utf8mb4_general_ci' + // is possible) + const auto *primary_utf8mb4_collation = + get_charset_by_csname("utf8mb4", MY_CS_PRIMARY, MYF(0)); + if (thd->variables.default_collation_for_utf8mb4 != + primary_utf8mb4_collation) { + if (var->save_result.ptr == primary_utf8mb4_collation) { + var->save_result.ptr = thd->variables.default_collation_for_utf8mb4; + } + } warn_on_deprecated_charset( thd, static_cast(var->save_result.ptr), err.ptr()); From da0002be2c62f52b98f3ea18dd13682b3a39dd26 Mon Sep 17 00:00:00 2001 From: Yura Sorokin Date: Wed, 31 Jul 2024 00:13:38 +0200 Subject: [PATCH 3/8] PS-9237 feature: Include support for utf8mb4_0900_ai_ci in MySQL 5.7 (mtr) https://perconadev.atlassian.net/browse/PS-9237 Added new 'main.percona_default_collation_for_utf8mb4_extensions' MTR test case which checks the following: * if setting 'default_collation_for_utf8mb4' affects collation variables for connections established from an external mysql client ('mysql' command line utility) * if setting 'default_collation_for_utf8mb4' affects the behavior of 'SET character_set_client = utf8mb4;' * if collation 'utf8mb4_0900_ai_ci' (255) never appears in the binary log when 'default_collation_for_utf8mb4' is set to 'utf8mb4_general_ci' * if default 'mysqldump ... > mysql ...' backup-restore procedure does not lead to changing collations back to 'utf8mb4_0900_ai_ci' when 'default_collation_for_utf8mb4' is set to 'utf8mb4_general_ci' --- ...lt_collation_for_utf8mb4_extensions.result | 137 +++++++++++++++++ ...ault_collation_for_utf8mb4_extensions.test | 144 ++++++++++++++++++ 2 files changed, 281 insertions(+) create mode 100644 mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result create mode 100644 mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test diff --git a/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result b/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result new file mode 100644 index 000000000000..4539a31f3ec6 --- /dev/null +++ b/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result @@ -0,0 +1,137 @@ +RESET MASTER; +*** Variables from the default session +*** (values for all collation variables are expected to be utf8mb4_0900_ai_ci) +SHOW GLOBAL VARIABLES LIKE '%collation%'; +Variable_name Value +collation_connection utf8mb4_0900_ai_ci +collation_database utf8mb4_0900_ai_ci +collation_server utf8mb4_0900_ai_ci +default_collation_for_utf8mb4 utf8mb4_0900_ai_ci +SHOW SESSION VARIABLES LIKE '%collation%'; +Variable_name Value +collation_connection utf8mb4_0900_ai_ci +collation_database utf8mb4_0900_ai_ci +collation_server utf8mb4_0900_ai_ci +default_collation_for_utf8mb4 utf8mb4_0900_ai_ci + +*** Variables from the new connection established via MySQL command line client +*** (values for all collation variables are expected to be utf8mb4_0900_ai_ci) +Variable_name Value +collation_connection utf8mb4_0900_ai_ci +collation_database utf8mb4_0900_ai_ci +collation_server utf8mb4_0900_ai_ci +default_collation_for_utf8mb4 utf8mb4_0900_ai_ci +Variable_name Value +collation_connection utf8mb4_0900_ai_ci +collation_database utf8mb4_0900_ai_ci +collation_server utf8mb4_0900_ai_ci +default_collation_for_utf8mb4 utf8mb4_0900_ai_ci + + +*** Updating collation variables +SET GLOBAL default_collation_for_utf8mb4 = utf8mb4_general_ci; +Warnings: +Warning 1681 Updating 'default_collation_for_utf8mb4' is deprecated. It will be made read-only in a future release. +SET GLOBAL collation_server = utf8mb4_general_ci; +SET GLOBAL collation_connection = utf8mb4_general_ci; +SET GLOBAL collation_database = utf8mb4_general_ci; +Warnings: +Warning 1681 Updating 'collation_database' is deprecated. It will be made read-only in a future release. + + +*** Re-connecting + + +*** Variables after re-connecting to the default database +*** (values for all collation variables except for @@session.collation_database are expected to be utf8mb4_general_ci) +SHOW GLOBAL VARIABLES LIKE '%collation%'; +Variable_name Value +collation_connection utf8mb4_general_ci +collation_database utf8mb4_general_ci +collation_server utf8mb4_general_ci +default_collation_for_utf8mb4 utf8mb4_general_ci +SHOW SESSION VARIABLES LIKE '%collation%'; +Variable_name Value +collation_connection utf8mb4_general_ci +collation_database utf8mb4_0900_ai_ci +collation_server utf8mb4_general_ci +default_collation_for_utf8mb4 utf8mb4_general_ci + + +*** Creating a fresh database +CREATE DATABASE fresh; +SHOW CREATE DATABASE fresh; +Database Create Database +fresh CREATE DATABASE `fresh` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ + + +*** Variables after connecting to a fresh database +*** (values for collation variables expected to be utf8mb4_general_ci) +SHOW GLOBAL VARIABLES LIKE '%collation%'; +Variable_name Value +collation_connection utf8mb4_general_ci +collation_database utf8mb4_general_ci +collation_server utf8mb4_general_ci +default_collation_for_utf8mb4 utf8mb4_general_ci +SHOW SESSION VARIABLES LIKE '%collation%'; +Variable_name Value +collation_connection utf8mb4_general_ci +collation_database utf8mb4_general_ci +collation_server utf8mb4_general_ci +default_collation_for_utf8mb4 utf8mb4_general_ci + +*** Variables from the new connection established via MySQL command line client to a fresh database +*** (values for all collation variables are expected to be utf8mb4_general_ci) +Variable_name Value +collation_connection utf8mb4_general_ci +collation_database utf8mb4_general_ci +collation_server utf8mb4_general_ci +default_collation_for_utf8mb4 utf8mb4_general_ci +Variable_name Value +collation_connection utf8mb4_general_ci +collation_database utf8mb4_general_ci +collation_server utf8mb4_general_ci +default_collation_for_utf8mb4 utf8mb4_general_ci + + +*** Creating tables in the fresh database from the default connection +CREATE TABLE tbl_internal_before(id BIGINT UNSIGNED); +SET character_set_client = utf8mb4; +CREATE TABLE tbl_internal_after(id BIGINT UNSIGNED); + + +*** Creating tables in the fresh database from a connection established via MySQL command line client + + +*** Creating logical dump of the fresh database + + +*** Creating a database for restoring data from the logical dump +CREATE DATABASE restore; +SHOW CREATE DATABASE restore; +Database Create Database +restore CREATE DATABASE `restore` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ + + +*** Restoring data from the logical dump + + +*** Checking events in the binary log +include/assert_grep.inc [Events in the binary log must use utf8mb4_general_ci (45) collation] +include/assert_grep.inc [Events in the binary log must not use utf8mb4_0900_ai_ci (255) collation] + + +*** Dropping fresh database +DROP DATABASE restore; +DROP DATABASE fresh; + + +*** Restoring collation variables +SET GLOBAL collation_database = utf8mb4_0900_ai_ci; +Warnings: +Warning 1681 Updating 'collation_database' is deprecated. It will be made read-only in a future release. +SET GLOBAL collation_connection = utf8mb4_0900_ai_ci; +SET GLOBAL collation_server = utf8mb4_0900_ai_ci; +SET GLOBAL default_collation_for_utf8mb4 = utf8mb4_0900_ai_ci; +Warnings: +Warning 1681 Updating 'default_collation_for_utf8mb4' is deprecated. It will be made read-only in a future release. diff --git a/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test b/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test new file mode 100644 index 000000000000..3198ce77b64e --- /dev/null +++ b/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test @@ -0,0 +1,144 @@ +--source include/count_sessions.inc + +# needed for repeatable content of the binary log +RESET MASTER; + +--let $global_col_stmt = SHOW GLOBAL VARIABLES LIKE '%collation%' +--let $session_col_stmt = SHOW SESSION VARIABLES LIKE '%collation%' + +--echo *** Variables from the default session +--echo *** (values for all collation variables are expected to be utf8mb4_0900_ai_ci) +eval $global_col_stmt; +eval $session_col_stmt; + +--let $default_database = `SELECT DATABASE()` + +--echo +--echo *** Variables from the new connection established via MySQL command line client +--echo *** (values for all collation variables are expected to be utf8mb4_0900_ai_ci) +--exec $MYSQL -e "$global_col_stmt; $session_col_stmt;" $default_database + +--echo +--echo +--echo *** Updating collation variables +--let $saved_default_collation_for_utf8mb4 = `SELECT @@global.default_collation_for_utf8mb4` +--let $saved_collation_server = `SELECT @@global.collation_server` +--let $saved_collation_connection = `SELECT @@global.collation_connection` +--let $saved_collation_database = `SELECT @@global.collation_database` + +SET GLOBAL default_collation_for_utf8mb4 = utf8mb4_general_ci; +SET GLOBAL collation_server = utf8mb4_general_ci; +SET GLOBAL collation_connection = utf8mb4_general_ci; +SET GLOBAL collation_database = utf8mb4_general_ci; + +--echo +--echo +--echo *** Re-connecting +--disconnect default +--connect (default,localhost,root,,$default_database) + +--echo +--echo +--echo *** Variables after re-connecting to the default database +--echo *** (values for all collation variables except for @@session.collation_database are expected to be utf8mb4_general_ci) +eval $global_col_stmt; +eval $session_col_stmt; + +--echo +--echo +--echo *** Creating a fresh database +--let $fresh_database = fresh +eval CREATE DATABASE $fresh_database; +eval SHOW CREATE DATABASE $fresh_database; + +--connect (con1,localhost,root,,$fresh_database) + +--echo +--echo +--echo *** Variables after connecting to a fresh database +--echo *** (values for collation variables expected to be utf8mb4_general_ci) +eval $global_col_stmt; +eval $session_col_stmt; + +--echo +--echo *** Variables from the new connection established via MySQL command line client to a fresh database +--echo *** (values for all collation variables are expected to be utf8mb4_general_ci) +--exec $MYSQL -e "$global_col_stmt; $session_col_stmt;" $fresh_database + +--let $binlog_file = query_get_value("SHOW MASTER STATUS", File, 1) +--let $server_port = `SELECT @@port` + +--echo +--echo +--echo *** Creating tables in the fresh database from the default connection +CREATE TABLE tbl_internal_before(id BIGINT UNSIGNED); +SET character_set_client = utf8mb4; +CREATE TABLE tbl_internal_after(id BIGINT UNSIGNED); + +--echo +--echo +--echo *** Creating tables in the fresh database from a connection established via MySQL command line client +--exec $MYSQL -e "CREATE TABLE tbl_external_before(id BIGINT UNSIGNED); SET character_set_client = utf8mb4; CREATE TABLE tbl_external_after(id BIGINT UNSIGNED);" $fresh_database + + +--echo +--echo +--echo *** Creating logical dump of the fresh database +--let $fresh_dump_file = $MYSQL_TMP_DIR/fresh_dump.sql +--exec $MYSQL_DUMP --column-statistics=0 --no-data $fresh_database > $fresh_dump_file + +--echo +--echo +--echo *** Creating a database for restoring data from the logical dump +--let $restore_database = restore +eval CREATE DATABASE $restore_database; +eval SHOW CREATE DATABASE $restore_database; + +--echo +--echo +--echo *** Restoring data from the logical dump +--exec $MYSQL $restore_database < $fresh_dump_file + +--remove_file $fresh_dump_file + +--echo +--echo +--echo *** Checking events in the binary log +--let $binlog_dump_file = $MYSQL_TMP_DIR/binlog_dump.sql +--exec $MYSQL_BINLOG --read-from-remote-server --host=127.0.0.1 --port=$server_port --user=root --to-last-log $binlog_file > $binlog_dump_file + +# The binary log is expected to have the following 2 lines with collation 45 (utf8mb4_general_ci) +# SET @@session.character_set_client=45,@@session.collation_connection=45,@@session.collation_server=45/*!*/; +# /*!80011 SET @@session.default_collation_for_utf8mb4=45*//*!*/; +--let $assert_text = Events in the binary log must use utf8mb4_general_ci (45) collation +--let $assert_file = $binlog_dump_file +--let $assert_select = =45 +--let $assert_count = 2 +--source include/assert_grep.inc + +--let $assert_text = Events in the binary log must not use utf8mb4_0900_ai_ci (255) collation +--let $assert_file = $binlog_dump_file +--let $assert_select = =255 +--let $assert_count = 0 +--source include/assert_grep.inc + +--remove_file $binlog_dump_file + + +--disconnect con1 +--connection default +--source include/wait_until_count_sessions.inc + +--echo +--echo +--echo *** Dropping fresh database +eval DROP DATABASE $restore_database; +eval DROP DATABASE $fresh_database; + +--echo +--echo +--echo *** Restoring collation variables +eval SET GLOBAL collation_database = $saved_collation_database; +eval SET GLOBAL collation_connection = $saved_collation_connection; +eval SET GLOBAL collation_server = $saved_collation_server; +eval SET GLOBAL default_collation_for_utf8mb4 = $saved_default_collation_for_utf8mb4; From 06da781ea332d40a3addda2d393b07831be89ee3 Mon Sep 17 00:00:00 2001 From: Yura Sorokin Date: Mon, 21 Oct 2024 23:53:27 +0200 Subject: [PATCH 4/8] PS-9237 feature: Include support for utf8mb4_0900_ai_ci in MySQL 5.7 (connection postfix) https://perconadev.atlassian.net/browse/PS-9237 Eliminated unnecessary call to 'get_charset_by_csname()' inside 'thd_init_client_charset()' as this function is in critical path. --- sql/sql_connect.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 82c6d2f36b59..1b3bb155d0c5 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -680,11 +680,9 @@ bool thd_init_client_charset(THD *thd, uint cs_number) { // we need to fix 'cs_number' here by setting it to the corresponding number // of 'default_collation_for_utf8mb4' (currently only 'utf8mb4_general_ci', // number 45, is supported) - const auto *primary_utf8mb4_collation = - get_charset_by_csname("utf8mb4", MY_CS_PRIMARY, MYF(0)); if (thd->variables.default_collation_for_utf8mb4 != - primary_utf8mb4_collation) { - if (cs_number == primary_utf8mb4_collation->number) { + &my_charset_utf8mb4_0900_ai_ci) { + if (cs_number == my_charset_utf8mb4_0900_ai_ci.number) { cs_number = thd->variables.default_collation_for_utf8mb4->number; } } From 3041e9a95dee1ce9e1c432d3d5253e9a7a61e53c Mon Sep 17 00:00:00 2001 From: Yura Sorokin Date: Tue, 22 Oct 2024 00:01:17 +0200 Subject: [PATCH 5/8] PS-9237 feature: Include support for utf8mb4_0900_ai_ci in MySQL 5.7 (set_var postfix) https://perconadev.atlassian.net/browse/PS-9237 Eliminated unnecessary call to 'get_charset_by_csname()' inside 'check_charset()'. --- sql/sys_vars.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index f37faf79c37e..c97c50e3a091 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1872,15 +1872,13 @@ static bool check_charset(sys_var *, THD *thd, set_var *var) { // if 'default_collation_for_utf8mb4' is set to something other than // default 'utf8mb4' collation ('utf8mb4_0900_ai_ci') and if the value // returned by 'get_charset_by_csname()' is also default 'utf8mb4' - // collation ('utf8mb4_0900_ai_ci'), meaning that were requesting for - // 'utf8mb4', we need to fix the returned value depending on the value of - // 'default_collation_for_utf8mb4' (currently, only 'utf8mb4_general_ci' - // is possible) - const auto *primary_utf8mb4_collation = - get_charset_by_csname("utf8mb4", MY_CS_PRIMARY, MYF(0)); + // collation ('utf8mb4_0900_ai_ci'), meaning that we were calling this + // function with 'utf8mb4', we need to fix the returned value depending + // on the value of 'default_collation_for_utf8mb4' (currently, only + // 'utf8mb4_general_ci' is possible) if (thd->variables.default_collation_for_utf8mb4 != - primary_utf8mb4_collation) { - if (var->save_result.ptr == primary_utf8mb4_collation) { + &my_charset_utf8mb4_0900_ai_ci) { + if (var->save_result.ptr == &my_charset_utf8mb4_0900_ai_ci) { var->save_result.ptr = thd->variables.default_collation_for_utf8mb4; } } From ccb29ccb331097055f2a4588cb8cbdb819a7ef76 Mon Sep 17 00:00:00 2001 From: Yura Sorokin Date: Tue, 22 Oct 2024 00:51:00 +0200 Subject: [PATCH 6/8] PS-9237 feature: Include support for utf8mb4_0900_ai_ci in MySQL 5.7 (triggers) https://perconadev.atlassian.net/browse/PS-9237 Fixed the value of the 'character_set_client' field for the binary log events generated implicitly from triggers. Updated 'main.percona_default_collation_for_utf8mb4_extensions' MTR test case with 'INSERT' statements executed from triggers and stored procedures. --- ...lt_collation_for_utf8mb4_extensions.result | 19 +++++++++++++-- ...ault_collation_for_utf8mb4_extensions.test | 24 +++++++++++++++++-- sql/trigger_creation_ctx.cc | 14 +++++++++++ 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result b/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result index 4539a31f3ec6..086fc7ea331c 100644 --- a/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result +++ b/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result @@ -80,6 +80,7 @@ collation_database utf8mb4_general_ci collation_server utf8mb4_general_ci default_collation_for_utf8mb4 utf8mb4_general_ci + *** Variables from the new connection established via MySQL command line client to a fresh database *** (values for all collation variables are expected to be utf8mb4_general_ci) Variable_name Value @@ -95,9 +96,23 @@ default_collation_for_utf8mb4 utf8mb4_general_ci *** Creating tables in the fresh database from the default connection -CREATE TABLE tbl_internal_before(id BIGINT UNSIGNED); +CREATE TABLE t1(id BIGINT UNSIGNED); SET character_set_client = utf8mb4; -CREATE TABLE tbl_internal_after(id BIGINT UNSIGNED); +CREATE TABLE t2(id BIGINT UNSIGNED); + + +*** Making sure that binlog events created implicitly via stored procedures +*** and triggers have character_set_client = 45 +CREATE TRIGGER test_trigger BEFORE INSERT ON t2 FOR EACH ROW +BEGIN +INSERT INTO t1 SET id = NEW.id; +END| +CREATE PROCEDURE proc() +BEGIN +INSERT INTO t2 VALUES (42); +END| +INSERT INTO t2 VALUES(1); +CALL proc(); *** Creating tables in the fresh database from a connection established via MySQL command line client diff --git a/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test b/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test index 3198ce77b64e..ceb43d876c7c 100644 --- a/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test +++ b/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test @@ -60,6 +60,7 @@ eval SHOW CREATE DATABASE $fresh_database; eval $global_col_stmt; eval $session_col_stmt; +--echo --echo --echo *** Variables from the new connection established via MySQL command line client to a fresh database --echo *** (values for all collation variables are expected to be utf8mb4_general_ci) @@ -71,9 +72,28 @@ eval $session_col_stmt; --echo --echo --echo *** Creating tables in the fresh database from the default connection -CREATE TABLE tbl_internal_before(id BIGINT UNSIGNED); +CREATE TABLE t1(id BIGINT UNSIGNED); SET character_set_client = utf8mb4; -CREATE TABLE tbl_internal_after(id BIGINT UNSIGNED); +CREATE TABLE t2(id BIGINT UNSIGNED); + +--echo +--echo +--echo *** Making sure that binlog events created implicitly via stored procedures +--echo *** and triggers have character_set_client = 45 +delimiter |; +CREATE TRIGGER test_trigger BEFORE INSERT ON t2 FOR EACH ROW +BEGIN + INSERT INTO t1 SET id = NEW.id; +END| + +CREATE PROCEDURE proc() +BEGIN + INSERT INTO t2 VALUES (42); +END| +delimiter ;| + +INSERT INTO t2 VALUES(1); +CALL proc(); --echo --echo diff --git a/sql/trigger_creation_ctx.cc b/sql/trigger_creation_ctx.cc index 28f6e246436a..461851d97fe0 100644 --- a/sql/trigger_creation_ctx.cc +++ b/sql/trigger_creation_ctx.cc @@ -61,6 +61,20 @@ Trigger_creation_ctx *Trigger_creation_ctx::create( invalid_creation_ctx = true; } + // if 'default_collation_for_utf8mb4' is set to something other than + // default 'utf8mb4' collation ('utf8mb4_0900_ai_ci') and if the value + // returned by 'resolve_charset()' is also default 'utf8mb4' + // collation ('utf8mb4_0900_ai_ci'), meaning that we were trying to resolve + // 'utf8mb4', we need to fix the returned value depending on the value of + // 'default_collation_for_utf8mb4' (currently, only 'utf8mb4_general_ci' + // is possible) + if (thd->variables.default_collation_for_utf8mb4 != + &my_charset_utf8mb4_0900_ai_ci) { + if (client_cs == &my_charset_utf8mb4_0900_ai_ci) { + client_cs = thd->variables.default_collation_for_utf8mb4; + } + } + if (resolve_collation(connection_cl_name.str, thd->variables.collation_connection, &connection_cl)) { LogErr(WARNING_LEVEL, ER_TRIGGER_INVALID_VALUE, (const char *)db_name.str, From e5dc3bfbe9b22c7cb804b2ea3e6946b928987452 Mon Sep 17 00:00:00 2001 From: Yura Sorokin Date: Tue, 22 Oct 2024 01:30:14 +0200 Subject: [PATCH 7/8] PS-9237 feature: Include support for utf8mb4_0900_ai_ci in MySQL 5.7 (SET CHARACTER SET) https://perconadev.atlassian.net/browse/PS-9237 'SET CHARACTER SET' statement now also takes into account the value of the 'default_collation_for_utf8mb4' system variable. 'main.percona_default_collation_for_utf8mb4_extensions' MTR test case extended with additional checks for 'SET NAMES' and `SET CHARACTER SET`. --- ..._default_collation_for_utf8mb4_extensions.result | 10 ++++++++++ ...na_default_collation_for_utf8mb4_extensions.test | 13 +++++++++++++ sql/parse_tree_nodes.cc | 9 +++++++++ 3 files changed, 32 insertions(+) diff --git a/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result b/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result index 086fc7ea331c..bbc72c90c9ec 100644 --- a/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result +++ b/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result @@ -99,6 +99,16 @@ default_collation_for_utf8mb4 utf8mb4_general_ci CREATE TABLE t1(id BIGINT UNSIGNED); SET character_set_client = utf8mb4; CREATE TABLE t2(id BIGINT UNSIGNED); +SET NAMES DEFAULT; +CREATE TABLE t3(id BIGINT UNSIGNED); +SET NAMES utf8mb4; +CREATE TABLE t4(id BIGINT UNSIGNED); +SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; +CREATE TABLE t5(id BIGINT UNSIGNED); +SET CHARACTER SET DEFAULT; +CREATE TABLE t6(id BIGINT UNSIGNED); +SET CHARACTER SET utf8mb4; +CREATE TABLE t7(id BIGINT UNSIGNED); *** Making sure that binlog events created implicitly via stored procedures diff --git a/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test b/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test index ceb43d876c7c..ab5554d7dfc2 100644 --- a/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test +++ b/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test @@ -75,6 +75,19 @@ eval $session_col_stmt; CREATE TABLE t1(id BIGINT UNSIGNED); SET character_set_client = utf8mb4; CREATE TABLE t2(id BIGINT UNSIGNED); +SET NAMES DEFAULT; +CREATE TABLE t3(id BIGINT UNSIGNED); +SET NAMES utf8mb4; +CREATE TABLE t4(id BIGINT UNSIGNED); +SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; +CREATE TABLE t5(id BIGINT UNSIGNED); +# Note that 'SET NAMES utf8mb4 COLLATE utf8mb4_0900_ai_ci' will generate +# character_set_client=45 in the binary log +SET CHARACTER SET DEFAULT; +CREATE TABLE t6(id BIGINT UNSIGNED); +SET CHARACTER SET utf8mb4; +CREATE TABLE t7(id BIGINT UNSIGNED); + --echo --echo diff --git a/sql/parse_tree_nodes.cc b/sql/parse_tree_nodes.cc index 4cb3666c5068..e88176be3ab2 100644 --- a/sql/parse_tree_nodes.cc +++ b/sql/parse_tree_nodes.cc @@ -191,6 +191,15 @@ bool PT_option_value_no_option_type_charset::contextualize(Parse_context *pc) { const CHARSET_INFO *cs2; cs2 = opt_charset ? opt_charset : global_system_variables.character_set_client; + // Fixing cs2 in case when default_collation_for_utf8mb4 is set to non-default + // value + if (thd->variables.default_collation_for_utf8mb4 != + &my_charset_utf8mb4_0900_ai_ci) { + if (cs2 == &my_charset_utf8mb4_0900_ai_ci) { + cs2 = thd->variables.default_collation_for_utf8mb4; + } + } + set_var_collation_client *var; var = new (thd->mem_root) set_var_collation_client( flags, cs2, thd->variables.collation_database, cs2); From bfc10f2c99f0f92d36d718a51eae292c36197869 Mon Sep 17 00:00:00 2001 From: Yura Sorokin Date: Tue, 22 Oct 2024 01:47:12 +0200 Subject: [PATCH 8/8] PS-9237 feature: Include support for utf8mb4_0900_ai_ci in MySQL 5.7 (SET collation_connection mtr) https://perconadev.atlassian.net/browse/PS-9237 'main.percona_default_collation_for_utf8mb4_extensions' MTR test case extended with additional checks for 'SET collation_connection'. --- ...ona_default_collation_for_utf8mb4_extensions.result | 2 ++ ...rcona_default_collation_for_utf8mb4_extensions.test | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result b/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result index bbc72c90c9ec..05570c42ba56 100644 --- a/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result +++ b/mysql-test/r/percona_default_collation_for_utf8mb4_extensions.result @@ -109,6 +109,8 @@ SET CHARACTER SET DEFAULT; CREATE TABLE t6(id BIGINT UNSIGNED); SET CHARACTER SET utf8mb4; CREATE TABLE t7(id BIGINT UNSIGNED); +SET collation_connection = utf8mb4_general_ci; +CREATE TABLE t8(id BIGINT UNSIGNED); *** Making sure that binlog events created implicitly via stored procedures diff --git a/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test b/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test index ab5554d7dfc2..cb37f6507ad3 100644 --- a/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test +++ b/mysql-test/t/percona_default_collation_for_utf8mb4_extensions.test @@ -82,11 +82,19 @@ CREATE TABLE t4(id BIGINT UNSIGNED); SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; CREATE TABLE t5(id BIGINT UNSIGNED); # Note that 'SET NAMES utf8mb4 COLLATE utf8mb4_0900_ai_ci' will generate -# character_set_client=45 in the binary log +# character_set_client=255 in the binary log. SET CHARACTER SET DEFAULT; CREATE TABLE t6(id BIGINT UNSIGNED); SET CHARACTER SET utf8mb4; CREATE TABLE t7(id BIGINT UNSIGNED); +SET collation_connection = utf8mb4_general_ci; +CREATE TABLE t8(id BIGINT UNSIGNED); +# Note that 'SET collation_connection = utf8mb4_0900_ai_ci' will generate +# character_set_client=255 in the binary log. +# Also statements like 'SET collation_connection = utf8mb4' when we try to +# assign a character set name to a collation variable are considered +# syntactically incorrect, so we do not include such checks into the test +# plan. --echo