MDEV-31018 Replica of 10.3, 10.4, <10.5.19 and <10.6.12 to 10.11 will not work when using non-default charset

MDEV-28769 earlier disabled the use if IDs with non-default collations
in statements like:

  SET character_set_results=2/*latin2_czech_cs*/;
  SET character_set_client=2/*latin2_czech_cs*/;
  SET character_set_server=2/*latin2_czech_cs*/;
  SET character_set_connection=2/*latin2_czech_cs*/;

MDEV-30824 later fixed "mysqlbinlog" to dump character set names
instead of IDs in these statements:

< SET @@session.character_set_client=33, ... /*!*/;
> SET @@session.character_set_client=utf8mb3, ... /*!*/;

However, mysqlbinlog from old (pre MDEV-30824) distributions can
still produce incorrect statements with numeric non-default
collation IDs.

New servers should still be able to load old dumps.

Allowing the use of "SET @@character_set_xxx=ID" with numeric
non-default collation IDs but only if:

- the current THD is a true slave thread or
- the current THD a pseudo slave thread
  (loading a mysqlbinlog output).
This commit is contained in:
Alexander Barkov 2023-04-10 11:35:38 +04:00
commit 46af63bfe2
9 changed files with 107 additions and 4 deletions

View file

@ -500,5 +500,16 @@ res
#
SET GLOBAL character_set_client=2;
ERROR 42000: Unknown character set: '2'
#
# MDEV-31018 Replica of 10.3, 10.4, <10.5.19 and <10.6.12 to 10.11 will not work when using non-default charset
#
SET @@pseudo_slave_mode=1;
SET character_set_client=2/*latin2_czech_cs*/;
SHOW VARIABLES LIKE 'character_set_client';
Variable_name Value
character_set_client latin2
SET @@pseudo_slave_mode=0;
Warnings:
Warning 1231 Slave applier execution mode not active, statement ineffective.
SET @@global.character_set_client = @global_start_value;
SET @@session.character_set_client = @session_start_value;

View file

@ -494,5 +494,21 @@ SELECT @@session.character_set_connection =
WHERE VARIABLE_NAME='character_set_connection') AS res;
res
1
#
# MDEV-31018 Replica of 10.3, 10.4, <10.5.19 and <10.6.12 to 10.11 will not work when using non-default charset
#
SET character_set_connection=2/*latin2_czech_cs*/;
ERROR 42000: Unknown character set: '2'
SET @@pseudo_slave_mode=1;
SET character_set_connection=2/*latin2_czech_cs*/;
SHOW VARIABLES LIKE 'character_set_connection';
Variable_name Value
character_set_connection latin2
SHOW VARIABLES LIKE 'collation_connection';
Variable_name Value
collation_connection latin2_general_ci
SET @@pseudo_slave_mode=0;
Warnings:
Warning 1231 Slave applier execution mode not active, statement ineffective.
SET @@global.character_set_connection = @global_start_value;
SET @@global.character_set_client = @save_character_set_client;

View file

@ -486,5 +486,21 @@ SELECT @@session.character_set_server =
WHERE VARIABLE_NAME='character_set_server') AS res;
res
1
#
# MDEV-31018 Replica of 10.3, 10.4, <10.5.19 and <10.6.12 to 10.11 will not work when using non-default charset
#
SET character_set_server=2/*latin2_czech_cs*/;
ERROR 42000: Unknown character set: '2'
SET @@pseudo_slave_mode=1;
SET character_set_server=2/*latin2_czech_cs*/;
SHOW VARIABLES LIKE 'character_set_server';
Variable_name Value
character_set_server latin2
SHOW VARIABLES LIKE 'collation_server';
Variable_name Value
collation_server latin2_general_ci
SET @@pseudo_slave_mode=0;
Warnings:
Warning 1231 Slave applier execution mode not active, statement ineffective.
SET @@global.character_set_server = @global_start_value;
SET @@session.character_set_server = @session_start_value;

View file

