From 629449172a5b0a6975663ca1ac420789e00b941d Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Fri, 30 Apr 2021 23:14:57 +0530 Subject: [PATCH] MDEV-25462: Assertion `m_status == DA_ERROR || m_status == DA_OK || m_status == DA_OK_BULK' failed in Diagnostics_area::message from get_schema_tables_record Analysis: SET NAMES changes character set for character_set_client, character_set_connection, character_set_results to 'filename'. The .frm file of view has @xx sequences in the SELECT query, which give parsing error because 'filename' character set is not parser friendly. When we get parsing error (ER_PARSE_ERROR), we directly return true without setting error status. This is caught later in assertion. Fix: Disallow 'filename' character set in SET NAMES because it is not parser friendly. --- mysql-test/r/ctype_filename.result | 29 +++++++++++++++++++++++++++++ mysql-test/t/ctype_filename.test | 26 ++++++++++++++++++++++++++ sql/sql_class.h | 2 +- sql/sql_view.cc | 7 +++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ctype_filename.result b/mysql-test/r/ctype_filename.result index c6d7d1e39b9..46b48113f9d 100644 --- a/mysql-test/r/ctype_filename.result +++ b/mysql-test/r/ctype_filename.result @@ -21,3 +21,32 @@ SET NAMES utf8; SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a), HEX(REVERSE(@a)); @a BINARY @a REVERSE(@a) HEX(@a) HEX(REVERSE(@a)) aя a@r1 яa 61407231 40723161 +# +# Beginning of 10.2 test. +# +# MDEV-25462: Assertion `m_status == DA_ERROR || m_status == DA_OK || +# m_status == DA_OK_BULK' failed in Diagnostics_area::message from +# get_schema_tables_record +# +SELECT @@character_set_client, @@character_set_connection, @@character_set_results; +@@character_set_client @@character_set_connection @@character_set_results +utf8 utf8 utf8 +SET @old_character_set_client= @@character_set_client; +SET @old_character_set_connection= @@character_set_connection; +SET @old_character_set_results= @@character_set_results; +SET NAMES 'filename'; +ERROR 42000: Variable 'character_set_client' can't be set to the value of 'filename' +SELECT @@character_set_client, @@character_set_connection, @@character_set_results; +@@character_set_client @@character_set_connection @@character_set_results +utf8 utf8 utf8 +CREATE VIEW v2 AS SELECT 1; +SHOW TABLE STATUS; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +v2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL VIEW +DROP VIEW v2; +SET @@character_set_client= @old_character_set_client; +SET @@character_set_connection= @old_character_set_connection; +SET @@character_set_results= @old_character_set_results; +# +# End of 10.2 test +# diff --git a/mysql-test/t/ctype_filename.test b/mysql-test/t/ctype_filename.test index 7ec07293a2b..99735b33ddc 100644 --- a/mysql-test/t/ctype_filename.test +++ b/mysql-test/t/ctype_filename.test @@ -27,3 +27,29 @@ select convert(convert(',' using filename) using binary); --echo # SET NAMES utf8; SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a), HEX(REVERSE(@a)); + +--echo # +--echo # Beginning of 10.2 test. +--echo # +--echo # MDEV-25462: Assertion `m_status == DA_ERROR || m_status == DA_OK || +--echo # m_status == DA_OK_BULK' failed in Diagnostics_area::message from +--echo # get_schema_tables_record +--echo # + +SELECT @@character_set_client, @@character_set_connection, @@character_set_results; +SET @old_character_set_client= @@character_set_client; +SET @old_character_set_connection= @@character_set_connection; +SET @old_character_set_results= @@character_set_results; +--error ER_WRONG_VALUE_FOR_VAR +SET NAMES 'filename'; +SELECT @@character_set_client, @@character_set_connection, @@character_set_results; +CREATE VIEW v2 AS SELECT 1; +SHOW TABLE STATUS; +DROP VIEW v2; +SET @@character_set_client= @old_character_set_client; +SET @@character_set_connection= @old_character_set_connection; +SET @@character_set_results= @old_character_set_results; + +--echo # +--echo # End of 10.2 test +--echo # diff --git a/sql/sql_class.h b/sql/sql_class.h index 890cce7bcb2..472d6294cf8 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -921,7 +921,7 @@ mysqld_collation_get_by_name(const char *name, static inline bool is_supported_parser_charset(CHARSET_INFO *cs) { - return MY_TEST(cs->mbminlen == 1); + return MY_TEST(cs->mbminlen == 1 && cs->number != 17 /* filename */); } #ifdef MYSQL_SERVER diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 0701c5233ac..0547a2fe856 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -878,6 +878,13 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, { LEX *lex= thd->lex; + /* + Ensure character set number != 17 (character set = filename) and mbminlen=1 + because these character sets are not parser friendly, which can give weird + sequence in .frm file of view and later give parsing error. + */ + DBUG_ASSERT(thd->charset()->mbminlen == 1 && thd->charset()->number != 17); + /* View definition query -- a SELECT statement that fully defines view. It is generated from the Item-tree built from the original (specified by