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: <monty@mariadb.org>,
             <vicentiu@mariadb.org>
This commit is contained in:
Anel Husakovic 2022-07-16 13:33:15 +02:00 committed by Sergei Golubchik
parent 91bfc76fe1
commit 1fb4828b28
3 changed files with 79 additions and 32 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;