From a923d6f49c1ad6fd3f4d6ec02e444c26e4d1dfa8 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 16 Jun 2022 10:38:35 +0400 Subject: [PATCH] MDEV-28769 Assertion `(m_ci->state & 32) || m_with_collate' failed in Lex_exact_charset_opt_extended_collate::Lex_exact_charset_opt_extended_collate on SET NAMES These system variables: @@character_set_client @@character_set_connection @@character_set_database @@character_set_filesystem @@character_set_results @@character_set_server can now be set in numeric format only to IDs of default collations, e.g.: SET @@character_set_xxx=9; -- OK (latin2_general_ci is default) SET @@character_set_xxx=2; -- ERROR (latin2_czech_cs is not default) SET @@character_set_xxx=21; -- ERROR (latin2_hungarian_ci is not default) Before this change the server accepted IDs of non-default collations so all three examples above worked without errors, but this could lead to unexpected behavior in later statements. --- .../r/character_set_client_basic.result | 27 ++++++++------- .../r/character_set_connection_basic.result | 26 +++++++------- .../r/character_set_database_basic.result | 22 ++++++------ .../r/character_set_filesystem_basic.result | 11 +++--- .../r/character_set_results_basic.result | Bin 16295 -> 16427 bytes .../r/character_set_server_basic.result | 22 ++++++------ .../t/character_set_client_basic.test | 32 ++++++++++++++---- .../t/character_set_connection_basic.test | 28 +++++++++++---- .../t/character_set_database_basic.test | 24 +++++++++---- .../t/character_set_filesystem_basic.test | 12 +++++-- .../t/character_set_results_basic.test | 25 ++++++++++---- .../t/character_set_server_basic.test | 24 +++++++++---- sql/sys_vars.cc | 4 ++- 13 files changed, 168 insertions(+), 89 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/character_set_client_basic.result b/mysql-test/suite/sys_vars/r/character_set_client_basic.result index a15e1d10b79..d62d88027c7 100644 --- a/mysql-test/suite/sys_vars/r/character_set_client_basic.result +++ b/mysql-test/suite/sys_vars/r/character_set_client_basic.result @@ -383,10 +383,9 @@ SET @@character_set_client = 1; SELECT @@character_set_client; @@character_set_client big5 +# latin2_czech_cs is not a default collation SET @@character_set_client = 2; -SELECT @@character_set_client; -@@character_set_client -latin2 +ERROR 42000: Unknown character set: '2' SET @@character_set_client = 3; SELECT @@character_set_client; @@character_set_client @@ -395,20 +394,19 @@ SET @@character_set_client = 36; SELECT @@character_set_client; @@character_set_client cp866 +# cp1250_polish_ci is not a default collation SET @@character_set_client = 99; -SELECT @@character_set_client; -@@character_set_client -cp1250 +ERROR 42000: Unknown character set: '99' +# Collation ID 100 does not exist SET @@character_set_client = 100; ERROR 42000: Unknown character set: '100' SET @@global.character_set_client = 1; SELECT @@global.character_set_client; @@global.character_set_client big5 +# latin2_czech_cs is not a default collation SET @@global.character_set_client = 2; -SELECT @@global.character_set_client; -@@global.character_set_client -latin2 +ERROR 42000: Unknown character set: '2' SET @@global.character_set_client = 3; SELECT @@global.character_set_client; @@global.character_set_client @@ -417,10 +415,10 @@ SET @@global.character_set_client = 36; SELECT @@global.character_set_client; @@global.character_set_client cp866 +# cp1250_polish_ci is not a default collation SET @@global.character_set_client = 99; -SELECT @@global.character_set_client; -@@global.character_set_client -cp1250 +ERROR 42000: Unknown character set: '99' +# Collation ID 100 does not exist SET @@global.character_set_client = 100; ERROR 42000: Unknown character set: '100' SET @total_charset = (SELECT count(*) FROM INFORMATION_SCHEMA.CHARACTER_SETS); @@ -497,5 +495,10 @@ SELECT @@session.character_set_client = WHERE VARIABLE_NAME='character_set_client') AS res; res 1 +# +# MDEV-28769 Assertion `(m_ci->state & 32) || m_with_collate' failed in Lex_exact_charset_opt_extended_collate::Lex_exact_charset_opt_extended_collate on SET NAMES +# +SET GLOBAL character_set_client=2; +ERROR 42000: Unknown character set: '2' SET @@global.character_set_client = @global_start_value; SET @@session.character_set_client = @session_start_value; diff --git a/mysql-test/suite/sys_vars/r/character_set_connection_basic.result b/mysql-test/suite/sys_vars/r/character_set_connection_basic.result index 6d098f37bd1..e356d62ed2b 100644 --- a/mysql-test/suite/sys_vars/r/character_set_connection_basic.result +++ b/mysql-test/suite/sys_vars/r/character_set_connection_basic.result @@ -378,10 +378,9 @@ SET @@character_set_connection = 1; SELECT @@character_set_connection; @@character_set_connection big5 +# latin2_czech_cs is not a default collation SET @@character_set_connection = 2; -SELECT @@character_set_connection; -@@character_set_connection -latin2 +ERROR 42000: Unknown character set: '2' SET @@character_set_connection = 3; SELECT @@character_set_connection; @@character_set_connection @@ -390,20 +389,19 @@ SET @@character_set_connection = 36; SELECT @@character_set_connection; @@character_set_connection cp866 +# cp1250_polish_ci is not a default collation SET @@character_set_connection = 99; -SELECT @@character_set_connection; -@@character_set_connection -cp1250 +ERROR 42000: Unknown character set: '99' +# Collation ID 100 does not exist SET @@character_set_connection = 100; ERROR 42000: Unknown character set: '100' SET @@global.character_set_connection = 1; SELECT @@global.character_set_connection; @@global.character_set_connection big5 +# latin2_czech_cs is not a default collation SET @@global.character_set_connection = 2; -SELECT @@global.character_set_connection; -@@global.character_set_connection -latin2 +ERROR 42000: Unknown character set: '2' SET @@global.character_set_connection = 3; SELECT @@global.character_set_connection; @@global.character_set_connection @@ -412,10 +410,10 @@ SET @@global.character_set_connection = 36; SELECT @@global.character_set_connection; @@global.character_set_connection cp866 +# cp1250_polish_ci is not a default collation SET @@global.character_set_connection = 99; -SELECT @@global.character_set_connection; -@@global.character_set_connection -cp1250 +ERROR 42000: Unknown character set: '99' +# Collation ID 100 does not exist SET @@global.character_set_connection = 100; ERROR 42000: Unknown character set: '100' SET @total_charset = (SELECT count(*) FROM INFORMATION_SCHEMA.CHARACTER_SETS); @@ -435,8 +433,12 @@ SET @@character_set_connection = -1; ERROR 42000: Unknown character set: '-1' SET @@character_set_connection = 'utf8 '; ERROR 42000: Unknown character set: 'utf8 ' +SET @@character_set_connection=cp1250; SET @@character_set_connection = 'lätin2'; ERROR 42000: Unknown character set: 'lätin2' +SET @@character_set_connection=cp866; +SET @@character_set_connection = 'lätin2'; +ERROR 42000: Unknown character set: 'l?tin2' SET @@character_set_connection = true; SELECT @@character_set_connection AS res_with_true; res_with_true diff --git a/mysql-test/suite/sys_vars/r/character_set_database_basic.result b/mysql-test/suite/sys_vars/r/character_set_database_basic.result index 752dad8500e..c15e0531efc 100644 --- a/mysql-test/suite/sys_vars/r/character_set_database_basic.result +++ b/mysql-test/suite/sys_vars/r/character_set_database_basic.result @@ -380,10 +380,9 @@ SET @@character_set_database = 1; SELECT @@character_set_database; @@character_set_database big5 +# latin2_czech_cs is not a default collation SET @@character_set_database = 2; -SELECT @@character_set_database; -@@character_set_database -latin2 +ERROR 42000: Unknown character set: '2' SET @@character_set_database = 3; SELECT @@character_set_database; @@character_set_database @@ -392,20 +391,19 @@ SET @@character_set_database = 36; SELECT @@character_set_database; @@character_set_database cp866 +# cp1250_polish_ci is not a default collation SET @@character_set_database = 99; -SELECT @@character_set_database; -@@character_set_database -cp1250 +ERROR 42000: Unknown character set: '99' +# Collation ID 100 does not exist SET @@character_set_database = 100; ERROR 42000: Unknown character set: '100' SET @@global.character_set_database = 1; SELECT @@global.character_set_database; @@global.character_set_database big5 +# latin2_czech_cs is not a default collation SET @@global.character_set_database = 2; -SELECT @@global.character_set_database; -@@global.character_set_database -latin2 +ERROR 42000: Unknown character set: '2' SET @@global.character_set_database = 3; SELECT @@global.character_set_database; @@global.character_set_database @@ -414,10 +412,10 @@ SET @@global.character_set_database = 36; SELECT @@global.character_set_database; @@global.character_set_database cp866 +# cp1250_polish_ci is not a default collation SET @@global.character_set_database = 99; -SELECT @@global.character_set_database; -@@global.character_set_database -cp1250 +ERROR 42000: Unknown character set: '99' +# Collation ID 100 does not exist SET @@global.character_set_database = 100; ERROR 42000: Unknown character set: '100' SET @total_charset = (SELECT count(*) FROM INFORMATION_SCHEMA.CHARACTER_SETS); diff --git a/mysql-test/suite/sys_vars/r/character_set_filesystem_basic.result b/mysql-test/suite/sys_vars/r/character_set_filesystem_basic.result index 8c5b5e524ba..da85a7dee54 100644 --- a/mysql-test/suite/sys_vars/r/character_set_filesystem_basic.result +++ b/mysql-test/suite/sys_vars/r/character_set_filesystem_basic.result @@ -379,10 +379,9 @@ SET @@character_set_filesystem = 1; SELECT @@character_set_filesystem; @@character_set_filesystem big5 +# latin2_czech_cs is not a default collation SET @@character_set_filesystem = 2; -SELECT @@character_set_filesystem; -@@character_set_filesystem -latin2 +ERROR 42000: Unknown character set: '2' SET @@character_set_filesystem = 3; SELECT @@character_set_filesystem; @@character_set_filesystem @@ -391,10 +390,10 @@ SET @@character_set_filesystem = 36; SELECT @@character_set_filesystem; @@character_set_filesystem cp866 +# cp1250_polish_ci is not a default collation SET @@character_set_filesystem = 99; -SELECT @@character_set_filesystem; -@@character_set_filesystem -cp1250 +ERROR 42000: Unknown character set: '99' +# Collation ID 100 does not exist SET @@character_set_filesystem = 100; ERROR 42000: Unknown character set: '100' SET @total_charset = (SELECT count(*) FROM INFORMATION_SCHEMA.CHARACTER_SETS); diff --git a/mysql-test/suite/sys_vars/r/character_set_results_basic.result b/mysql-test/suite/sys_vars/r/character_set_results_basic.result index 86cd9265efbfe1a53602572b01f683c8aa56a26a..d1c6a52ba177c0b07efa3ba653ea42c1025b3e94 100644 GIT binary patch delta 358 zcmZ2pzq)~OgMq$|vO-Q`NoJl=d~#K4az=b|u|j6CLSBA}LZU)SYFc7xPKiQtehx@Y ze%|Dby7G)hlLf8RnT*syoXP9-7w9T0Bo`POnHt0wFWhLGg$&5p)tJOJXpczgf= delta 109 zcmZ48z_`4AgMt2JVGB7%qsbrjtR|o5<(<4kS7P!J{RNZ#)!8P`Fp!!2SXGZ|F%*mNQ&9xkW}5sNstate & 32) || m_with_collate' failed in Lex_exact_charset_opt_extended_collate::Lex_exact_charset_opt_extended_collate on SET NAMES +--echo # + +--error ER_UNKNOWN_CHARACTER_SET +SET GLOBAL character_set_client=2; + #################################### # Restore initial value # #################################### diff --git a/mysql-test/suite/sys_vars/t/character_set_connection_basic.test b/mysql-test/suite/sys_vars/t/character_set_connection_basic.test index 5d6412dd420..3d9094fca04 100644 --- a/mysql-test/suite/sys_vars/t/character_set_connection_basic.test +++ b/mysql-test/suite/sys_vars/t/character_set_connection_basic.test @@ -155,30 +155,42 @@ SELECT @@global.character_set_connection; ############################################################## SET @@character_set_connection = 1; SELECT @@character_set_connection; + +--echo # latin2_czech_cs is not a default collation +--error ER_UNKNOWN_CHARACTER_SET SET @@character_set_connection = 2; -SELECT @@character_set_connection; + SET @@character_set_connection = 3; SELECT @@character_set_connection; SET @@character_set_connection = 36; SELECT @@character_set_connection; -SET @@character_set_connection = 99; -SELECT @@character_set_connection; +--echo # cp1250_polish_ci is not a default collation +--error ER_UNKNOWN_CHARACTER_SET +SET @@character_set_connection = 99; + +--echo # Collation ID 100 does not exist --Error ER_UNKNOWN_CHARACTER_SET SET @@character_set_connection = 100; SET @@global.character_set_connection = 1; SELECT @@global.character_set_connection; + +--echo # latin2_czech_cs is not a default collation +--error ER_UNKNOWN_CHARACTER_SET SET @@global.character_set_connection = 2; -SELECT @@global.character_set_connection; + SET @@global.character_set_connection = 3; SELECT @@global.character_set_connection; SET @@global.character_set_connection = 36; SELECT @@global.character_set_connection; -SET @@global.character_set_connection = 99; -SELECT @@global.character_set_connection; +--echo # cp1250_polish_ci is not a default collation +--error ER_UNKNOWN_CHARACTER_SET +SET @@global.character_set_connection = 99; + +--echo # Collation ID 100 does not exist --Error ER_UNKNOWN_CHARACTER_SET SET @@global.character_set_connection = 100; @@ -201,6 +213,10 @@ SET @@character_set_connection = 1.1; SET @@character_set_connection = -1; --Error ER_UNKNOWN_CHARACTER_SET SET @@character_set_connection = 'utf8 '; +SET @@character_set_connection=cp1250; +--Error ER_UNKNOWN_CHARACTER_SET +SET @@character_set_connection = 'lätin2'; +SET @@character_set_connection=cp866; --Error ER_UNKNOWN_CHARACTER_SET SET @@character_set_connection = 'lätin2'; SET @@character_set_connection = true; diff --git a/mysql-test/suite/sys_vars/t/character_set_database_basic.test b/mysql-test/suite/sys_vars/t/character_set_database_basic.test index 54ccc5afddb..95ffa83950f 100644 --- a/mysql-test/suite/sys_vars/t/character_set_database_basic.test +++ b/mysql-test/suite/sys_vars/t/character_set_database_basic.test @@ -154,30 +154,42 @@ SELECT @@global.character_set_database; ############################################################## SET @@character_set_database = 1; SELECT @@character_set_database; + +--echo # latin2_czech_cs is not a default collation +--error ER_UNKNOWN_CHARACTER_SET SET @@character_set_database = 2; -SELECT @@character_set_database; + SET @@character_set_database = 3; SELECT @@character_set_database; SET @@character_set_database = 36; SELECT @@character_set_database; -SET @@character_set_database = 99; -SELECT @@character_set_database; +--echo # cp1250_polish_ci is not a default collation +--error ER_UNKNOWN_CHARACTER_SET +SET @@character_set_database = 99; + +--echo # Collation ID 100 does not exist --Error ER_UNKNOWN_CHARACTER_SET SET @@character_set_database = 100; SET @@global.character_set_database = 1; SELECT @@global.character_set_database; + +--echo # latin2_czech_cs is not a default collation +--error ER_UNKNOWN_CHARACTER_SET SET @@global.character_set_database = 2; -SELECT @@global.character_set_database; + SET @@global.character_set_database = 3; SELECT @@global.character_set_database; SET @@global.character_set_database = 36; SELECT @@global.character_set_database; -SET @@global.character_set_database = 99; -SELECT @@global.character_set_database; +--echo # cp1250_polish_ci is not a default collation +--error ER_UNKNOWN_CHARACTER_SET +SET @@global.character_set_database = 99; + +--echo # Collation ID 100 does not exist --Error ER_UNKNOWN_CHARACTER_SET SET @@global.character_set_database = 100; diff --git a/mysql-test/suite/sys_vars/t/character_set_filesystem_basic.test b/mysql-test/suite/sys_vars/t/character_set_filesystem_basic.test index 33b77eede06..b3ebb38360e 100644 --- a/mysql-test/suite/sys_vars/t/character_set_filesystem_basic.test +++ b/mysql-test/suite/sys_vars/t/character_set_filesystem_basic.test @@ -151,15 +151,21 @@ SELECT @@character_set_filesystem; ############################################################## SET @@character_set_filesystem = 1; SELECT @@character_set_filesystem; + +--echo # latin2_czech_cs is not a default collation +--error ER_UNKNOWN_CHARACTER_SET SET @@character_set_filesystem = 2; -SELECT @@character_set_filesystem; + SET @@character_set_filesystem = 3; SELECT @@character_set_filesystem; SET @@character_set_filesystem = 36; SELECT @@character_set_filesystem; -SET @@character_set_filesystem = 99; -SELECT @@character_set_filesystem; +--echo # cp1250_polish_ci is not a default collation +--error ER_UNKNOWN_CHARACTER_SET +SET @@character_set_filesystem = 99; + +--echo # Collation ID 100 does not exist --Error ER_UNKNOWN_CHARACTER_SET SET @@character_set_filesystem = 100; diff --git a/mysql-test/suite/sys_vars/t/character_set_results_basic.test b/mysql-test/suite/sys_vars/t/character_set_results_basic.test index cca2277713e..617332b9780 100644 --- a/mysql-test/suite/sys_vars/t/character_set_results_basic.test +++ b/mysql-test/suite/sys_vars/t/character_set_results_basic.test @@ -153,29 +153,42 @@ SELECT @@global.character_set_results; ############################################################## SET @@character_set_results = 1; SELECT @@character_set_results; + +--echo # latin2_czech_cs is not a default collation +--error ER_UNKNOWN_CHARACTER_SET SET @@character_set_results = 2; -SELECT @@character_set_results; + SET @@character_set_results = 3; SELECT @@character_set_results; SET @@character_set_results = 36; SELECT @@character_set_results; -SET @@character_set_results = 99; -SELECT @@character_set_results; +--echo # cp1250_polish_ci is not a default collation +--error ER_UNKNOWN_CHARACTER_SET +SET @@character_set_results = 99; + +--echo # Collation ID 100 does not exist --Error ER_UNKNOWN_CHARACTER_SET SET @@character_set_results = 100; + SET @@global.character_set_results = 1; SELECT @@global.character_set_results; + +--echo # latin2_czech_cs is not a default collation +--error ER_UNKNOWN_CHARACTER_SET SET @@global.character_set_results = 2; -SELECT @@global.character_set_results; + SET @@global.character_set_results = 3; SELECT @@global.character_set_results; SET @@global.character_set_results = 36; SELECT @@global.character_set_results; -SET @@global.character_set_results = 99; -SELECT @@global.character_set_results; +--echo # cp1250_polish_ci is not a default collation +--error ER_UNKNOWN_CHARACTER_SET +SET @@global.character_set_results = 99; + +--echo # Collation ID 100 does not exist --Error ER_UNKNOWN_CHARACTER_SET SET @@global.character_set_results = 100; diff --git a/mysql-test/suite/sys_vars/t/character_set_server_basic.test b/mysql-test/suite/sys_vars/t/character_set_server_basic.test index de090348307..b2f4788fdae 100644 --- a/mysql-test/suite/sys_vars/t/character_set_server_basic.test +++ b/mysql-test/suite/sys_vars/t/character_set_server_basic.test @@ -155,27 +155,39 @@ SELECT @@global.character_set_server; ############################################################## SET @@character_set_server = 1; SELECT @@character_set_server; + +--echo # latin2_czech_cs is not a default collation +--error ER_UNKNOWN_CHARACTER_SET SET @@character_set_server = 2; -SELECT @@character_set_server; + SET @@character_set_server = 3; SELECT @@character_set_server; SET @@character_set_server = 36; SELECT @@character_set_server; -SET @@character_set_server = 99; -SELECT @@character_set_server; +--echo # cp1250_polish_ci is not a default collation +--error ER_UNKNOWN_CHARACTER_SET +SET @@character_set_server = 99; + +--echo # Collation ID 100 does not exist --Error ER_UNKNOWN_CHARACTER_SET SET @@character_set_server = 100; SET @@global.character_set_server = 1; SELECT @@global.character_set_server; + +--echo # latin2_czech_cs is not a default collation +--error ER_UNKNOWN_CHARACTER_SET SET @@global.character_set_server = 2; -SELECT @@global.character_set_server; + SET @@global.character_set_server = 36; SELECT @@global.character_set_server; -SET @@global.character_set_server = 99; -SELECT @@global.character_set_server; +--echo # cp1250_polish_ci is not a default collation +--error ER_UNKNOWN_CHARACTER_SET +SET @@global.character_set_server = 99; + +--echo # Collation ID 100 does not exist --Error ER_UNKNOWN_CHARACTER_SET SET @@global.character_set_server = 100; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index da308f5b734..eb8137c26a8 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -789,7 +789,9 @@ static bool check_charset(sys_var *self, THD *thd, set_var *var) else // INT_RESULT { int csno= (int)var->value->val_int(); - if (!(var->save_result.ptr= get_charset(csno, MYF(0)))) + CHARSET_INFO *cs; + if (!(var->save_result.ptr= cs= get_charset(csno, MYF(0))) || + !(cs->state & MY_CS_PRIMARY)) { my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), llstr(csno, buff)); return true;