mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-34288 SET NAMES DEFAULT crashes mariadbd --collation-server=utf8mb4_unicode_ci
The @@global.character_set_client variable could erroneously be set to a non-default collation of its character set, which further made the `SET NAMES DEFAULT` statement crash the server. Fixing the code to make sure that the global value these variables: @@character_set_client @@character_set_connection @@character_set_server @@character_set_database @@character_set_connection point to the default compiled collations of the character set.
This commit is contained in:
parent
d61947550a
commit
76e0dc18b6
9 changed files with 156 additions and 16 deletions
|
@ -9,3 +9,48 @@ DROP TABLE t1;
|
|||
#
|
||||
# End of 10.3 tests
|
||||
#
|
||||
#
|
||||
# Start of 10.11 tests
|
||||
#
|
||||
#
|
||||
# MDEV-34288 SET NAMES DEFAULT crashes `mariadbd --collation-server=utf8mb4_unicode_ci`
|
||||
#
|
||||
SET NAMES DEFAULT COLLATE latin1_bin;
|
||||
ERROR 42000: COLLATION 'latin1_bin' is not valid for CHARACTER SET 'utf8mb4'
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
@@character_set_connection @@collation_connection @@character_set_results
|
||||
latin1 latin1_swedish_ci latin1
|
||||
SET NAMES DEFAULT COLLATE utf8mb4_bin;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
@@character_set_connection @@collation_connection @@character_set_results
|
||||
utf8mb4 utf8mb4_bin utf8mb4
|
||||
SET NAMES DEFAULT COLLATE uca1400_ai_ci;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
@@character_set_connection @@collation_connection @@character_set_results
|
||||
utf8mb4 utf8mb4_uca1400_ai_ci utf8mb4
|
||||
SET @@global.character_set_client=latin1;
|
||||
SET NAMES DEFAULT;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
@@character_set_connection @@collation_connection @@character_set_results
|
||||
latin1 latin1_swedish_ci latin1
|
||||
SET @@global.character_set_client=utf8mb3;
|
||||
SET NAMES DEFAULT;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
@@character_set_connection @@collation_connection @@character_set_results
|
||||
utf8mb3 utf8mb3_general_ci utf8mb3
|
||||
SET @@global.character_set_client=DEFAULT;
|
||||
SET NAMES DEFAULT;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
@@character_set_connection @@collation_connection @@character_set_results
|
||||
utf8mb4 utf8mb4_general_ci utf8mb4
|
||||
SET NAMES DEFAULT;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
@@character_set_connection @@collation_connection @@character_set_results
|
||||
utf8mb4 utf8mb4_general_ci utf8mb4
|
||||
SET NAMES DEFAULT COLLATE DEFAULT;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
@@character_set_connection @@collation_connection @@character_set_results
|
||||
utf8mb4 utf8mb4_general_ci utf8mb4
|
||||
#
|
||||
# End of 10.11 tests
|
||||
#
|
||||
|
|
|
@ -13,3 +13,45 @@ DROP TABLE t1;
|
|||
--echo #
|
||||
--echo # End of 10.3 tests
|
||||
--echo #
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Start of 10.11 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-34288 SET NAMES DEFAULT crashes `mariadbd --collation-server=utf8mb4_unicode_ci`
|
||||
--echo #
|
||||
|
||||
--error ER_COLLATION_CHARSET_MISMATCH
|
||||
SET NAMES DEFAULT COLLATE latin1_bin;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
|
||||
SET NAMES DEFAULT COLLATE utf8mb4_bin;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
|
||||
SET NAMES DEFAULT COLLATE uca1400_ai_ci;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
|
||||
SET @@global.character_set_client=latin1;
|
||||
SET NAMES DEFAULT;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
|
||||
SET @@global.character_set_client=utf8mb3;
|
||||
SET NAMES DEFAULT;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
|
||||
SET @@global.character_set_client=DEFAULT;
|
||||
SET NAMES DEFAULT;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
|
||||
SET NAMES DEFAULT;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
|
||||
SET NAMES DEFAULT COLLATE DEFAULT;
|
||||
SELECT @@character_set_connection, @@collation_connection, @@character_set_results;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.11 tests
|
||||
--echo #
|
||||
|
|
|
@ -288,6 +288,12 @@ public:
|
|||
DBUG_ASSERT(0);
|
||||
return m_ci->coll_name;
|
||||
}
|
||||
static Lex_extended_collation_st collate_default()
|
||||
{
|
||||
Lex_extended_collation_st res;
|
||||
res.set_collate_default();
|
||||
return res;
|
||||
}
|
||||
void set_collate_default()
|
||||
{
|
||||
m_ci= &my_collation_contextually_typed_default;
|
||||
|
|
|
@ -4329,8 +4329,10 @@ static int init_common_variables()
|
|||
if (is_supported_parser_charset(default_charset_info))
|
||||
{
|
||||
global_system_variables.collation_connection= default_charset_info;
|
||||
global_system_variables.character_set_results= default_charset_info;
|
||||
global_system_variables.character_set_client= default_charset_info;
|
||||
global_system_variables.character_set_results=
|
||||
global_system_variables.character_set_client=
|
||||
Lex_exact_charset_opt_extended_collate(default_charset_info, true).
|
||||
find_default_collation();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -12131,10 +12131,31 @@ bool LEX::sp_create_set_password_instr(THD *thd,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Handle the SET NAMES statement variants, e.g.:
|
||||
SET NAMES DEFAULT;
|
||||
SET NAMES DEFAULT COLLATE DEFAULT;
|
||||
SET NAMES DEFAULT COLLATE latin1_bin;
|
||||
SET NAMES latin1;
|
||||
SET NAMES latin1 COLLATE DEFAULT;
|
||||
SET NAMES latin1 COLLATE latin1_bin;
|
||||
SET NAMES utf8mb4 COLLATE uca1400_ai_ci;
|
||||
|
||||
@param pos - The position of the keyword `NAMES` inside the query
|
||||
@param cs - The character set part, or nullptr if DEFAULT
|
||||
@param cl - The collation (explicit or contextually typed)
|
||||
@param no_lookahead - The tokinizer lookahead state
|
||||
*/
|
||||
bool LEX::set_names(const char *pos,
|
||||
const Lex_exact_charset_opt_extended_collate &cscl,
|
||||
CHARSET_INFO *cs,
|
||||
const Lex_extended_collation_st &cl,
|
||||
bool no_lookahead)
|
||||
{
|
||||
CHARSET_INFO *def= global_system_variables.character_set_client;
|
||||
Lex_exact_charset_opt_extended_collate cscl(cs ? cs : def, true);
|
||||
if (cscl.merge_collation_override(cl))
|
||||
return true;
|
||||
|
||||
if (sp_create_assignment_lex(thd, pos))
|
||||
return true;
|
||||
CHARSET_INFO *ci= cscl.collation().charset_info();
|
||||
|
|
|
@ -3873,7 +3873,8 @@ public:
|
|||
int case_stmt_action_then();
|
||||
bool setup_select_in_parentheses();
|
||||
bool set_names(const char *pos,
|
||||
const Lex_exact_charset_opt_extended_collate &cs,
|
||||
CHARSET_INFO *cs,
|
||||
const Lex_extended_collation_st &coll,
|
||||
bool no_lookahead);
|
||||
bool set_trigger_new_row(const LEX_CSTRING *name, Item *val);
|
||||
bool set_trigger_field(const LEX_CSTRING *name1, const LEX_CSTRING *name2,
|
||||
|
|
|
@ -16671,18 +16671,15 @@ option_value_no_option_type:
|
|||
}
|
||||
| NAMES_SYM charset_name_or_default
|
||||
{
|
||||
CHARSET_INFO *def= global_system_variables.character_set_client;
|
||||
Lex_exact_charset_opt_extended_collate tmp($2 ? $2 : def, false);
|
||||
if (Lex->set_names($1.pos(), tmp, yychar == YYEMPTY))
|
||||
if (Lex->set_names($1.pos(), $2,
|
||||
Lex_extended_collation_st::collate_default(),
|
||||
yychar == YYEMPTY))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| NAMES_SYM charset_name_or_default
|
||||
COLLATE_SYM collation_name_or_default
|
||||
{
|
||||
CHARSET_INFO *def= global_system_variables.character_set_client;
|
||||
Lex_exact_charset_opt_extended_collate tmp($2 ? $2 : def, false);
|
||||
if (tmp.merge_collation($4) ||
|
||||
Lex->set_names($1.pos(), tmp, yychar == YYEMPTY))
|
||||
if (Lex->set_names($1.pos(), $2, $4, yychar == YYEMPTY))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| DEFAULT ROLE_SYM grant_role
|
||||
|
|
|
@ -824,7 +824,7 @@ static Sys_var_struct Sys_character_set_system(
|
|||
READ_ONLY GLOBAL_VAR(system_charset_info), NO_CMD_LINE,
|
||||
offsetof(CHARSET_INFO, cs_name.str), DEFAULT(0));
|
||||
|
||||
static Sys_var_struct Sys_character_set_server(
|
||||
static Sys_var_charset Sys_character_set_server(
|
||||
"character_set_server", "The default character set",
|
||||
SESSION_VAR(collation_server), NO_CMD_LINE,
|
||||
offsetof(CHARSET_INFO, cs_name.str), DEFAULT(&default_charset_info),
|
||||
|
@ -838,7 +838,7 @@ static bool check_charset_db(sys_var *self, THD *thd, set_var *var)
|
|||
var->save_result.ptr= thd->db_charset;
|
||||
return false;
|
||||
}
|
||||
static Sys_var_struct Sys_character_set_database(
|
||||
static Sys_var_charset Sys_character_set_database(
|
||||
"character_set_database",
|
||||
"The character set used by the default database",
|
||||
SESSION_VAR(collation_database), NO_CMD_LINE,
|
||||
|
@ -862,7 +862,8 @@ static bool fix_thd_charset(sys_var *self, THD *thd, enum_var_type type)
|
|||
thd->update_charset();
|
||||
return false;
|
||||
}
|
||||
static Sys_var_struct Sys_character_set_client(
|
||||
|
||||
static Sys_var_charset Sys_character_set_client(
|
||||
"character_set_client", "The character set for statements "
|
||||
"that arrive from the client",
|
||||
NO_SET_STMT SESSION_VAR(character_set_client), NO_CMD_LINE,
|
||||
|
@ -872,7 +873,7 @@ static Sys_var_struct Sys_character_set_client(
|
|||
// for check changing
|
||||
export sys_var *Sys_character_set_client_ptr= &Sys_character_set_client;
|
||||
|
||||
static Sys_var_struct Sys_character_set_connection(
|
||||
static Sys_var_charset Sys_character_set_connection(
|
||||
"character_set_connection", "The character set used for "
|
||||
"literals that do not have a character set introducer and for "
|
||||
"number-to-string conversion",
|
||||
|
@ -883,7 +884,7 @@ static Sys_var_struct Sys_character_set_connection(
|
|||
// for check changing
|
||||
export sys_var *Sys_character_set_connection_ptr= &Sys_character_set_connection;
|
||||
|
||||
static Sys_var_struct Sys_character_set_results(
|
||||
static Sys_var_charset Sys_character_set_results(
|
||||
"character_set_results", "The character set used for returning "
|
||||
"query results to the client",
|
||||
SESSION_VAR(character_set_results), NO_CMD_LINE,
|
||||
|
|
|
@ -2166,6 +2166,31 @@ public:
|
|||
{ return valptr(thd, *(uchar**)option.def_value); }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
The class to store character sets.
|
||||
*/
|
||||
class Sys_var_charset: public Sys_var_struct
|
||||
{
|
||||
public:
|
||||
using Sys_var_struct::Sys_var_struct;
|
||||
void global_save_default(THD *thd, set_var *var)
|
||||
{
|
||||
/*
|
||||
The default value can point to an arbitrary collation,
|
||||
e.g. default_charset_info.
|
||||
Let's convert it to the compiled default collation.
|
||||
This makes the code easier in various places such as SET NAMES.
|
||||
*/
|
||||
void **default_value= reinterpret_cast<void**>(option.def_value);
|
||||
var->save_result.ptr=
|
||||
Lex_exact_charset_opt_extended_collate((CHARSET_INFO *) *default_value,
|
||||
true).
|
||||
find_default_collation();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
The class for variables that store time zones
|
||||
|
||||
|
|
Loading…
Reference in a new issue