mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
377d710296
'CREATE TABLE IF NOT EXISTS ... SELECT' statement were causing 'CREATE TEMPORARY TABLE ...' to be written to the binary log in row-based mode (a.k.a. RBR), when there was a temporary table with the same name. Because the 'CREATE TABLE ... SELECT' statement was executed as 'INSERT ... SELECT' into the temporary table. Since in RBR mode no other statements related to temporary tables are written into binary log, this sometimes broke replication. This patch changes behavior of 'CREATE TABLE [IF NOT EXISTS] ... SELECT ...'. it ignores existence of temporary table with the same name as table being created and is interpreted as attempt to create/insert into base table. This makes behavior of 'CREATE TABLE [IF NOT EXISTS] ... SELECT' consistent with how ordinary 'CREATE TABLE' and 'CREATE TABLE ... LIKE' behave.
2049 lines
49 KiB
Text
2049 lines
49 KiB
Text
#
|
|
# Testing the behavior of 'PREPARE', 'DDL', 'EXECUTE' scenarios
|
|
#
|
|
# Background:
|
|
# In a statement like "select * from t1", t1 can be:
|
|
# - nothing (the table does not exist)
|
|
# - a real table
|
|
# - a temporary table
|
|
# - a view
|
|
#
|
|
# Changing the nature of "t1" between a PREPARE and an EXECUTE
|
|
# can invalidate the internal state of a prepared statement, so that,
|
|
# during the execute, the server should:
|
|
# - detect state changes and fail to execute a statement,
|
|
# instead of crashing the server or returning wrong results
|
|
# - "RE-PREPARE" the statement to restore a valid internal state.
|
|
#
|
|
# Also, changing the physical structure of "t1", by:
|
|
# - changing the definition of t1 itself (DDL on tables, views)
|
|
# - changing TRIGGERs associated with a table
|
|
# - changing PROCEDURE, FUNCTION referenced by a TRIGGER body,
|
|
# - changing PROCEDURE, FUNCTION referenced by a VIEW body,
|
|
# impacts the internal structure of a prepared statement, and should
|
|
# cause the same verifications at execute time to be performed.
|
|
#
|
|
# This test provided in this file cover the different state transitions
|
|
# between a PREPARE and an EXECUTE, and are organized as follows:
|
|
# - Part 1: NOTHING -> TABLE
|
|
# - Part 2: NOTHING -> TEMPORARY TABLE
|
|
# - Part 3: NOTHING -> VIEW
|
|
# - Part 4: TABLE -> NOTHING
|
|
# - Part 5: TABLE -> TABLE (DDL)
|
|
# - Part 6: TABLE -> TABLE (TRIGGER)
|
|
# - Part 7: TABLE -> TABLE (TRIGGER dependencies)
|
|
# - Part 8: TABLE -> TEMPORARY TABLE
|
|
# - Part 9: TABLE -> VIEW
|
|
# - Part 10: TEMPORARY TABLE -> NOTHING
|
|
# - Part 11: TEMPORARY TABLE -> TABLE
|
|
# - Part 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL)
|
|
# - Part 13: TEMPORARY TABLE -> VIEW
|
|
# - Part 14: VIEW -> NOTHING
|
|
# - Part 15: VIEW -> TABLE
|
|
# - Part 16: VIEW -> TEMPORARY TABLE
|
|
# - Part 17: VIEW -> VIEW (DDL)
|
|
# - Part 18: VIEW -> VIEW (VIEW dependencies)
|
|
# - Part 19: Special tables (INFORMATION_SCHEMA)
|
|
# - Part 20: Special tables (log tables)
|
|
# - Part 21: Special tables (system tables)
|
|
# - Part 22: Special tables (views temp tables)
|
|
# - Part 23: Special statements
|
|
# - Part 24: Testing the strength of TABLE_SHARE version
|
|
--disable_warnings
|
|
drop temporary table if exists t1, t2, t3;
|
|
drop table if exists t1, t2, t3;
|
|
drop procedure if exists p_verify_reprepare_count;
|
|
drop procedure if exists p1;
|
|
drop function if exists f1;
|
|
drop view if exists v1, v2;
|
|
--enable_warnings
|
|
|
|
delimiter |;
|
|
create procedure p_verify_reprepare_count(expected int)
|
|
begin
|
|
declare old_reprepare_count int default @reprepare_count;
|
|
|
|
select variable_value from
|
|
information_schema.session_status where
|
|
variable_name='com_stmt_reprepare'
|
|
into @reprepare_count;
|
|
|
|
if old_reprepare_count + expected <> @reprepare_count then
|
|
select concat("Expected: ", expected,
|
|
", actual: ", @reprepare_count - old_reprepare_count)
|
|
as "ERROR";
|
|
else
|
|
select '' as "SUCCESS";
|
|
end if;
|
|
end|
|
|
delimiter ;|
|
|
set @reprepare_count= 0;
|
|
flush status;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 1: NOTHING -> TABLE transitions
|
|
--echo =====================================================================
|
|
|
|
# can not be tested since prepare failed
|
|
--error ER_NO_SUCH_TABLE
|
|
prepare stmt from "select * from t1";
|
|
|
|
--echo =====================================================================
|
|
--echo Part 2: NOTHING -> TEMPORARY TABLE transitions
|
|
--echo =====================================================================
|
|
|
|
# can not be tested
|
|
|
|
--echo =====================================================================
|
|
--echo Part 3: NOTHING -> VIEW transitions
|
|
--echo =====================================================================
|
|
|
|
# can not be tested
|
|
|
|
--echo =====================================================================
|
|
--echo Part 4: TABLE -> NOTHING transitions
|
|
--echo =====================================================================
|
|
|
|
--echo # Test 4-a: select ... from <table>
|
|
create table t1 (a int);
|
|
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t1;
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
deallocate prepare stmt;
|
|
|
|
--echo # Test 4-b: TABLE -> NOTHING by renaming the table
|
|
create table t1 (a int);
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
rename table t1 to t2;
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
deallocate prepare stmt;
|
|
drop table t2;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 5: TABLE -> TABLE (DDL) transitions
|
|
--echo =====================================================================
|
|
|
|
create table t1 (a int);
|
|
|
|
prepare stmt from "select a from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
alter table t1 add column (b int);
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
|
|
--echo =====================================================================
|
|
--echo Part 6: TABLE -> TABLE (TRIGGER) transitions
|
|
--echo =====================================================================
|
|
|
|
--echo # Test 6-a: adding a relevant trigger
|
|
|
|
create table t1 (a int);
|
|
|
|
prepare stmt from "insert into t1 (a) value (?)";
|
|
set @val=1;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
# Relevant trigger: execute should reprepare
|
|
create trigger t1_bi before insert on t1 for each row
|
|
set @message= new.a;
|
|
|
|
set @val=2;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(1);
|
|
select @message;
|
|
set @val=3;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(0);
|
|
select @message;
|
|
|
|
prepare stmt from "insert into t1 (a) value (?)";
|
|
set @val=4;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(0);
|
|
select @message;
|
|
|
|
--echo # Test 6-b: adding an irrelevant trigger
|
|
|
|
# Unrelated trigger: reprepare may or may not happen, implementation dependent
|
|
create trigger t1_bd before delete on t1 for each row
|
|
set @message= old.a;
|
|
|
|
set @val=5;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(1);
|
|
select @message;
|
|
set @val=6;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(0);
|
|
select @message;
|
|
|
|
prepare stmt from "insert into t1 (a) value (?)";
|
|
set @val=7;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(0);
|
|
select @message;
|
|
|
|
--echo # Test 6-c: changing a relevant trigger
|
|
|
|
# Relevant trigger: execute should reprepare
|
|
drop trigger t1_bi;
|
|
create trigger t1_bi before insert on t1 for each row
|
|
set @message= concat("new trigger: ", new.a);
|
|
|
|
set @val=8;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(1);
|
|
select @message;
|
|
set @val=9;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(0);
|
|
select @message;
|
|
|
|
prepare stmt from "insert into t1 (a) value (?)";
|
|
set @val=10;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(0);
|
|
select @message;
|
|
|
|
--echo # Test 6-d: changing an irrelevant trigger
|
|
|
|
# Unrelated trigger: reprepare may or may not happen, implementation dependent
|
|
drop trigger t1_bd;
|
|
|
|
set @val=11;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(1);
|
|
select @message;
|
|
|
|
--echo Test 6-e: removing a relevant trigger
|
|
|
|
drop trigger t1_bi;
|
|
|
|
set @val=12;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(1);
|
|
select @message;
|
|
set @val=13;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(0);
|
|
select @message;
|
|
|
|
prepare stmt from "insert into t1 (a) value (?)";
|
|
set @val=14;
|
|
execute stmt using @val;
|
|
call p_verify_reprepare_count(0);
|
|
select @message;
|
|
|
|
select * from t1 order by a;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 7: TABLE -> TABLE (TRIGGER dependencies) transitions
|
|
--echo =====================================================================
|
|
|
|
--echo # Test 7-a: dependent PROCEDURE has changed
|
|
--echo #
|
|
--echo # Note, this scenario is not supported, subject of Bug#12093
|
|
--echo #
|
|
|
|
create table t1 (a int);
|
|
create trigger t1_ai after insert on t1 for each row
|
|
call p1(new.a);
|
|
create procedure p1(a int) begin end;
|
|
prepare stmt from "insert into t1 (a) values (?)";
|
|
set @var= 1;
|
|
execute stmt using @var;
|
|
drop procedure p1;
|
|
create procedure p1 (a int) begin end;
|
|
set @var= 2;
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
execute stmt using @var;
|
|
--echo # Cleanup
|
|
drop procedure p1;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # Test 7-b: dependent FUNCTION has changed
|
|
--echo #
|
|
--echo # Note, this scenario is supported, subject of Bug#12093
|
|
--echo #
|
|
drop trigger t1_ai;
|
|
create trigger t1_ai after insert on t1 for each row
|
|
select f1(new.a+1) into @var;
|
|
create function f1 (a int) returns int return a;
|
|
prepare stmt from "insert into t1(a) values (?)";
|
|
set @var=3;
|
|
execute stmt using @var;
|
|
select @var;
|
|
drop function f1;
|
|
create function f1 (a int) returns int return 0;
|
|
execute stmt using @var;
|
|
call p_verify_reprepare_count(1);
|
|
drop function f1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo # Test 7-c: dependent VIEW has changed
|
|
--echo #
|
|
--echo # Note, this scenario is not functioning correctly, see
|
|
--echo # Bug#33255 Trigger using views and view ddl : corrupted triggers
|
|
--echo # and Bug #33000 Triggers do not detect changes in meta-data.
|
|
--echo #
|
|
drop trigger t1_ai;
|
|
create table t2 (a int unique);
|
|
create table t3 (a int unique);
|
|
create view v1 as select a from t2;
|
|
create trigger t1_ai after insert on t1 for each row
|
|
insert into v1 (a) values (new.a);
|
|
|
|
--echo # Demonstrate that the same bug is present
|
|
--echo # without prepared statements
|
|
insert into t1 (a) values (5);
|
|
select * from t2;
|
|
select * from t3;
|
|
drop view v1;
|
|
create view v1 as select a from t3;
|
|
--error ER_NO_SUCH_TABLE
|
|
insert into t1 (a) values (6);
|
|
flush table t1;
|
|
insert into t1 (a) values (6);
|
|
select * from t2;
|
|
select * from t3;
|
|
|
|
prepare stmt from "insert into t1 (a) values (?)";
|
|
set @var=7;
|
|
execute stmt using @var;
|
|
call p_verify_reprepare_count(0);
|
|
select * from t3;
|
|
select * from t2;
|
|
drop view v1;
|
|
create view v1 as select a from t2;
|
|
set @var=8;
|
|
--echo # XXX: bug, the SQL statement in the trigger is still
|
|
--echo # pointing at table 't3', since the view was expanded
|
|
--echo # at first statement execution.
|
|
--echo # Repreparation of the main statement doesn't cause repreparation
|
|
--echo # of trigger statements.
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt using @var;
|
|
call p_verify_reprepare_count(1);
|
|
--echo #
|
|
--echo # Sic: the insert went into t3, even though the view now
|
|
--echo # points at t2. This is because neither the merged view
|
|
--echo # nor its prelocking list are affected by view DDL
|
|
--echo # The binary log is of course wrong, since it is not
|
|
--echo # using prepared statements
|
|
--echo #
|
|
select * from t2;
|
|
select * from t3;
|
|
flush table t1;
|
|
set @var=9;
|
|
execute stmt using @var;
|
|
call p_verify_reprepare_count(1);
|
|
select * from t2;
|
|
select * from t3;
|
|
drop view v1;
|
|
drop table t1,t2,t3;
|
|
|
|
--echo # Test 7-d: dependent TABLE has changed
|
|
create table t1 (a int);
|
|
create trigger t1_ai after insert on t1 for each row
|
|
insert into t2 (a) values (new.a);
|
|
create table t2 (a int);
|
|
|
|
prepare stmt from "insert into t1 (a) values (?)";
|
|
set @var=1;
|
|
execute stmt using @var;
|
|
alter table t2 add column comment varchar(255);
|
|
set @var=2;
|
|
--echo # Since the dependent table is tracked in the prelocked
|
|
--echo # list of the prepared statement, invalidation happens
|
|
--echo # and the statement is re-prepared. This is an unnecessary
|
|
--echo # side effect, since the statement that *is* dependent
|
|
--echo # on t2 definition is inside the trigger, and it is currently
|
|
--echo # not reprepared (see the previous test case).
|
|
execute stmt using @var;
|
|
call p_verify_reprepare_count(1);
|
|
select * from t1;
|
|
select * from t2;
|
|
drop table t1,t2;
|
|
|
|
--echo # Test 7-e: dependent TABLE TRIGGER has changed
|
|
create table t1 (a int);
|
|
create trigger t1_ai after insert on t1 for each row
|
|
insert into t2 (a) values (new.a);
|
|
create table t2 (a int unique);
|
|
create trigger t2_ai after insert on t2 for each row
|
|
insert into t3 (a) values (new.a);
|
|
create table t3 (a int unique);
|
|
create table t4 (a int unique);
|
|
|
|
insert into t1 (a) values (1);
|
|
select * from t1 join t2 on (t1.a=t2.a) join t3 on (t2.a=t3.a);
|
|
drop trigger t2_ai;
|
|
create trigger t2_ai after insert on t2 for each row
|
|
insert into t4 (a) values (new.a);
|
|
insert into t1 (a) values (2);
|
|
select * from t1 join t2 on (t1.a=t2.a) join t4 on (t2.a=t4.a);
|
|
|
|
prepare stmt from "insert into t1 (a) values (?)";
|
|
set @var=3;
|
|
execute stmt using @var;
|
|
select * from t1 join t2 on (t1.a=t2.a) join t4 on (t2.a=t4.a);
|
|
drop trigger t2_ai;
|
|
create trigger t2_ai after insert on t2 for each row
|
|
insert into t3 (a) values (new.a);
|
|
set @var=4;
|
|
execute stmt using @var;
|
|
call p_verify_reprepare_count(1);
|
|
select * from t1 join t2 on (t1.a=t2.a) join t3 on (t2.a=t3.a);
|
|
select * from t1 join t2 on (t1.a=t2.a) join t4 on (t2.a=t4.a);
|
|
|
|
drop table t1, t2, t3, t4;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 8: TABLE -> TEMPORARY TABLE transitions
|
|
--echo =====================================================================
|
|
|
|
--echo # Test 8-a: base table used recreated as temporary table
|
|
create table t1 (a int);
|
|
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
|
|
drop table t1;
|
|
create temporary table t1 (a int);
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo # Test 8-b: temporary table has precedence over base table with same name
|
|
create table t1 (a int);
|
|
prepare stmt from 'select count(*) from t1';
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
create temporary table t1 AS SELECT 1;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
deallocate prepare stmt;
|
|
drop temporary table t1;
|
|
drop table t1;
|
|
|
|
|
|
--echo =====================================================================
|
|
--echo Part 9: TABLE -> VIEW transitions
|
|
--echo =====================================================================
|
|
|
|
create table t1 (a int);
|
|
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t1;
|
|
create table t2 (a int);
|
|
create view t1 as select * from t2;
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
drop view t1;
|
|
drop table t2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 10: TEMPORARY TABLE -> NOTHING transitions
|
|
--echo =====================================================================
|
|
|
|
create temporary table t1 (a int);
|
|
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop temporary table t1;
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 11: TEMPORARY TABLE -> TABLE transitions
|
|
--echo =====================================================================
|
|
|
|
--echo # Test 11-a: temporary table replaced by base table
|
|
create table t1 (a int);
|
|
insert into t1 (a) value (1);
|
|
create temporary table t1 (a int);
|
|
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop temporary table t1;
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
select * from t1;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
|
|
--echo # Test 11-b: temporary table has precedence over base table with same name
|
|
--echo # temporary table disappears
|
|
create table t1 (a int);
|
|
create temporary table t1 as select 1 as a;
|
|
prepare stmt from "select count(*) from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop temporary table t1;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
deallocate prepare stmt;
|
|
drop table t1;
|
|
|
|
|
|
--echo =====================================================================
|
|
--echo Part 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions
|
|
--echo =====================================================================
|
|
|
|
create temporary table t1 (a int);
|
|
|
|
prepare stmt from "select a from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop temporary table t1;
|
|
create temporary table t1 (a int, b int);
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
select * from t1;
|
|
drop temporary table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 13: TEMPORARY TABLE -> VIEW transitions
|
|
--echo =====================================================================
|
|
|
|
create temporary table t1 (a int);
|
|
create table t2 (a int);
|
|
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop temporary table t1;
|
|
create view t1 as select * from t2;
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
drop view t1;
|
|
drop table t2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 14: VIEW -> NOTHING transitions
|
|
--echo =====================================================================
|
|
|
|
create table t2 (a int);
|
|
create view t1 as select * from t2;
|
|
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
drop view t1;
|
|
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 15: VIEW -> TABLE transitions
|
|
--echo =====================================================================
|
|
|
|
create table t2 (a int);
|
|
create view t1 as select * from t2;
|
|
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop view t1;
|
|
create table t1 (a int);
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
drop table t2;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 16: VIEW -> TEMPORARY TABLE transitions
|
|
--echo =====================================================================
|
|
|
|
create table t2 (a int);
|
|
insert into t2 (a) values (1);
|
|
create view t1 as select * from t2;
|
|
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
create temporary table t1 (a int);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
drop view t1;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t2;
|
|
drop temporary table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 17: VIEW -> VIEW (DDL) transitions
|
|
--echo =====================================================================
|
|
|
|
create table t2 (a int);
|
|
insert into t2 values (10), (20), (30);
|
|
|
|
create view t1 as select a, 2*a as b, 3*a as c from t2;
|
|
select * from t1;
|
|
|
|
prepare stmt from "select * from t1";
|
|
execute stmt;
|
|
|
|
drop view t1;
|
|
create view t1 as select a, 2*a as b, 5*a as c from t2;
|
|
select * from t1;
|
|
|
|
--echo # Currently a different result from conventional statements.
|
|
--echo # A view is inlined once at prepare, later on view DDL
|
|
--echo # does not affect prepared statement and it is not re-prepared.
|
|
--echo # This is reported in Bug#36002 Prepared statements: if a view
|
|
--echo # used in a statement is replaced, bad data
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
flush table t2;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
drop table t2;
|
|
drop view t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 18: VIEW -> VIEW (VIEW dependencies) transitions
|
|
--echo =====================================================================
|
|
|
|
--echo # Part 18a: dependent function has changed
|
|
create table t1 (a int);
|
|
insert into t1 (a) values (1), (2), (3);
|
|
create function f1() returns int return (select max(a) from t1);
|
|
create view v1 as select f1();
|
|
prepare stmt from "select * from v1";
|
|
execute stmt;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop function f1;
|
|
create function f1() returns int return 2;
|
|
--echo # XXX: Used to be another manifestation of Bug#12093.
|
|
--echo # We only used to get a different error
|
|
--echo # message because the non-existing procedure error is masked
|
|
--echo # by the view.
|
|
execute stmt;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
--echo # Part 18b: dependent procedure has changed (referred to via a function)
|
|
|
|
create table t2 (a int);
|
|
insert into t2 (a) values (4), (5), (6);
|
|
|
|
drop function f1;
|
|
delimiter |;
|
|
create function f1() returns int
|
|
begin
|
|
declare x int;
|
|
call p1(x);
|
|
return x;
|
|
end|
|
|
delimiter ;|
|
|
create procedure p1(out x int) select max(a) from t1 into x;
|
|
|
|
prepare stmt from "select * from v1";
|
|
execute stmt;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop procedure p1;
|
|
create procedure p1(out x int) select max(a) from t2 into x;
|
|
--echo # XXX: used to be a bug. The prelocked list was not invalidated
|
|
--echo # and we kept opening table t1, whereas the procedure
|
|
--echo # is now referring to table t2
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
flush table t1;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
execute stmt;
|
|
|
|
--echo # Test 18-c: dependent VIEW has changed
|
|
|
|
drop view v1;
|
|
create view v2 as select a from t1;
|
|
create view v1 as select * from v2;
|
|
prepare stmt from "select * from v1";
|
|
execute stmt;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop view v2;
|
|
create view v2 as select a from t2;
|
|
execute stmt;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
flush table t1;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
--echo # Test 18-d: dependent TABLE has changed
|
|
drop view v2;
|
|
create table v2 as select * from t1;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop table v2;
|
|
create table v2 (a int unique) as select * from t2;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # Test 18-e: dependent TABLE trigger has changed
|
|
|
|
prepare stmt from "insert into v1 (a) values (?)";
|
|
set @var= 7;
|
|
execute stmt using @var;
|
|
call p_verify_reprepare_count(0);
|
|
create trigger v2_bi before insert on v2 for each row set @message="v2_bi";
|
|
set @var=8;
|
|
execute stmt using @var;
|
|
call p_verify_reprepare_count(1);
|
|
select @message;
|
|
drop trigger v2_bi;
|
|
set @message=null;
|
|
set @var=9;
|
|
execute stmt using @var;
|
|
call p_verify_reprepare_count(1);
|
|
select @message;
|
|
create trigger v2_bi after insert on v2 for each row set @message="v2_ai";
|
|
set @var= 10;
|
|
execute stmt using @var;
|
|
call p_verify_reprepare_count(1);
|
|
select @message;
|
|
select * from v1;
|
|
|
|
--echo # Cleanup
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2, v1, v2;
|
|
drop view if exists v1, v2;
|
|
drop function f1;
|
|
drop procedure p1;
|
|
--enable_warnings
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 19: Special tables (INFORMATION_SCHEMA)
|
|
--echo =====================================================================
|
|
|
|
# Using a temporary table internally should not confuse the prepared
|
|
# statement code, and should not raise ER_PS_INVALIDATED errors
|
|
prepare stmt from
|
|
"select ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
|
|
from INFORMATION_SCHEMA.ROUTINES where
|
|
routine_name='p1'";
|
|
|
|
create procedure p1() select "hi there";
|
|
|
|
execute stmt;
|
|
execute stmt;
|
|
|
|
drop procedure p1;
|
|
create procedure p1() select "hi there, again";
|
|
|
|
execute stmt;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop procedure p1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 20: Special tables (log tables)
|
|
--echo =====================================================================
|
|
|
|
prepare stmt from
|
|
"select * from mysql.general_log where argument='IMPOSSIBLE QUERY STRING'";
|
|
|
|
--disable_result_log
|
|
execute stmt;
|
|
execute stmt;
|
|
execute stmt;
|
|
execute stmt;
|
|
--enable_result_log
|
|
call p_verify_reprepare_count(0);
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 21: Special tables (system tables)
|
|
--echo =====================================================================
|
|
|
|
prepare stmt from
|
|
"select type, db, name from mysql.proc where name='p1'";
|
|
|
|
create procedure p1() select "hi there";
|
|
|
|
execute stmt;
|
|
execute stmt;
|
|
|
|
drop procedure p1;
|
|
create procedure p1() select "hi there, again";
|
|
|
|
execute stmt;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop procedure p1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 22: Special tables (views temp tables)
|
|
--echo =====================================================================
|
|
|
|
create table t1 (a int);
|
|
|
|
create algorithm=temptable view v1 as select a*a as a2 from t1;
|
|
|
|
--echo # Using a temporary table internally should not confuse the prepared
|
|
--echo # statement code, and should not raise ER_PS_INVALIDATED errors
|
|
show create view v1;
|
|
|
|
prepare stmt from "select * from v1";
|
|
|
|
insert into t1 values (1), (2), (3);
|
|
execute stmt;
|
|
execute stmt;
|
|
|
|
insert into t1 values (4), (5), (6);
|
|
execute stmt;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t1;
|
|
drop view v1;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 23: Special statements
|
|
--echo =====================================================================
|
|
|
|
--echo # SQLCOM_ALTER_TABLE:
|
|
|
|
|
|
create table t1 (a int);
|
|
|
|
prepare stmt from "alter table t1 add column b int";
|
|
execute stmt;
|
|
|
|
drop table t1;
|
|
create table t1 (a1 int, a2 int);
|
|
|
|
--echo # t1 has changed, and it's does not lead to reprepare
|
|
execute stmt;
|
|
|
|
alter table t1 drop column b;
|
|
execute stmt;
|
|
|
|
alter table t1 drop column b;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t1;
|
|
|
|
--echo # SQLCOM_REPAIR:
|
|
|
|
create table t1 (a int);
|
|
|
|
insert into t1 values (1), (2), (3);
|
|
|
|
prepare stmt from "repair table t1";
|
|
|
|
execute stmt;
|
|
execute stmt;
|
|
|
|
drop table t1;
|
|
create table t1 (a1 int, a2 int);
|
|
insert into t1 values (1, 10), (2, 20), (3, 30);
|
|
|
|
--echo # t1 has changed, and it's does not lead to reprepare
|
|
execute stmt;
|
|
|
|
alter table t1 add column b varchar(50) default NULL;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
alter table t1 drop column b;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # SQLCOM_ANALYZE:
|
|
|
|
prepare stmt from "analyze table t1";
|
|
execute stmt;
|
|
|
|
drop table t1;
|
|
create table t1 (a1 int, a2 int);
|
|
insert into t1 values (1, 10), (2, 20), (3, 30);
|
|
--echo # t1 has changed, and it's not a problem
|
|
execute stmt;
|
|
|
|
alter table t1 add column b varchar(50) default NULL;
|
|
execute stmt;
|
|
|
|
alter table t1 drop column b;
|
|
execute stmt;
|
|
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # SQLCOM_OPTIMIZE:
|
|
|
|
prepare stmt from "optimize table t1";
|
|
execute stmt;
|
|
|
|
drop table t1;
|
|
create table t1 (a1 int, a2 int);
|
|
insert into t1 values (1, 10), (2, 20), (3, 30);
|
|
|
|
--echo # t1 has changed, and it's not a problem
|
|
execute stmt;
|
|
|
|
alter table t1 add column b varchar(50) default NULL;
|
|
execute stmt;
|
|
|
|
alter table t1 drop column b;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t1;
|
|
|
|
--echo # SQLCOM_SHOW_CREATE_PROC:
|
|
|
|
prepare stmt from "show create procedure p1";
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
execute stmt;
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
execute stmt;
|
|
|
|
create procedure p1() begin end;
|
|
|
|
--disable_result_log
|
|
execute stmt;
|
|
execute stmt;
|
|
--enable_result_log
|
|
|
|
drop procedure p1;
|
|
create procedure p1(x int, y int) begin end;
|
|
|
|
--disable_result_log
|
|
execute stmt;
|
|
execute stmt;
|
|
--enable_result_log
|
|
|
|
drop procedure p1;
|
|
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
execute stmt;
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # SQLCOM_SHOW_CREATE_FUNC:
|
|
|
|
prepare stmt from "show create function f1";
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
execute stmt;
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
execute stmt;
|
|
|
|
create function f1() returns int return 0;
|
|
|
|
--disable_result_log
|
|
execute stmt;
|
|
execute stmt;
|
|
--enable_result_log
|
|
|
|
drop function f1;
|
|
create function f1(x int, y int) returns int return x+y;
|
|
|
|
--disable_result_log
|
|
execute stmt;
|
|
execute stmt;
|
|
--enable_result_log
|
|
|
|
drop function f1;
|
|
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
execute stmt;
|
|
--error ER_SP_DOES_NOT_EXIST
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # SQLCOM_SHOW_CREATE_TRIGGER:
|
|
|
|
create table t1 (a int);
|
|
|
|
prepare stmt from "show create trigger t1_bi";
|
|
--error ER_TRG_DOES_NOT_EXIST
|
|
execute stmt;
|
|
--error ER_TRG_DOES_NOT_EXIST
|
|
execute stmt;
|
|
|
|
create trigger t1_bi before insert on t1 for each row set @message= "t1_bi";
|
|
|
|
--disable_result_log
|
|
execute stmt;
|
|
execute stmt;
|
|
--enable_result_log
|
|
|
|
drop trigger t1_bi;
|
|
|
|
create trigger t1_bi before insert on t1 for each row set @message= "t1_bi (2)";
|
|
|
|
--disable_result_log
|
|
execute stmt;
|
|
execute stmt;
|
|
--enable_result_log
|
|
|
|
drop trigger t1_bi;
|
|
|
|
--error ER_TRG_DOES_NOT_EXIST
|
|
execute stmt;
|
|
--error ER_TRG_DOES_NOT_EXIST
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Part 24: Testing the strength of TABLE_SHARE version
|
|
--echo =====================================================================
|
|
|
|
--echo # Test 24-a: number of columns
|
|
|
|
create table t1 (a int);
|
|
|
|
prepare stmt from "select a from t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
alter table t1 add column b varchar(50) default NULL;
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # Test 24-b: column name
|
|
|
|
alter table t1 change b c int;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # Test 24-c: column type
|
|
|
|
alter table t1 change a a varchar(10);
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # Test 24-d: column type length
|
|
|
|
alter table t1 change a a varchar(20);
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # Test 24-e: column NULL property
|
|
|
|
alter table t1 change a a varchar(20) NOT NULL;
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # Test 24-f: column DEFAULT
|
|
|
|
alter table t1 change c c int DEFAULT 20;
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # Test 24-g: number of keys
|
|
create unique index t1_a_idx on t1 (a);
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # Test 24-h: changing index uniqueness
|
|
|
|
drop index t1_a_idx on t1;
|
|
create index t1_a_idx on t1 (a);
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
--echo # Cleanup
|
|
drop table t1;
|
|
|
|
deallocate prepare stmt;
|
|
|
|
--echo =====================================================================
|
|
--echo Testing reported bugs
|
|
--echo =====================================================================
|
|
|
|
--echo #
|
|
--echo # Bug#27420 A combination of PS and view operations cause
|
|
--echo # error + assertion on shutdown
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t_27420_100;
|
|
drop table if exists t_27420_101;
|
|
drop view if exists v_27420;
|
|
--enable_warnings
|
|
|
|
create table t_27420_100(a int);
|
|
insert into t_27420_100 values (1), (2);
|
|
|
|
create table t_27420_101(a int);
|
|
insert into t_27420_101 values (1), (2);
|
|
|
|
create view v_27420 as select t_27420_100.a X, t_27420_101.a Y
|
|
from t_27420_100, t_27420_101
|
|
where t_27420_100.a=t_27420_101.a;
|
|
|
|
prepare stmt from "select * from v_27420";
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop view v_27420;
|
|
create table v_27420(X int, Y int);
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
drop table v_27420;
|
|
# passes in 5.0, fails in 5.1, should pass
|
|
create table v_27420 (a int, b int, filler char(200));
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
drop table t_27420_100;
|
|
drop table t_27420_101;
|
|
drop table v_27420;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # Bug#27430 Crash in subquery code when in PS and table DDL changed
|
|
--echo # after PREPARE
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t_27430_1;
|
|
drop table if exists t_27430_2;
|
|
--enable_warnings
|
|
|
|
create table t_27430_1 (a int not null, oref int not null, key(a));
|
|
insert into t_27430_1 values
|
|
(1, 1),
|
|
(1, 1234),
|
|
(2, 3),
|
|
(2, 1234),
|
|
(3, 1234);
|
|
|
|
create table t_27430_2 (a int not null, oref int not null);
|
|
insert into t_27430_2 values
|
|
(1, 1),
|
|
(2, 2),
|
|
(1234, 3),
|
|
(1234, 4);
|
|
|
|
prepare stmt from
|
|
"select oref, a, a in (select a from t_27430_1 where oref=t_27430_2.oref) Z from t_27430_2";
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t_27430_1, t_27430_2;
|
|
|
|
create table t_27430_1 (a int, oref int, key(a));
|
|
insert into t_27430_1 values
|
|
(1, 1),
|
|
(1, NULL),
|
|
(2, 3),
|
|
(2, NULL),
|
|
(3, NULL);
|
|
|
|
create table t_27430_2 (a int, oref int);
|
|
insert into t_27430_2 values
|
|
(1, 1),
|
|
(2,2),
|
|
(NULL, 3),
|
|
(NULL, 4);
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
drop table t_27430_1;
|
|
drop table t_27430_2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # Bug#27690 Re-execution of prepared statement after table
|
|
--echo # was replaced with a view crashes
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t_27690_1;
|
|
drop view if exists v_27690_1;
|
|
drop table if exists v_27690_2;
|
|
--enable_warnings
|
|
|
|
create table t_27690_1 (a int, b int);
|
|
insert into t_27690_1 values (1,1),(2,2);
|
|
|
|
create table v_27690_1 as select * from t_27690_1;
|
|
create table v_27690_2 as select * from t_27690_1;
|
|
|
|
prepare stmt from "select * from v_27690_1, v_27690_2";
|
|
|
|
execute stmt;
|
|
execute stmt;
|
|
|
|
drop table v_27690_1;
|
|
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
create view v_27690_1 as select A.a, A.b from t_27690_1 A, t_27690_1 B;
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
|
|
drop table t_27690_1;
|
|
drop view v_27690_1;
|
|
drop table v_27690_2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #=====================================================================
|
|
--echo #
|
|
--echo # Bug#21294 Executing a prepared statement that executes
|
|
--echo # a stored function which was recreat
|
|
--echo #
|
|
|
|
create function f1() returns int return 10;
|
|
|
|
prepare stmt from "select f1()";
|
|
execute stmt;
|
|
|
|
drop function f1;
|
|
create function f1() returns int return 10;
|
|
|
|
# might pass or fail, implementation dependent
|
|
execute stmt;
|
|
|
|
drop function f1;
|
|
create function f1() returns int return 20;
|
|
|
|
execute stmt;
|
|
call p_verify_reprepare_count(2);
|
|
|
|
drop function f1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # Bug#12093 SP not found on second PS execution if another thread drops
|
|
--echo # other SP in between
|
|
--echo #
|
|
--disable_warnings
|
|
drop table if exists t_12093;
|
|
drop function if exists f_12093;
|
|
drop function if exists f_12093_unrelated;
|
|
drop procedure if exists p_12093;
|
|
drop view if exists v_12093_unrelated;
|
|
--enable_warnings
|
|
|
|
create table t_12093 (a int);
|
|
create function f_12093() returns int return (select count(*) from t_12093);
|
|
create procedure p_12093(a int) select * from t_12093;
|
|
|
|
create function f_12093_unrelated() returns int return 2;
|
|
create procedure p_12093_unrelated() begin end;
|
|
create view v_12093_unrelated as select * from t_12093;
|
|
|
|
connect (con1,localhost,root,,);
|
|
connection default;
|
|
|
|
let $my_drop = drop function f_12093_unrelated;
|
|
--source include/ps_ddl_1.inc
|
|
#
|
|
let $my_drop = drop procedure p_12093_unrelated;
|
|
--source include/ps_ddl_1.inc
|
|
#
|
|
# A reprepare of stmt_sf and stmt_sp is necessary because there is no
|
|
# information about views within the table definition cache.
|
|
let $my_drop = drop view v_12093_unrelated;
|
|
--source include/ps_ddl_1.inc
|
|
|
|
call p_verify_reprepare_count(6);
|
|
|
|
disconnect con1;
|
|
drop table t_12093;
|
|
drop function f_12093;
|
|
drop procedure p_12093;
|
|
deallocate prepare stmt_sf;
|
|
deallocate prepare stmt_sp;
|
|
|
|
|
|
--echo =====================================================================
|
|
--echo Ensure that metadata validation is performed for every type of
|
|
--echo SQL statement where it is needed.
|
|
--echo =====================================================================
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SELECT
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "select 1 as res from dual where (1) in (select * from t1)";
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
call p_verify_reprepare_count(1);
|
|
|
|
--echo #
|
|
--echo # SQLCOM_CREATE_TABLE
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
drop table if exists t2;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from 'create table t2 as select * from t1';
|
|
execute stmt;
|
|
drop table t2;
|
|
execute stmt;
|
|
drop table t2;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
# Base table with name of table to be created exists
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop table t2;
|
|
# Temporary table with name of table to be created exists
|
|
create temporary table t2 (a int);
|
|
# Temporary table and base table are not in the same name space.
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
drop temporary table t2;
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop table t2;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
drop table t2;
|
|
# View with name of table to be created exists
|
|
# Attention:
|
|
# We cannot print the error message because it contains a random filename.
|
|
# Example: 1050: Table '<some_path>/var/tmp/#sql_6979_0' already exists
|
|
# Therefore we mangle it via
|
|
# "--error ER_TABLE_EXISTS_ERROR,9999" (9999 is currently not used)
|
|
# to "Got one of the listed errors".
|
|
create view t2 as select 1;
|
|
--error ER_TABLE_EXISTS_ERROR,9999
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
--error ER_TABLE_EXISTS_ERROR,9999
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop view t2;
|
|
drop table t1;
|
|
# Table to be used recreated (drop,create) with different layout
|
|
create table t1 (x varchar(20));
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
select * from t2;
|
|
drop table t2;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop table t2;
|
|
# Table to be used has a modified (alter table) layout
|
|
alter table t1 add column y decimal(10,3);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
select * from t2;
|
|
drop table t2;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
--echo # XXX: no validation of the first table in case of
|
|
--echo # CREATE TEMPORARY TABLE. This is a shortcoming of the current code,
|
|
--echo # but since validation is not strictly necessary, nothing is done
|
|
--echo # about it.
|
|
--echo # Will be fixed as part of work on Bug#21431 "Incomplete support of
|
|
--echo # temporary tables"
|
|
create table t1 (a int);
|
|
insert into t1 (a) values (1);
|
|
prepare stmt from "create temporary table if not exists t2 as select * from t1";
|
|
execute stmt;
|
|
drop table t2;
|
|
execute stmt;
|
|
execute stmt;
|
|
select * from t2;
|
|
execute stmt;
|
|
select * from t2;
|
|
drop table t2;
|
|
create temporary table t2 (a varchar(10));
|
|
execute stmt;
|
|
select * from t2;
|
|
call p_verify_reprepare_count(0);
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop table t1;
|
|
drop temporary table t2;
|
|
drop table t2;
|
|
deallocate prepare stmt;
|
|
|
|
create table t1 (a int);
|
|
prepare stmt from "create table t2 like t1";
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop table t2;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop table t2;
|
|
# Table to be used does not exist
|
|
drop table t1;
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
--error ER_NO_SUCH_TABLE
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
# Table to be used recreated (drop,create) with different layout
|
|
create table t1 (x char(17));
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
drop table t2;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop table t2;
|
|
# Table to be used has a modified (alter table) layout
|
|
alter table t1 add column y time;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(1);
|
|
select * from t2;
|
|
drop table t2;
|
|
execute stmt;
|
|
call p_verify_reprepare_count(0);
|
|
drop table t1;
|
|
drop table t2;
|
|
deallocate prepare stmt;
|
|
|
|
|
|
--echo #
|
|
--echo # SQLCOM_UPDATE
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
create table t2 (a int);
|
|
prepare stmt from "update t2 set a=a+1 where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1, t2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_INSERT
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
create table t2 (a int);
|
|
prepare stmt from "insert into t2 set a=((1) in (select * from t1))";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
|
|
drop table t1, t2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_INSERT_SELECT
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
create table t2 (a int);
|
|
prepare stmt from "insert into t2 select * from t1";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1, t2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_REPLACE
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
create table t2 (a int);
|
|
prepare stmt from "replace t2 set a=((1) in (select * from t1))";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1, t2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_REPLACE_SELECT
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
create table t2 (a int);
|
|
prepare stmt from "replace t2 select * from t1";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1, t2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_DELETE
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
create table t2 (a int);
|
|
prepare stmt from "delete from t2 where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1, t2;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_DELETE_MULTI
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2, t3;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
create table t2 (a int);
|
|
create table t3 (a int);
|
|
prepare stmt from "delete t2, t3 from t2, t3 where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1, t2, t3;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_UPDATE_MULTI
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1, t2, t3;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
create table t2 (a int);
|
|
create table t3 (a int);
|
|
prepare stmt from "update t2, t3 set t3.a=t2.a, t2.a=null where (1) in (select * from t1)";
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1, t2, t3;
|
|
deallocate prepare stmt;
|
|
--echo # Intermediate results: 8 SQLCOMs tested, 8 automatic reprepares
|
|
call p_verify_reprepare_count(8);
|
|
|
|
--echo #
|
|
--echo # SQLCOM_LOAD
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a varchar(20));
|
|
--error ER_UNSUPPORTED_PS
|
|
prepare stmt from "load data infile '../std_data_ln/words.dat' into table t1";
|
|
drop table t1;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_DATABASES
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show databases where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_TABLES
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show tables where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_FIELDS
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show fields from t1 where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_KEYS
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show keys from t1 where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_VARIABLES
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show variables where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_STATUS
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show status where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_LOGS,
|
|
--echo # SQLCOM_SHOW_ENGINE_MUTEX, SQLCOM_SHOW_PROCESSLIST
|
|
--echo #
|
|
|
|
--echo # Currently can not have a where clause, need to be covered
|
|
--echo # with tests
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
--error ER_PARSE_ERROR
|
|
prepare stmt from "show engine all status where (1) in (select * from t1)";
|
|
--error ER_PARSE_ERROR
|
|
prepare stmt from "show engine all logs where (1) in (select * from t1)";
|
|
--error ER_PARSE_ERROR
|
|
prepare stmt from "show engine all mutex where (1) in (select * from t1)";
|
|
--error ER_PARSE_ERROR
|
|
prepare stmt from "show processlist where (1) in (select * from t1)";
|
|
drop table t1;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_CHARSETS
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show charset where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_COLLATIONS
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show collation where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_TABLE_STATUS
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show table status where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_TRIGGERS
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show triggers where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_OPEN_TABLES
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show open tables where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_STATUS_PROC
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show procedure status where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_STATUS_FUNC
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "show function status where (1) in (select * from t1)";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SHOW_EVENTS
|
|
--echo #
|
|
--echo #
|
|
--echo # Please see this test in ps.test, it requires not_embedded.inc
|
|
--echo #
|
|
|
|
--echo #
|
|
--echo # SQLCOM_SET_OPTION
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "set @a=((1) in (select * from t1))";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_DO
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "do ((1) in (select * from t1))";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_CALL
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
drop procedure if exists p1;
|
|
--enable_warnings
|
|
create procedure p1(a int) begin end;
|
|
create table t1 (a int);
|
|
prepare stmt from "call p1((1) in (select * from t1))";
|
|
execute stmt;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop table t1;
|
|
drop procedure p1;
|
|
deallocate prepare stmt;
|
|
|
|
--echo #
|
|
--echo # SQLCOM_CREATE_VIEW
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
drop view if exists v1;
|
|
--enable_warnings
|
|
create table t1 (a int);
|
|
prepare stmt from "create view v1 as select * from t1";
|
|
execute stmt;
|
|
drop view v1;
|
|
drop table t1;
|
|
create table t1 (x int);
|
|
execute stmt;
|
|
drop view v1;
|
|
drop table t1;
|
|
deallocate prepare stmt;
|
|
--echo # Intermediate result: number of reprepares matches the number
|
|
--echo # of tests
|
|
call p_verify_reprepare_count(17);
|
|
|
|
--echo #
|
|
--echo # SQLCOM_ALTER_VIEW
|
|
--echo #
|
|
|
|
--disable_warnings
|
|
drop view if exists v1;
|
|
--enable_warnings
|
|
create view v1 as select 1;
|
|
--error ER_UNSUPPORTED_PS
|
|
prepare stmt from "alter view v1 as select 2";
|
|
drop view v1;
|
|
|
|
--echo # Cleanup
|
|
--echo #
|
|
--disable_warnings
|
|
drop temporary table if exists t1, t2, t3;
|
|
drop table if exists t1, t2, t3, v1, v2;
|
|
drop procedure if exists p_verify_reprepare_count;
|
|
drop procedure if exists p1;
|
|
drop function if exists f1;
|
|
drop view if exists v1, v2;
|
|
--enable_warnings
|