From e119174cfe8c9835214d3f34a616ded43f453db3 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Apr 2008 14:31:43 +0200 Subject: [PATCH 1/2] Minor corrections within the script mysql-test/r/ps_ddl.result: Updated results mysql-test/t/ps_ddl.test: - remove trailing spaces - correct wrong written word "echo" --- mysql-test/r/ps_ddl.result | 26 +++++++++++----------- mysql-test/t/ps_ddl.test | 44 +++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result index 3121650508d..cca00dd4781 100644 --- a/mysql-test/r/ps_ddl.result +++ b/mysql-test/r/ps_ddl.result @@ -192,6 +192,7 @@ SUCCESS select @message; @message new trigger: 11 +Test 6-e: removing a relevant trigger drop trigger t1_bi; set @val=12; execute stmt using @val; @@ -338,7 +339,7 @@ SUCCESS # # Sic: the insert went into t3, even though the view now # points at t2. This is because neither the merged view -# nor its prelocking list are affected by view DDL +# nor its prelocking list are affected by view DDL # The binary log is of course wrong, since it is not # using prepared statements # @@ -380,7 +381,7 @@ set @var=2; # Since the dependent table is tracked in the prelocked # list of the prepared statement, invalidation happens # and the statement is re-prepared. This is an unnecessary -# side effect, since the statement that *is* dependent +# side effect, since the statement that *is* dependent # on t2 definition is inside the trigger, and it is currently # not reprepared (see the previous test case). execute stmt using @var; @@ -398,7 +399,7 @@ a comment drop table t1,t2; # Test 7-e: dependent TABLE TRIGGER has changed create table t1 (a int); -create trigger t1_ai after insert on t1 for each row +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 @@ -740,6 +741,7 @@ drop procedure p1; create procedure p1(out x int) select max(a) from t2 into x; # XXX: bug. The prelocked list is not invalidated # and we keep opening table t1, whereas the procedure +# is now referring to table t2 execute stmt; ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them call p_verify_reprepare_count(0); @@ -1007,7 +1009,7 @@ prepare stmt from "alter table t1 add column b int"; execute stmt; drop table t1; create table t1 (a1 int, a2 int); -# t1 has changed, and it's does not lead to reprepare +# t1 has changed, and it's does not lead to reprepare execute stmt; alter table t1 drop column b; execute stmt; @@ -1030,7 +1032,7 @@ test.t1 repair status OK drop table t1; create table t1 (a1 int, a2 int); insert into t1 values (1, 10), (2, 20), (3, 30); -# t1 has changed, and it's does not lead to reprepare +# t1 has changed, and it's does not lead to reprepare execute stmt; Table Op Msg_type Msg_text test.t1 repair status OK @@ -1333,7 +1335,7 @@ insert into t_27430_2 values (2, 2), (1234, 3), (1234, 4); -prepare stmt from +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; oref a Z @@ -1346,7 +1348,7 @@ SUCCESS 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 +insert into t_27430_1 values (1, 1), (1, NULL), (2, 3), @@ -1500,7 +1502,7 @@ drop procedure p_12093; deallocate prepare stmt_sf; deallocate prepare stmt_sp; ===================================================================== -Ensure that metadata validation is performed for every type of +Ensure that metadata validation is performed for every type of SQL statement where it is needed. ===================================================================== drop table if exists t1; @@ -1586,7 +1588,7 @@ deallocate prepare stmt; # CREATE TEMPORARY TABLE. This is a shortcoming of the current code, # but since validation is not strictly necessary, nothing is done # about it. -# Will be fixed as part of work on Bug#21431 "Incomplete support of +# Will be fixed as part of work on Bug#21431 "Incomplete support of # temporary tables" create table t1 (a int); insert into t1 (a) values (1); @@ -1839,11 +1841,11 @@ Variable_name Value drop table t1; deallocate prepare stmt; # -# SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_LOGS, +# SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_LOGS, # SQLCOM_SHOW_ENGINE_MUTEX, SQLCOM_SHOW_PROCESSLIST # # Currently can not have a where clause, need to be covered -# with tests +# with tests drop table if exists t1; create table t1 (a int); prepare stmt from "show engine all status where (1) in (select * from t1)"; @@ -2035,7 +2037,7 @@ prepare stmt from "alter view v1 as select 2"; ERROR HY000: This command is not supported in the prepared statement protocol yet drop view v1; # Cleanup -# +# 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; diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test index 94791cd81f8..810dc568eee 100644 --- a/mysql-test/t/ps_ddl.test +++ b/mysql-test/t/ps_ddl.test @@ -181,7 +181,7 @@ select @message; # 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); @@ -229,7 +229,7 @@ execute stmt using @val; call p_verify_reprepare_count(1); select @message; ---ehco Test 6-e: removing a relevant trigger +--echo Test 6-e: removing a relevant trigger drop trigger t1_bi; @@ -338,7 +338,7 @@ call p_verify_reprepare_count(0); --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 # 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 # @@ -367,7 +367,7 @@ 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 # 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; @@ -378,7 +378,7 @@ 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 +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 @@ -674,7 +674,7 @@ drop procedure p1; create procedure p1(out x int) select max(a) from t2 into x; --echo # XXX: bug. The prelocked list is not invalidated --echo # and we keep opening table t1, whereas the procedure ---ehco # is now referring to table t2 +--echo # is now referring to table t2 --error ER_VIEW_INVALID execute stmt; call p_verify_reprepare_count(0); @@ -702,7 +702,7 @@ execute stmt; call p_verify_reprepare_count(1); execute stmt; --echo # Test 18-d: dependent TABLE has changed -drop view v2; +drop view v2; create table v2 as select * from t1; execute stmt; call p_verify_reprepare_count(1); @@ -854,7 +854,7 @@ execute stmt; drop table t1; create table t1 (a1 int, a2 int); ---echo # t1 has changed, and it's does not lead to reprepare +--echo # t1 has changed, and it's does not lead to reprepare execute stmt; alter table t1 drop column b; @@ -881,7 +881,7 @@ 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 +--echo # t1 has changed, and it's does not lead to reprepare execute stmt; alter table t1 add column b varchar(50) default NULL; @@ -1190,16 +1190,16 @@ insert into t_27430_2 values (1234, 3), (1234, 4); -prepare stmt from +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; +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 +insert into t_27430_1 values (1, 1), (1, NULL), (2, 3), @@ -1237,7 +1237,7 @@ 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"; +prepare stmt from "select * from v_27690_1, v_27690_2"; execute stmt; execute stmt; @@ -1327,17 +1327,17 @@ drop procedure p_12093_unrelated; connection default; --echo # XXX: bug ---error ER_SP_DOES_NOT_EXIST +--error ER_SP_DOES_NOT_EXIST execute stmt_sf; --echo # XXX: bug ---error ER_SP_DOES_NOT_EXIST +--error ER_SP_DOES_NOT_EXIST execute stmt_sp; --echo # XXX: bug ---error ER_SP_DOES_NOT_EXIST +--error ER_SP_DOES_NOT_EXIST execute stmt_sf; --echo # XXX: bug ---error ER_SP_DOES_NOT_EXIST +--error ER_SP_DOES_NOT_EXIST execute stmt_sp; call p_verify_reprepare_count(0); @@ -1351,7 +1351,7 @@ deallocate prepare stmt_sp; --echo ===================================================================== ---echo Ensure that metadata validation is performed for every type of +--echo Ensure that metadata validation is performed for every type of --echo SQL statement where it is needed. --echo ===================================================================== --disable_warnings @@ -1421,7 +1421,7 @@ deallocate prepare stmt; --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 # 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); @@ -1697,12 +1697,12 @@ drop table t1; deallocate prepare stmt; --echo # ---echo # SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_LOGS, +--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 +--echo # with tests --disable_warnings drop table if exists t1; @@ -1932,7 +1932,7 @@ prepare stmt from "alter view v1 as select 2"; drop view v1; --echo # Cleanup ---echo # +--echo # --disable_warnings drop temporary table if exists t1, t2, t3; drop table if exists t1, t2, t3, v1, v2; From 0a3d14a3950a8f07fecd4184f50ac3a781bc33dd Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 18 Apr 2008 21:18:53 +0200 Subject: [PATCH 2/2] Add tests + modifications according to review mysql-test/r/ps_ddl.result: Updated results mysql-test/t/ps_ddl.test: - add missing subtests - add comments + minor reformatting for better overview on content mysql-test/r/ps_ddl1.result: Expected results mysql-test/t/ps_ddl1.test: Script for tests which do not really fit into ps_ddl --- mysql-test/r/ps_ddl.result | 170 ++++++++++++- mysql-test/r/ps_ddl1.result | 482 ++++++++++++++++++++++++++++++++++++ mysql-test/t/ps_ddl.test | 140 ++++++++++- mysql-test/t/ps_ddl1.test | 398 +++++++++++++++++++++++++++++ 4 files changed, 1182 insertions(+), 8 deletions(-) create mode 100644 mysql-test/r/ps_ddl1.result create mode 100644 mysql-test/t/ps_ddl1.test diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result index cca00dd4781..9e1db062368 100644 --- a/mysql-test/r/ps_ddl.result +++ b/mysql-test/r/ps_ddl.result @@ -35,6 +35,7 @@ Part 3: NOTHING -> VIEW transitions ===================================================================== Part 4: TABLE -> NOTHING transitions ===================================================================== +# Test 4-a: select ... from create table t1 (a int); prepare stmt from "select * from t1"; execute stmt; @@ -59,6 +60,32 @@ call p_verify_reprepare_count(0); SUCCESS deallocate prepare stmt; +# Test 4-b: TABLE -> NOTHING by renaming the table +create table t1 (a int); +prepare stmt from "select * from t1"; +execute stmt; +a +call p_verify_reprepare_count(0); +SUCCESS + +execute stmt; +a +call p_verify_reprepare_count(0); +SUCCESS + +rename table t1 to t2; +execute stmt; +ERROR 42S02: Table 'test.t1' doesn't exist +call p_verify_reprepare_count(0); +SUCCESS + +execute stmt; +ERROR 42S02: Table 'test.t1' doesn't exist +call p_verify_reprepare_count(0); +SUCCESS + +deallocate prepare stmt; +drop table t2; ===================================================================== Part 5: TABLE -> TABLE (DDL) transitions ===================================================================== @@ -445,6 +472,7 @@ deallocate prepare stmt; ===================================================================== Part 8: TABLE -> TEMPORARY TABLE transitions ===================================================================== +# Test 8-a: base table used recreated as temporary table create table t1 (a int); prepare stmt from "select * from t1"; execute stmt; @@ -463,6 +491,37 @@ SUCCESS drop table t1; deallocate prepare stmt; +# 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; +count(*) +0 +call p_verify_reprepare_count(0); +SUCCESS + +execute stmt; +count(*) +0 +call p_verify_reprepare_count(0); +SUCCESS + +create temporary table t1 AS SELECT 1; +execute stmt; +count(*) +1 +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt; +count(*) +1 +call p_verify_reprepare_count(0); +SUCCESS + +deallocate prepare stmt; +drop temporary table t1; +drop table t1; ===================================================================== Part 9: TABLE -> VIEW transitions ===================================================================== @@ -504,6 +563,7 @@ deallocate prepare stmt; ===================================================================== Part 11: TEMPORARY TABLE -> TABLE transitions ===================================================================== +# 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); @@ -525,6 +585,38 @@ a 1 drop table t1; deallocate prepare stmt; +# Test 11-b: temporary table has precedence over base table with same name +# 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; +count(*) +1 +call p_verify_reprepare_count(0); +SUCCESS + +execute stmt; +count(*) +1 +call p_verify_reprepare_count(0); +SUCCESS + +drop temporary table t1; +execute stmt; +count(*) +0 +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt; +count(*) +0 +call p_verify_reprepare_count(0); +SUCCESS + +deallocate prepare stmt; +drop table t1; ===================================================================== Part 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions ===================================================================== @@ -1505,11 +1597,11 @@ deallocate prepare stmt_sp; Ensure that metadata validation is performed for every type of SQL statement where it is needed. ===================================================================== -drop table if exists t1; -create table t1 (a int); # # SQLCOM_SELECT # +drop table if exists t1; +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); @@ -1568,6 +1660,18 @@ call p_verify_reprepare_count(0); SUCCESS drop table t2; +create view t2 as select 1; +execute stmt; +Got one of the listed errors +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt; +Got one of the listed errors +call p_verify_reprepare_count(0); +SUCCESS + +drop view t2; drop table t1; create table t1 (x varchar(20)); execute stmt; @@ -1582,6 +1686,18 @@ call p_verify_reprepare_count(0); SUCCESS drop table t2; +alter table t1 add column y decimal(10,3); +execute stmt; +call p_verify_reprepare_count(1); +SUCCESS + +select * from t2; +x y +drop table t2; +execute stmt; +call p_verify_reprepare_count(0); +SUCCESS + drop table t1; deallocate prepare stmt; # XXX: no validation of the first table in case of @@ -1636,6 +1752,56 @@ Note 1050 Table 't2' already exists call p_verify_reprepare_count(0); SUCCESS +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); +SUCCESS + +drop table t2; +execute stmt; +call p_verify_reprepare_count(0); +SUCCESS + +drop table t2; +drop table t1; +execute stmt; +ERROR 42S02: Table 'test.t1' doesn't exist +call p_verify_reprepare_count(0); +SUCCESS + +execute stmt; +ERROR 42S02: Table 'test.t1' doesn't exist +call p_verify_reprepare_count(0); +SUCCESS + +create table t1 (x char(17)); +execute stmt; +call p_verify_reprepare_count(1); +SUCCESS + +drop table t2; +execute stmt; +call p_verify_reprepare_count(0); +SUCCESS + +drop table t2; +alter table t1 add column y time; +execute stmt; +call p_verify_reprepare_count(1); +SUCCESS + +select * from t2; +x y +drop table t2; +execute stmt; +call p_verify_reprepare_count(0); +SUCCESS + drop table t1; drop table t2; deallocate prepare stmt; diff --git a/mysql-test/r/ps_ddl1.result b/mysql-test/r/ps_ddl1.result new file mode 100644 index 00000000000..87abcd90590 --- /dev/null +++ b/mysql-test/r/ps_ddl1.result @@ -0,0 +1,482 @@ +drop temporary table if exists t1; +drop table if exists t1, t2; +drop procedure if exists p_verify_reprepare_count; +drop procedure if exists p1; +drop function if exists f1; +drop view if exists t1; +drop schema if exists mysqltest; +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| +set @reprepare_count= 0; +flush status; +drop table if exists t1; +# Column added or dropped is not within the list of selected columns +# or table comment has changed. +# A reprepare is probably not needed. +create table t1 (a int, b int); +prepare stmt from "select a from t1"; +execute stmt; +a +call p_verify_reprepare_count(0); +SUCCESS + +alter table t1 add column c int; +execute stmt; +a +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt; +a +call p_verify_reprepare_count(0); +SUCCESS + +alter table t1 drop column b; +execute stmt; +a +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt; +a +call p_verify_reprepare_count(0); +SUCCESS + +alter table t1 comment "My best table"; +execute stmt; +a +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt; +a +call p_verify_reprepare_count(0); +SUCCESS + +drop table t1; +deallocate prepare stmt; +# Selects using the table at various positions, inser,update ... +# + the table disappears +create table t1 (a int); +prepare stmt1 from "truncate t1"; +prepare stmt2 from "select 1 as my_column from t1"; +prepare stmt3 from "select 1 as my_column from (select * from t1) as t2"; +prepare stmt4 from +"select 1 as my_column from (select 1) as t2 where exists (select 1 from t1)"; +prepare stmt5 from "select * from (select 1 as b) as t2, t1"; +prepare stmt6 from "select * from t1 union all select 1.5"; +prepare stmt7 from "select 1 as my_column union all select 1 from t1"; +prepare stmt8 from "insert into t1 values(1),(2)"; +prepare stmt9 from "update t1 set a = 3 where a = 2"; +prepare stmt10 from "delete from t1 where a = 1"; +# Attention: Result logging is disabled. +execute stmt10; +execute stmt9; +execute stmt8; +execute stmt7; +execute stmt6; +execute stmt5; +execute stmt4; +execute stmt3; +execute stmt2; +execute stmt1; +call p_verify_reprepare_count(0); +SUCCESS + +drop table t1; +execute stmt10; +ERROR 42S02: Table 'test.t1' doesn't exist +execute stmt9; +ERROR 42S02: Table 'test.t1' doesn't exist +execute stmt8; +ERROR 42S02: Table 'test.t1' doesn't exist +execute stmt7; +ERROR 42S02: Table 'test.t1' doesn't exist +execute stmt6; +ERROR 42S02: Table 'test.t1' doesn't exist +execute stmt5; +ERROR 42S02: Table 'test.t1' doesn't exist +execute stmt4; +ERROR 42S02: Table 'test.t1' doesn't exist +execute stmt3; +ERROR 42S02: Table 'test.t1' doesn't exist +execute stmt2; +ERROR 42S02: Table 'test.t1' doesn't exist +execute stmt1; +ERROR 42S02: Table 'test.t1' doesn't exist +call p_verify_reprepare_count(0); +SUCCESS + +deallocate prepare stmt10; +deallocate prepare stmt9; +deallocate prepare stmt8; +deallocate prepare stmt7; +deallocate prepare stmt6; +deallocate prepare stmt5; +deallocate prepare stmt4; +deallocate prepare stmt3; +deallocate prepare stmt2; +deallocate prepare stmt1; +# Selects using the table at various positions, inser,update ... +# + layout change (drop column) which must cause a reprepare +create table t1 (a int, b int); +insert into t1 values(1,1),(2,2),(3,3); +create table t2 like t1; +insert into t1 values(2,2); +prepare stmt1 from "select a,b from t1"; +prepare stmt2 from "select a,b from (select * from t1) as t1"; +prepare stmt3 from "select * from t1 where a = 2 and b = 2"; +prepare stmt4 from "select * from t2 where (a,b) in (select * from t1)"; +prepare stmt5 from "select * from t1 union select * from t2"; +prepare stmt6 from "select * from t1 union all select * from t2"; +prepare stmt7 from "insert into t1 set a = 4, b = 4"; +prepare stmt8 from "insert into t1 select * from t2"; +# Attention: Result logging is disabled. +execute stmt8; +execute stmt7; +execute stmt6; +execute stmt5; +execute stmt4; +execute stmt3; +execute stmt2; +execute stmt1; +call p_verify_reprepare_count(0); +SUCCESS + +alter table t1 drop column b; +execute stmt8; +ERROR 21S01: Column count doesn't match value count at row 1 +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt7; +ERROR 42S22: Unknown column 'b' in 'field list' +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt6; +ERROR 21000: The used SELECT statements have a different number of columns +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt5; +ERROR 21000: The used SELECT statements have a different number of columns +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt4; +ERROR 21000: Operand should contain 2 column(s) +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt3; +ERROR 42S22: Unknown column 'b' in 'where clause' +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt2; +ERROR 42S22: Unknown column 'b' in 'field list' +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt1; +ERROR 42S22: Unknown column 'b' in 'field list' +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt8; +ERROR 21S01: Column count doesn't match value count at row 1 +call p_verify_reprepare_count(1); +ERROR +Expected: 1, actual: 0 +execute stmt7; +ERROR 42S22: Unknown column 'b' in 'field list' +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt6; +ERROR 21000: The used SELECT statements have a different number of columns +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt5; +ERROR 21000: The used SELECT statements have a different number of columns +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt4; +ERROR 21000: Operand should contain 2 column(s) +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt3; +ERROR 42S22: Unknown column 'b' in 'where clause' +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt2; +ERROR 42S22: Unknown column 'b' in 'field list' +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt1; +ERROR 42S22: Unknown column 'b' in 'field list' +call p_verify_reprepare_count(1); +SUCCESS + +# Why does the INSERT ... SELECT does not get a reprepare or is +# only the counter not incremented? +execute stmt8; +ERROR 21S01: Column count doesn't match value count at row 1 +call p_verify_reprepare_count(1); +ERROR +Expected: 1, actual: 0 +alter table t2 add column c int; +execute stmt8; +ERROR 21S01: Column count doesn't match value count at row 1 +call p_verify_reprepare_count(1); +SUCCESS + +deallocate prepare stmt8; +deallocate prepare stmt7; +deallocate prepare stmt6; +deallocate prepare stmt5; +deallocate prepare stmt4; +deallocate prepare stmt3; +deallocate prepare stmt2; +deallocate prepare stmt1; +drop table t1; +drop table t2; +# select AVG() + optimizer uses index meets loss of the index +create table t1 (a int, b int, primary key(b),unique index t1_unq_idx(a)); +insert into t1 set a = 0, b = 0; +insert into t1 select a + 1, b + 1 from t1; +insert into t1 select a + 2, b + 2 from t1; +insert into t1 select a + 4, b + 4 from t1; +insert into t1 select a + 8, b + 8 from t1; +# Optimizer strategy: Possible keys = NULL , Extra = Using index +prepare stmt from "select avg(a) from t1"; +execute stmt; +avg(a) +7.5000 +call p_verify_reprepare_count(0); +SUCCESS + +execute stmt; +avg(a) +7.5000 +call p_verify_reprepare_count(0); +SUCCESS + +alter table t1 drop index t1_unq_idx; +# Optimizer strategy: Possible keys = NULL , Extra = +execute stmt; +avg(a) +7.5000 +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt; +avg(a) +7.5000 +call p_verify_reprepare_count(0); +SUCCESS + +# select AVG() + optimizer uses table scan meets a new index +alter table t1 add unique index t1_unq_idx(a); +# Optimizer strategy: Possible keys = NULL , Extra = Using index +execute stmt; +avg(a) +7.5000 +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt; +avg(a) +7.5000 +call p_verify_reprepare_count(0); +SUCCESS + +deallocate prepare stmt; +drop table t1; +# table replaced by not updatable view - Insert +create table t1 (a int); +prepare stmt from "insert into t1 values(1)"; +execute stmt; +call p_verify_reprepare_count(0); +SUCCESS + +drop table t1; +create view t1 as select 1; +execute stmt; +ERROR HY000: The target table t1 of the INSERT is not insertable-into +call p_verify_reprepare_count(1); +SUCCESS + +drop view t1; +create table t2 (a int); +create view t1 as select * from t2 with check option; +execute stmt; +call p_verify_reprepare_count(1); +SUCCESS + +execute stmt; +call p_verify_reprepare_count(0); +SUCCESS + +select * from t1; +a +1 +1 +deallocate prepare stmt; +drop view t1; +drop table t2; +===================================================================== +Some freestyle tests +===================================================================== +create temporary table t1 as select 1 as a; +create procedure p1() +begin +drop temporary table t1; +end| +create function f1() returns int +begin +call p1(); +return 1; +end| +prepare stmt from "select f1() as my_column, a from t1"; +execute stmt; +ERROR HY000: Can't reopen table: 't1' +call p_verify_reprepare_count(0); +SUCCESS + +select * from t1; +a +1 +prepare stmt from "select a, f1() as my_column from t1"; +execute stmt; +ERROR HY000: Can't reopen table: 't1' +call p_verify_reprepare_count(0); +SUCCESS + +select * from t1; +a +1 +prepare stmt from "select f1() as my_column, count(*) from t1"; +execute stmt; +ERROR HY000: Can't reopen table: 't1' +call p_verify_reprepare_count(0); +SUCCESS + +select * from t1; +a +1 +prepare stmt from "select count(*), f1() as my_column from t1"; +execute stmt; +ERROR HY000: Can't reopen table: 't1' +call p_verify_reprepare_count(0); +SUCCESS + +select * from t1; +a +1 +# Execute fails, no drop of temporary table +prepare stmt from "select 1 as my_column from (select 1) as t2 + where exists (select f1() from t1)"; +execute stmt; +my_column +1 +call p_verify_reprepare_count(0); +SUCCESS + +execute stmt; +my_column +1 +call p_verify_reprepare_count(0); +SUCCESS + +select * from t1; +a +1 +# Execute drops temporary table +prepare stmt from "select f1()"; +execute stmt; +f1() +1 +call p_verify_reprepare_count(0); +SUCCESS + +execute stmt; +ERROR 42S02: Unknown table 't1' +call p_verify_reprepare_count(0); +SUCCESS + +drop function f1; +drop procedure p1; +deallocate prepare stmt; +# Execute fails, temporary table is not replaced by another +create temporary table t1 as select 1 as a; +create procedure p1() +begin +drop temporary table t1; +create temporary table t1 as select 'abc' as a; +end| +create function f1() returns int +begin +call p1(); +return 1; +end| +prepare stmt from "select count(*), f1() as my_column from t1"; +execute stmt; +ERROR HY000: Can't reopen table: 't1' +call p_verify_reprepare_count(0); +SUCCESS + +select * from t1; +a +1 +deallocate prepare stmt; +prepare stmt from "call p1"; +execute stmt; +drop procedure p1; +create schema mysqltest; +create procedure mysqltest.p1() +begin +drop schema mysqltest; +create schema mysqltest; +end| +execute stmt; +ERROR 42000: PROCEDURE test.p1 does not exist +call p_verify_reprepare_count(0); +SUCCESS + +execute stmt; +ERROR 42000: PROCEDURE test.p1 does not exist +call p_verify_reprepare_count(0); +SUCCESS + +deallocate prepare stmt; +drop schema mysqltest; +drop temporary table t1; +# Cleanup +# +drop temporary table if exists t1; +drop table if exists t1, t2; +drop procedure if exists p_verify_reprepare_count; +drop procedure if exists p1; +drop function if exists f1; +drop view if exists t1; +drop schema if exists mysqltest; diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test index 810dc568eee..e19e73df3ac 100644 --- a/mysql-test/t/ps_ddl.test +++ b/mysql-test/t/ps_ddl.test @@ -104,6 +104,7 @@ prepare stmt from "select * from t1"; --echo Part 4: TABLE -> NOTHING transitions --echo ===================================================================== +--echo # Test 4-a: select ... from
create table t1 (a int); prepare stmt from "select * from t1"; @@ -121,6 +122,25 @@ 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 ===================================================================== @@ -143,11 +163,11 @@ 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); @@ -414,6 +434,7 @@ deallocate prepare stmt; --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"; @@ -430,6 +451,25 @@ 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 ===================================================================== @@ -471,6 +511,7 @@ deallocate prepare stmt; --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); @@ -488,6 +529,27 @@ 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 ===================================================================== @@ -1354,13 +1416,15 @@ deallocate prepare stmt_sp; --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); ---echo # ---echo # SQLCOM_SELECT ---echo # prepare stmt from "select 1 as res from dual where (1) in (select * from t1)"; drop table t1; create table t1 (x int); @@ -1368,16 +1432,16 @@ 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; @@ -1385,6 +1449,7 @@ 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); @@ -1392,6 +1457,7 @@ call p_verify_reprepare_count(1); 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); --error ER_TABLE_EXISTS_ERROR execute stmt; @@ -1406,7 +1472,23 @@ drop table t2; execute stmt; call p_verify_reprepare_count(0); 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 '/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); @@ -1415,6 +1497,14 @@ 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 @@ -1445,9 +1535,47 @@ 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 # diff --git a/mysql-test/t/ps_ddl1.test b/mysql-test/t/ps_ddl1.test new file mode 100644 index 00000000000..0145d445a14 --- /dev/null +++ b/mysql-test/t/ps_ddl1.test @@ -0,0 +1,398 @@ +# +# Testing the behavior of 'PREPARE', 'DDL', 'EXECUTE' scenarios +# +# There are several subtests which are probably "superfluous" because a DDL +# statement before the EXECUTE contained a keyword +# or action (Example: Alter) which causes that all prepared statements using +# the modified object are reprepared before execution. +# Please do not delete these subtests if they disturb. Just disable them by +# if (0) +# { +# +# }. +# There might be future optimisations of the server which decrease the amount +# of unneeded reprepares or skip unneeded prepare steps and than these subtests +# might become valuable. +# Example: +# Every preceding ALTER TABLE seems to cause a reprepare. +# But if the ALTER only changed the table comment ... +# +# Created: 2008-04-18 mleich +# + +--disable_warnings +drop temporary table if exists t1; +drop table if exists t1, t2; +drop procedure if exists p_verify_reprepare_count; +drop procedure if exists p1; +drop function if exists f1; +drop view if exists t1; +drop schema if exists mysqltest; +--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; + +--disable_warnings +drop table if exists t1; +--disable_warnings + +--echo # Column added or dropped is not within the list of selected columns +--echo # or table comment has changed. +--echo # A reprepare is probably not needed. +create table t1 (a int, b int); +prepare stmt from "select a from t1"; +execute stmt; +call p_verify_reprepare_count(0); +alter table t1 add column c int; +execute stmt; +call p_verify_reprepare_count(1); +execute stmt; +call p_verify_reprepare_count(0); +alter table t1 drop column b; +execute stmt; +call p_verify_reprepare_count(1); +execute stmt; +call p_verify_reprepare_count(0); +alter table t1 comment "My best table"; +execute stmt; +call p_verify_reprepare_count(1); +execute stmt; +call p_verify_reprepare_count(0); +drop table t1; +deallocate prepare stmt; + +--echo # Selects using the table at various positions, inser,update ... +--echo # + the table disappears +create table t1 (a int); +# Attention: +# "truncate" must have the first position (= executed as last prepared +# statement), because it recreates the table which has leads to reprepare +# (is this really needed) of all statements. +prepare stmt1 from "truncate t1"; +prepare stmt2 from "select 1 as my_column from t1"; +prepare stmt3 from "select 1 as my_column from (select * from t1) as t2"; +prepare stmt4 from +"select 1 as my_column from (select 1) as t2 where exists (select 1 from t1)"; +prepare stmt5 from "select * from (select 1 as b) as t2, t1"; +prepare stmt6 from "select * from t1 union all select 1.5"; +prepare stmt7 from "select 1 as my_column union all select 1 from t1"; +prepare stmt8 from "insert into t1 values(1),(2)"; +prepare stmt9 from "update t1 set a = 3 where a = 2"; +prepare stmt10 from "delete from t1 where a = 1"; +let ps_stmt_count= 10; +--echo # Attention: Result logging is disabled. +# Checks of correct results of statements are not the goal of this test. +let $num= $ps_stmt_count; +while ($num) +{ + --disable_result_log + eval execute stmt$num; + --enable_result_log + dec $num; +} +# There was no reprepare needed, because none of the objects has changed. +call p_verify_reprepare_count(0); +drop table t1; +let $num= $ps_stmt_count; +while ($num) +{ + --error ER_NO_SUCH_TABLE + eval execute stmt$num; + dec $num; +} +# There was no reprepare needed, because the statement is no more applicable. +call p_verify_reprepare_count(0); +let $num= $ps_stmt_count; +while ($num) +{ + eval deallocate prepare stmt$num; + dec $num; +} + +--echo # Selects using the table at various positions, inser,update ... +--echo # + layout change (drop column) which must cause a reprepare +create table t1 (a int, b int); +insert into t1 values(1,1),(2,2),(3,3); +create table t2 like t1; +insert into t1 values(2,2); +prepare stmt1 from "select a,b from t1"; +prepare stmt2 from "select a,b from (select * from t1) as t1"; +prepare stmt3 from "select * from t1 where a = 2 and b = 2"; +prepare stmt4 from "select * from t2 where (a,b) in (select * from t1)"; +prepare stmt5 from "select * from t1 union select * from t2"; +prepare stmt6 from "select * from t1 union all select * from t2"; +prepare stmt7 from "insert into t1 set a = 4, b = 4"; +prepare stmt8 from "insert into t1 select * from t2"; +let ps_stmt_count= 8; +--echo # Attention: Result logging is disabled. +# Checks of correct results of statements are not the goal of this test. +let $num= $ps_stmt_count; +while ($num) +{ + --disable_result_log + eval execute stmt$num; + --enable_result_log + dec $num; +} +call p_verify_reprepare_count(0); +alter table t1 drop column b; +--disable_abort_on_error +let $num= $ps_stmt_count; +while ($num) +{ + eval execute stmt$num; + # A reprepare is needed, because layout change of t1 affects statement. + call p_verify_reprepare_count(1); + dec $num; +} +let $num= $ps_stmt_count; +while ($num) +{ + eval execute stmt$num; + call p_verify_reprepare_count(1); + dec $num; +} +--echo # Why does the INSERT ... SELECT does not get a reprepare or is +--echo # only the counter not incremented? +eval execute stmt8; +call p_verify_reprepare_count(1); +--enable_abort_on_error +alter table t2 add column c int; +--error ER_WRONG_VALUE_COUNT_ON_ROW +eval execute stmt8; +call p_verify_reprepare_count(1); +let $num= $ps_stmt_count; +while ($num) +{ + eval deallocate prepare stmt$num; + dec $num; +} +drop table t1; +drop table t2; + + +--echo # select AVG() + optimizer uses index meets loss of the index +create table t1 (a int, b int, primary key(b),unique index t1_unq_idx(a)); +# We need an index which is not converted to PRIMARY KEY (becomes in +# case of InnoDB the key used for table clustering). +insert into t1 set a = 0, b = 0; +insert into t1 select a + 1, b + 1 from t1; +insert into t1 select a + 2, b + 2 from t1; +insert into t1 select a + 4, b + 4 from t1; +insert into t1 select a + 8, b + 8 from t1; +# "using index" optimizer strategy is intended +let $possible_keys= + query_get_value(explain select avg(a) from t1, possible_keys, 1); +let $extra= + query_get_value(explain select avg(a) from t1, Extra, 1); +--echo # Optimizer strategy: Possible keys = $possible_keys , Extra = $extra +prepare stmt from "select avg(a) from t1"; +execute stmt; +call p_verify_reprepare_count(0); +execute stmt; +call p_verify_reprepare_count(0); + +alter table t1 drop index t1_unq_idx; +let $possible_keys= + query_get_value(explain select avg(a) from t1, possible_keys, 1); +let $extra= + query_get_value(explain select avg(a) from t1, Extra, 1); +--echo # Optimizer strategy: Possible keys = $possible_keys , Extra = $extra +execute stmt; +call p_verify_reprepare_count(1); +execute stmt; +call p_verify_reprepare_count(0); + + +--echo # select AVG() + optimizer uses table scan meets a new index +alter table t1 add unique index t1_unq_idx(a); +let $possible_keys= + query_get_value(explain select avg(a) from t1, possible_keys, 1); +let $extra= + query_get_value(explain select avg(a) from t1, Extra, 1); +--echo # Optimizer strategy: Possible keys = $possible_keys , Extra = $extra +execute stmt; +call p_verify_reprepare_count(1); +execute stmt; +call p_verify_reprepare_count(0); + +deallocate prepare stmt; +drop table t1; + + +--echo # table replaced by not updatable view - Insert +create table t1 (a int); +prepare stmt from "insert into t1 values(1)"; +execute stmt; +call p_verify_reprepare_count(0); + +drop table t1; +create view t1 as select 1; +--error ER_NON_INSERTABLE_TABLE +execute stmt; +call p_verify_reprepare_count(1); + +drop view t1; +create table t2 (a int); +create view t1 as select * from t2 with check option; +execute stmt; +call p_verify_reprepare_count(1); +execute stmt; +call p_verify_reprepare_count(0); +select * from t1; + +deallocate prepare stmt; +drop view t1; +drop table t2; + + +--echo ===================================================================== +--echo Some freestyle tests +--echo ===================================================================== + +create temporary table t1 as select 1 as a; +delimiter |; +create procedure p1() +begin + drop temporary table t1; +end| +create function f1() returns int +begin + call p1(); + return 1; +end| +delimiter ;| + +prepare stmt from "select f1() as my_column, a from t1"; +--error ER_CANT_REOPEN_TABLE +execute stmt; +call p_verify_reprepare_count(0); +select * from t1; + +prepare stmt from "select a, f1() as my_column from t1"; +--error ER_CANT_REOPEN_TABLE +execute stmt; +call p_verify_reprepare_count(0); +select * from t1; + +prepare stmt from "select f1() as my_column, count(*) from t1"; +--error ER_CANT_REOPEN_TABLE +execute stmt; +call p_verify_reprepare_count(0); +select * from t1; + +prepare stmt from "select count(*), f1() as my_column from t1"; +--error ER_CANT_REOPEN_TABLE +execute stmt; +call p_verify_reprepare_count(0); +select * from t1; + + +--echo # Execute fails, no drop of temporary table +prepare stmt from "select 1 as my_column from (select 1) as t2 + where exists (select f1() from t1)"; +execute stmt; +call p_verify_reprepare_count(0); +execute stmt; +call p_verify_reprepare_count(0); +select * from t1; + +--echo # Execute drops temporary table +prepare stmt from "select f1()"; +execute stmt; +call p_verify_reprepare_count(0); +--error ER_BAD_TABLE_ERROR +execute stmt; +call p_verify_reprepare_count(0); + +drop function f1; +drop procedure p1; +deallocate prepare stmt; + +--echo # Execute fails, temporary table is not replaced by another +create temporary table t1 as select 1 as a; +delimiter |; +create procedure p1() +begin + drop temporary table t1; + create temporary table t1 as select 'abc' as a; +end| +create function f1() returns int +begin + call p1(); + return 1; +end| +delimiter ;| +prepare stmt from "select count(*), f1() as my_column from t1"; +--error ER_CANT_REOPEN_TABLE +execute stmt; +call p_verify_reprepare_count(0); +select * from t1; +deallocate prepare stmt; + +prepare stmt from "call p1"; +execute stmt; +drop procedure p1; +create schema mysqltest; +delimiter |; +create procedure mysqltest.p1() +begin + drop schema mysqltest; + create schema mysqltest; +end| +delimiter ;| +--error ER_SP_DOES_NOT_EXIST +execute stmt; +call p_verify_reprepare_count(0); +--error ER_SP_DOES_NOT_EXIST +execute stmt; +call p_verify_reprepare_count(0); +deallocate prepare stmt; +drop schema mysqltest; +drop temporary table t1; + + +# Bug#36089 drop temp table in SP called by function, crash +# Note: A non prepared "select 1 from t1 having count(*) = f1();" is sufficient. +if (0) +{ +create temporary table t1 as select 1 as a; +prepare stmt from "select 1 from t1 having count(*) = f1()"; +execute stmt; +call p_verify_reprepare_count(0); +deallocate prepare stmt; +drop temporary table t1; +} + + +--echo # Cleanup +--echo # +--disable_warnings +drop temporary table if exists t1; +drop table if exists t1, t2; +drop procedure if exists p_verify_reprepare_count; +drop procedure if exists p1; +drop function if exists f1; +drop view if exists t1; +drop schema if exists mysqltest; +--enable_warnings