From 1fb4828b283ec3e7d72b0ca341a8bdeb1ed8823a Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Sat, 16 Jul 2022 13:33:15 +0200 Subject: [PATCH] MDEV-28343: sys.create_synonym_db fails with ER_VIEW_SELECT_TMPTABLE when schema contains temporary tables - MDEV-28342 raised the error in case temporary table shadows base table - Now we are allowed to shadow base tables with temporary tables and `sys.create_synonym_db()` can easily check for existance of temporary table and ignore view creation, since it is not supported to create view from temporary table. Reviewed-by: , --- .../sysschema/r/pr_create_synonym_db.result | 33 +++++++++++- .../sysschema/t/pr_create_synonym_db.test | 28 ++++++++++- .../procedures/create_synonym_db.sql | 50 ++++++++----------- 3 files changed, 79 insertions(+), 32 deletions(-) diff --git a/mysql-test/suite/sysschema/r/pr_create_synonym_db.result b/mysql-test/suite/sysschema/r/pr_create_synonym_db.result index 8c0e8dfa957..d23d3bad823 100644 --- a/mysql-test/suite/sysschema/r/pr_create_synonym_db.result +++ b/mysql-test/suite/sysschema/r/pr_create_synonym_db.result @@ -61,6 +61,37 @@ create table t (b int); create table b(a int); create temporary table b (a int); call sys.create_synonym_db('db','db_copy'); -ERROR HY000: Table`db`.`b`shadows base table. View cannot be created! Terminating! +summary +Created 2 views in the `db_copy` database +use db_copy; +show tables; +Tables_in_db_copy +a +t drop database db; drop database db_copy; +# MDEV-28343: sys.create_synonym_db fails with ER_VIEW_SELECT_TMPTABLE +# when schema contains temporary tables +# +create database mytestdb; +use mytestdb; +create table t (b int); +create temporary table tmp (a int); +call sys.create_synonym_db('mytestdb','db_syn1'); +summary +Created 1 view in the `db_syn1` database +use db_syn1; +show tables; +Tables_in_db_syn1 +t +drop database db_syn1; +use mytestdb; +create temporary table t (b int); +call sys.create_synonym_db('mytestdb','db_syn1'); +summary +Created 0 views in the `db_syn1` database +use db_syn1; +show tables; +Tables_in_db_syn1 +drop database mytestdb; +drop database db_syn1; diff --git a/mysql-test/suite/sysschema/t/pr_create_synonym_db.test b/mysql-test/suite/sysschema/t/pr_create_synonym_db.test index 30c6f502e30..b05446c2adf 100644 --- a/mysql-test/suite/sysschema/t/pr_create_synonym_db.test +++ b/mysql-test/suite/sysschema/t/pr_create_synonym_db.test @@ -62,8 +62,34 @@ create table a(a int); create table t (b int); create table b(a int); create temporary table b (a int); ---error ER_SIGNAL_EXCEPTION call sys.create_synonym_db('db','db_copy'); +use db_copy; +show tables; + drop database db; drop database db_copy; +--echo # MDEV-28343: sys.create_synonym_db fails with ER_VIEW_SELECT_TMPTABLE +--echo # when schema contains temporary tables +--echo # + +create database mytestdb; +use mytestdb; +create table t (b int); +# This temporary table will not be created as an view in synonym db +create temporary table tmp (a int); +call sys.create_synonym_db('mytestdb','db_syn1'); +use db_syn1; +show tables; +drop database db_syn1; + +use mytestdb; +# This temporary table will shadow the base table and no views will be created +create temporary table t (b int); +call sys.create_synonym_db('mytestdb','db_syn1'); + +use db_syn1; +show tables; + +drop database mytestdb; +drop database db_syn1; diff --git a/scripts/sys_schema/procedures/create_synonym_db.sql b/scripts/sys_schema/procedures/create_synonym_db.sql index e373a9b4ee6..4827037677c 100644 --- a/scripts/sys_schema/procedures/create_synonym_db.sql +++ b/scripts/sys_schema/procedures/create_synonym_db.sql @@ -98,7 +98,9 @@ BEGIN DECLARE v_table VARCHAR(64); DECLARE v_views_created INT DEFAULT 0; DECLARE v_table_exists ENUM('', 'BASE TABLE', 'VIEW', 'TEMPORARY') DEFAULT ''; - DECLARE v_temp_table TEXT; + + DECLARE db_doesnt_exist CONDITION FOR SQLSTATE '42000'; + DECLARE db_name_exists CONDITION FOR SQLSTATE 'HY000'; DECLARE c_table_names CURSOR FOR SELECT TABLE_NAME @@ -142,37 +144,25 @@ BEGIN IF v_done THEN LEAVE c_table_names; END IF; - - -- Check does temporary table shadows the base table. If it is so, terminate. + -- Check the table type, don't support temporary since cannot create the view CALL sys.table_exists(in_db_name, v_table, v_table_exists); - IF (v_table_exists = 'TEMPORARY') THEN - SET v_temp_table = - CONCAT( - 'Table', - sys.quote_identifier(in_db_name), - '.', - sys.quote_identifier(v_table), - 'shadows base table. View cannot be created! Terminating!'); - SIGNAL SQLSTATE 'HY000' - SET MESSAGE_TEXT = v_temp_table; - LEAVE c_table_names; + IF (v_table_exists <> 'TEMPORARY') THEN + SET @create_view_stmt = CONCAT( + 'CREATE SQL SECURITY INVOKER VIEW ', + sys.quote_identifier(in_synonym), + '.', + sys.quote_identifier(v_table), + ' AS SELECT * FROM ', + sys.quote_identifier(in_db_name), + '.', + sys.quote_identifier(v_table) + ); + PREPARE create_view_stmt FROM @create_view_stmt; + EXECUTE create_view_stmt; + DEALLOCATE PREPARE create_view_stmt; + + SET v_views_created = v_views_created + 1; END IF; - - SET @create_view_stmt = CONCAT( - 'CREATE SQL SECURITY INVOKER VIEW ', - sys.quote_identifier(in_synonym), - '.', - sys.quote_identifier(v_table), - ' AS SELECT * FROM ', - sys.quote_identifier(in_db_name), - '.', - sys.quote_identifier(v_table) - ); - PREPARE create_view_stmt FROM @create_view_stmt; - EXECUTE create_view_stmt; - DEALLOCATE PREPARE create_view_stmt; - - SET v_views_created = v_views_created + 1; END LOOP; CLOSE c_table_names;