@ -350,6 +350,15 @@ SELECT @@session.character_set_client =
--error ER_UNKNOWN_CHARACTER_SET
SET GLOBAL character_set_client=2;
--echo #
--echo # MDEV-31018 Replica of 10.3, 10.4, <10.5.19 and <10.6.12 to 10.11 will not work when using non-default charset
--echo #
SET @@pseudo_slave_mode=1;
SET character_set_client=2/*latin2_czech_cs*/;
SHOW VARIABLES LIKE 'character_set_client';
SET @@pseudo_slave_mode=0;
####################################
# Restore initial value #
####################################

View file

@ -275,6 +275,19 @@ SELECT @@session.character_set_connection =
(SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES
WHERE VARIABLE_NAME='character_set_connection') AS res;
--echo #
--echo # MDEV-31018 Replica of 10.3, 10.4, <10.5.19 and <10.6.12 to 10.11 will not work when using non-default charset
--echo #
--error ER_UNKNOWN_CHARACTER_SET
SET character_set_connection=2/*latin2_czech_cs*/;
SET @@pseudo_slave_mode=1;
SET character_set_connection=2/*latin2_czech_cs*/;
SHOW VARIABLES LIKE 'character_set_connection';
SHOW VARIABLES LIKE 'collation_connection';
SET @@pseudo_slave_mode=0;
####################################
# Restore initial value #
####################################

View file

@ -272,6 +272,18 @@ SELECT @@session.character_set_results =
(SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES
WHERE VARIABLE_NAME='character_set_results') AS res;
--echo #
--echo # MDEV-31018 Replica of 10.3, 10.4, <10.5.19 and <10.6.12 to 10.11 will not work when using non-default charset
--echo #
--error ER_UNKNOWN_CHARACTER_SET
SET character_set_results=2/*latin2_czech_cs*/;
SET @@pseudo_slave_mode=1;
SET character_set_results=2;
SHOW VARIABLES LIKE 'character_set_results';
SET @@pseudo_slave_mode=0;
####################################
# Restore initial value #
####################################

View file

@ -266,6 +266,18 @@ SELECT @@session.character_set_server =
(SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES
WHERE VARIABLE_NAME='character_set_server') AS res;
--echo #
--echo # MDEV-31018 Replica of 10.3, 10.4, <10.5.19 and <10.6.12 to 10.11 will not work when using non-default charset
--echo #
--error ER_UNKNOWN_CHARACTER_SET
SET character_set_server=2/*latin2_czech_cs*/;
SET @@pseudo_slave_mode=1;
SET character_set_server=2/*latin2_czech_cs*/;
SHOW VARIABLES LIKE 'character_set_server';
SHOW VARIABLES LIKE 'collation_server';
SET @@pseudo_slave_mode=0;
####################################
# Restore initial value #
####################################

View file

@ -791,12 +791,26 @@ static bool check_charset(sys_var *self, THD *thd, set_var *var)
{
int csno= (int)var->value->val_int();
CHARSET_INFO *cs;
if (!(var->save_result.ptr= cs= get_charset(csno, MYF(0))) ||
!(cs->state & MY_CS_PRIMARY))
if ((var->save_result.ptr= cs= get_charset(csno, MYF(0))))
{
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), llstr(csno, buff));
return true;
/*
Backward compatibility: pre MDEV-30824 servers
can write non-default collation IDs to binary log:
SET character_set_client=83; -- utf8mb3_bin
Convert a non-default collation to the compiled default collation,
e.g. utf8mb3_bin to utf8mb3_general_ci, but only if
- THD is a slave thread or
- is processing a mysqlbinlog output.
*/
if ((cs->state & MY_CS_PRIMARY) ||
((thd->variables.pseudo_slave_mode || thd->slave_thread) &&
(var->save_result.ptr=
Lex_exact_charset_opt_extended_collate(cs, true).
find_default_collation())))
return false;
}
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), llstr(csno, buff));
return true;
}
return false;
}