From b9c7da4c91919b188ea04c528bef5fbf8f9222e6 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 20 Jul 2023 07:44:05 +0400 Subject: [PATCH] MDEV-30003 Assertion failure upon 2nd execution of SP trying to set collation on non-existing database The DBUG_ASSER in HA_CREATE_INFO::resolve_to_charset_collation_context() didn't take into account that the second execution is possible not only during a prepared EXECUTE, but also during a CALL. --- mysql-test/main/ctype_collate_context.result | 28 ++++++++++++++++ mysql-test/main/ctype_collate_context.test | 35 ++++++++++++++++++++ sql/sql_table.cc | 7 ++-- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/ctype_collate_context.result b/mysql-test/main/ctype_collate_context.result index 53eeaa4e713af..d0625f188800a 100644 --- a/mysql-test/main/ctype_collate_context.result +++ b/mysql-test/main/ctype_collate_context.result @@ -1958,3 +1958,31 @@ DROP TABLE results_alter_db; DROP TABLE results_create_table; DROP TABLE results_alter_table; DROP TABLE results_convert_table; +# +# MDEV-30003 Assertion failure upon 2nd execution of SP trying to set collation on non-existing database +# +CREATE PROCEDURE p() ALTER SCHEMA db DEFAULT COLLATE = utf8_bin; +CALL p; +ERROR HY000: Can't create/write to file 'db.opt' (Errcode: 2 "No such file or directory") +CALL p; +ERROR HY000: Can't create/write to file 'db.opt' (Errcode: 2 "No such file or directory") +DROP PROCEDURE p; +CREATE DATABASE db1; +CREATE PROCEDURE p() CREATE DATABASE db1 COLLATE DEFAULT; +CALL p; +ERROR HY000: Can't create database 'db1'; database exists +CALL p; +ERROR HY000: Can't create database 'db1'; database exists +DROP DATABASE db1; +DROP PROCEDURE p; +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p() CREATE TABLE t1 (a INT) COLLATE DEFAULT; +CALL p; +ERROR 42S01: Table 't1' already exists +CALL p; +ERROR 42S01: Table 't1' already exists +DROP TABLE t1; +DROP PROCEDURE p; +# +# End of 10.9 tests +# diff --git a/mysql-test/main/ctype_collate_context.test b/mysql-test/main/ctype_collate_context.test index 0867237a223b4..74444a7177703 100644 --- a/mysql-test/main/ctype_collate_context.test +++ b/mysql-test/main/ctype_collate_context.test @@ -364,3 +364,38 @@ DROP TABLE results_alter_db; DROP TABLE results_create_table; DROP TABLE results_alter_table; DROP TABLE results_convert_table; + +--echo # +--echo # MDEV-30003 Assertion failure upon 2nd execution of SP trying to set collation on non-existing database +--echo # + +CREATE PROCEDURE p() ALTER SCHEMA db DEFAULT COLLATE = utf8_bin; +--replace_regex /to file '.*db.opt'/to file 'db.opt'/ +--error 1 +CALL p; +--replace_regex /to file '.*db.opt'/to file 'db.opt'/ +--error 1 +CALL p; +DROP PROCEDURE p; + +CREATE DATABASE db1; +CREATE PROCEDURE p() CREATE DATABASE db1 COLLATE DEFAULT; +--error ER_DB_CREATE_EXISTS +CALL p; +--error ER_DB_CREATE_EXISTS +CALL p; +DROP DATABASE db1; +DROP PROCEDURE p; + +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p() CREATE TABLE t1 (a INT) COLLATE DEFAULT; +--error ER_TABLE_EXISTS_ERROR +CALL p; +--error ER_TABLE_EXISTS_ERROR +CALL p; +DROP TABLE t1; +DROP PROCEDURE p; + +--echo # +--echo # End of 10.9 tests +--echo # diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f94e81cc3f757..5aa2d6b80800b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -12533,7 +12533,9 @@ bool HA_CREATE_INFO:: else { // Make sure we don't do double resolution in direct SQL execution - DBUG_ASSERT(!default_table_charset || thd->stmt_arena->is_stmt_execute()); + DBUG_ASSERT(!default_table_charset || + thd->stmt_arena->is_stmt_execute() || + thd->stmt_arena->state == Query_arena::STMT_INITIALIZED_FOR_SP); if (!(default_table_charset= default_cscl.resolved_to_context(ctx))) return true; @@ -12545,7 +12547,8 @@ bool HA_CREATE_INFO:: { // Make sure we don't do double resolution in direct SQL execution DBUG_ASSERT(!alter_table_convert_to_charset || - thd->stmt_arena->is_stmt_execute()); + thd->stmt_arena->is_stmt_execute() || + thd->stmt_arena->state == Query_arena::STMT_INITIALIZED_FOR_SP); if (!(alter_table_convert_to_charset= convert_cscl.resolved_to_context(ctx))) return true;