Commit 30296dca authored by kostja@bodhi.(none)'s avatar kostja@bodhi.(none)

Merge bk-internal.mysql.com:/home/bk/mysql-5.1-27430

into  bodhi.(none):/opt/local/work/mysql-5.1-27430
parents db705749 95ca5495
...@@ -35,6 +35,7 @@ Part 3: NOTHING -> VIEW transitions ...@@ -35,6 +35,7 @@ Part 3: NOTHING -> VIEW transitions
===================================================================== =====================================================================
Part 4: TABLE -> NOTHING transitions Part 4: TABLE -> NOTHING transitions
===================================================================== =====================================================================
# Test 4-a: select ... from <table>
create table t1 (a int); create table t1 (a int);
prepare stmt from "select * from t1"; prepare stmt from "select * from t1";
execute stmt; execute stmt;
...@@ -59,6 +60,32 @@ call p_verify_reprepare_count(0); ...@@ -59,6 +60,32 @@ call p_verify_reprepare_count(0);
SUCCESS SUCCESS
deallocate prepare stmt; 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 Part 5: TABLE -> TABLE (DDL) transitions
===================================================================== =====================================================================
...@@ -192,6 +219,7 @@ SUCCESS ...@@ -192,6 +219,7 @@ SUCCESS
select @message; select @message;
@message @message
new trigger: 11 new trigger: 11
Test 6-e: removing a relevant trigger
drop trigger t1_bi; drop trigger t1_bi;
set @val=12; set @val=12;
execute stmt using @val; execute stmt using @val;
...@@ -338,7 +366,7 @@ SUCCESS ...@@ -338,7 +366,7 @@ SUCCESS
# #
# Sic: the insert went into t3, even though the view now # Sic: the insert went into t3, even though the view now
# points at t2. This is because neither the merged view # 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 # The binary log is of course wrong, since it is not
# using prepared statements # using prepared statements
# #
...@@ -380,7 +408,7 @@ set @var=2; ...@@ -380,7 +408,7 @@ set @var=2;
# Since the dependent table is tracked in the prelocked # Since the dependent table is tracked in the prelocked
# list of the prepared statement, invalidation happens # list of the prepared statement, invalidation happens
# and the statement is re-prepared. This is an unnecessary # 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 # on t2 definition is inside the trigger, and it is currently
# not reprepared (see the previous test case). # not reprepared (see the previous test case).
execute stmt using @var; execute stmt using @var;
...@@ -398,7 +426,7 @@ a comment ...@@ -398,7 +426,7 @@ a comment
drop table t1,t2; drop table t1,t2;
# Test 7-e: dependent TABLE TRIGGER has changed # Test 7-e: dependent TABLE TRIGGER has changed
create table t1 (a int); 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); insert into t2 (a) values (new.a);
create table t2 (a int unique); create table t2 (a int unique);
create trigger t2_ai after insert on t2 for each row create trigger t2_ai after insert on t2 for each row
...@@ -444,6 +472,7 @@ deallocate prepare stmt; ...@@ -444,6 +472,7 @@ deallocate prepare stmt;
===================================================================== =====================================================================
Part 8: TABLE -> TEMPORARY TABLE transitions Part 8: TABLE -> TEMPORARY TABLE transitions
===================================================================== =====================================================================
# Test 8-a: base table used recreated as temporary table
create table t1 (a int); create table t1 (a int);
prepare stmt from "select * from t1"; prepare stmt from "select * from t1";
execute stmt; execute stmt;
...@@ -462,6 +491,37 @@ SUCCESS ...@@ -462,6 +491,37 @@ SUCCESS
drop table t1; drop table t1;
deallocate prepare stmt; 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 Part 9: TABLE -> VIEW transitions
===================================================================== =====================================================================
...@@ -503,6 +563,7 @@ deallocate prepare stmt; ...@@ -503,6 +563,7 @@ deallocate prepare stmt;
===================================================================== =====================================================================
Part 11: TEMPORARY TABLE -> TABLE transitions Part 11: TEMPORARY TABLE -> TABLE transitions
===================================================================== =====================================================================
# Test 11-a: temporary table replaced by base table
create table t1 (a int); create table t1 (a int);
insert into t1 (a) value (1); insert into t1 (a) value (1);
create temporary table t1 (a int); create temporary table t1 (a int);
...@@ -524,6 +585,38 @@ a ...@@ -524,6 +585,38 @@ a
1 1
drop table t1; drop table t1;
deallocate prepare stmt; 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 Part 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions
===================================================================== =====================================================================
...@@ -740,6 +833,7 @@ drop procedure p1; ...@@ -740,6 +833,7 @@ drop procedure p1;
create procedure p1(out x int) select max(a) from t2 into x; create procedure p1(out x int) select max(a) from t2 into x;
# XXX: bug. The prelocked list is not invalidated # XXX: bug. The prelocked list is not invalidated
# and we keep opening table t1, whereas the procedure # and we keep opening table t1, whereas the procedure
# is now referring to table t2
execute stmt; 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 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); call p_verify_reprepare_count(0);
...@@ -1007,7 +1101,7 @@ prepare stmt from "alter table t1 add column b int"; ...@@ -1007,7 +1101,7 @@ prepare stmt from "alter table t1 add column b int";
execute stmt; execute stmt;
drop table t1; drop table t1;
create table t1 (a1 int, a2 int); 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; execute stmt;
alter table t1 drop column b; alter table t1 drop column b;
execute stmt; execute stmt;
...@@ -1030,7 +1124,7 @@ test.t1 repair status OK ...@@ -1030,7 +1124,7 @@ test.t1 repair status OK
drop table t1; drop table t1;
create table t1 (a1 int, a2 int); create table t1 (a1 int, a2 int);
insert into t1 values (1, 10), (2, 20), (3, 30); 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; execute stmt;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 repair status OK test.t1 repair status OK
...@@ -1333,7 +1427,7 @@ insert into t_27430_2 values ...@@ -1333,7 +1427,7 @@ insert into t_27430_2 values
(2, 2), (2, 2),
(1234, 3), (1234, 3),
(1234, 4); (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"; "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;
oref a Z oref a Z
...@@ -1346,7 +1440,7 @@ SUCCESS ...@@ -1346,7 +1440,7 @@ SUCCESS
drop table t_27430_1, t_27430_2; drop table t_27430_1, t_27430_2;
create table t_27430_1 (a int, oref int, key(a)); 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, 1),
(1, NULL), (1, NULL),
(2, 3), (2, 3),
...@@ -1500,14 +1594,14 @@ drop procedure p_12093; ...@@ -1500,14 +1594,14 @@ drop procedure p_12093;
deallocate prepare stmt_sf; deallocate prepare stmt_sf;
deallocate prepare stmt_sp; 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. SQL statement where it is needed.
===================================================================== =====================================================================
drop table if exists t1;
create table t1 (a int);
# #
# SQLCOM_SELECT # 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)"; prepare stmt from "select 1 as res from dual where (1) in (select * from t1)";
drop table t1; drop table t1;
create table t1 (x int); create table t1 (x int);
...@@ -1566,6 +1660,18 @@ call p_verify_reprepare_count(0); ...@@ -1566,6 +1660,18 @@ call p_verify_reprepare_count(0);
SUCCESS SUCCESS
drop table t2; 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; drop table t1;
create table t1 (x varchar(20)); create table t1 (x varchar(20));
execute stmt; execute stmt;
...@@ -1580,13 +1686,25 @@ call p_verify_reprepare_count(0); ...@@ -1580,13 +1686,25 @@ call p_verify_reprepare_count(0);
SUCCESS SUCCESS
drop table t2; 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; drop table t1;
deallocate prepare stmt; deallocate prepare stmt;
# XXX: no validation of the first table in case of # XXX: no validation of the first table in case of
# CREATE TEMPORARY TABLE. This is a shortcoming of the current code, # CREATE TEMPORARY TABLE. This is a shortcoming of the current code,
# but since validation is not strictly necessary, nothing is done # but since validation is not strictly necessary, nothing is done
# about it. # 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" # temporary tables"
create table t1 (a int); create table t1 (a int);
insert into t1 (a) values (1); insert into t1 (a) values (1);
...@@ -1634,6 +1752,56 @@ Note 1050 Table 't2' already exists ...@@ -1634,6 +1752,56 @@ Note 1050 Table 't2' already exists
call p_verify_reprepare_count(0); call p_verify_reprepare_count(0);
SUCCESS 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 t1;
drop table t2; drop table t2;
deallocate prepare stmt; deallocate prepare stmt;
...@@ -1839,11 +2007,11 @@ Variable_name Value ...@@ -1839,11 +2007,11 @@ Variable_name Value
drop table t1; drop table t1;
deallocate prepare stmt; 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 # SQLCOM_SHOW_ENGINE_MUTEX, SQLCOM_SHOW_PROCESSLIST
# #
# Currently can not have a where clause, need to be covered # Currently can not have a where clause, need to be covered
# with tests # with tests
drop table if exists t1; drop table if exists t1;
create table t1 (a int); create table t1 (a int);
prepare stmt from "show engine all status where (1) in (select * from t1)"; prepare stmt from "show engine all status where (1) in (select * from t1)";
...@@ -2035,7 +2203,7 @@ prepare stmt from "alter view v1 as select 2"; ...@@ -2035,7 +2203,7 @@ prepare stmt from "alter view v1 as select 2";
ERROR HY000: This command is not supported in the prepared statement protocol yet ERROR HY000: This command is not supported in the prepared statement protocol yet
drop view v1; drop view v1;
# Cleanup # Cleanup
# #
drop temporary table if exists t1, t2, t3; drop temporary table if exists t1, t2, t3;
drop table if exists t1, t2, t3, v1, v2; drop table if exists t1, t2, t3, v1, v2;
drop procedure if exists p_verify_reprepare_count; drop procedure if exists p_verify_reprepare_count;
......
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(<col>) + 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(<col>) + 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;
...@@ -104,6 +104,7 @@ prepare stmt from "select * from t1"; ...@@ -104,6 +104,7 @@ prepare stmt from "select * from t1";
--echo Part 4: TABLE -> NOTHING transitions --echo Part 4: TABLE -> NOTHING transitions
--echo ===================================================================== --echo =====================================================================
--echo # Test 4-a: select ... from <table>
create table t1 (a int); create table t1 (a int);
prepare stmt from "select * from t1"; prepare stmt from "select * from t1";
...@@ -121,6 +122,25 @@ execute stmt; ...@@ -121,6 +122,25 @@ execute stmt;
call p_verify_reprepare_count(0); call p_verify_reprepare_count(0);
deallocate prepare stmt; 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 =====================================================================
--echo Part 5: TABLE -> TABLE (DDL) transitions --echo Part 5: TABLE -> TABLE (DDL) transitions
--echo ===================================================================== --echo =====================================================================
...@@ -143,11 +163,11 @@ call p_verify_reprepare_count(0); ...@@ -143,11 +163,11 @@ call p_verify_reprepare_count(0);
drop table t1; drop table t1;
deallocate prepare stmt; deallocate prepare stmt;
--echo ===================================================================== --echo =====================================================================
--echo Part 6: TABLE -> TABLE (TRIGGER) transitions --echo Part 6: TABLE -> TABLE (TRIGGER) transitions
--echo ===================================================================== --echo =====================================================================
--echo # Test 6-a: adding a relevant trigger --echo # Test 6-a: adding a relevant trigger
create table t1 (a int); create table t1 (a int);
...@@ -181,7 +201,7 @@ select @message; ...@@ -181,7 +201,7 @@ select @message;
# Unrelated trigger: reprepare may or may not happen, implementation dependent # Unrelated trigger: reprepare may or may not happen, implementation dependent
create trigger t1_bd before delete on t1 for each row create trigger t1_bd before delete on t1 for each row
set @message= old.a; set @message= old.a;
set @val=5; set @val=5;
execute stmt using @val; execute stmt using @val;
call p_verify_reprepare_count(1); call p_verify_reprepare_count(1);
...@@ -229,7 +249,7 @@ execute stmt using @val; ...@@ -229,7 +249,7 @@ execute stmt using @val;
call p_verify_reprepare_count(1); call p_verify_reprepare_count(1);
select @message; select @message;
--ehco Test 6-e: removing a relevant trigger --echo Test 6-e: removing a relevant trigger
drop trigger t1_bi; drop trigger t1_bi;
...@@ -338,7 +358,7 @@ call p_verify_reprepare_count(0); ...@@ -338,7 +358,7 @@ call p_verify_reprepare_count(0);
--echo # --echo #
--echo # Sic: the insert went into t3, even though the view now --echo # Sic: the insert went into t3, even though the view now
--echo # points at t2. This is because neither the merged view --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 # The binary log is of course wrong, since it is not
--echo # using prepared statements --echo # using prepared statements
--echo # --echo #
...@@ -367,7 +387,7 @@ set @var=2; ...@@ -367,7 +387,7 @@ set @var=2;
--echo # Since the dependent table is tracked in the prelocked --echo # Since the dependent table is tracked in the prelocked
--echo # list of the prepared statement, invalidation happens --echo # list of the prepared statement, invalidation happens
--echo # and the statement is re-prepared. This is an unnecessary --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 # on t2 definition is inside the trigger, and it is currently
--echo # not reprepared (see the previous test case). --echo # not reprepared (see the previous test case).
execute stmt using @var; execute stmt using @var;
...@@ -378,7 +398,7 @@ drop table t1,t2; ...@@ -378,7 +398,7 @@ drop table t1,t2;
--echo # Test 7-e: dependent TABLE TRIGGER has changed --echo # Test 7-e: dependent TABLE TRIGGER has changed
create table t1 (a int); 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); insert into t2 (a) values (new.a);
create table t2 (a int unique); create table t2 (a int unique);
create trigger t2_ai after insert on t2 for each row create trigger t2_ai after insert on t2 for each row
...@@ -414,6 +434,7 @@ deallocate prepare stmt; ...@@ -414,6 +434,7 @@ deallocate prepare stmt;
--echo Part 8: TABLE -> TEMPORARY TABLE transitions --echo Part 8: TABLE -> TEMPORARY TABLE transitions
--echo ===================================================================== --echo =====================================================================
--echo # Test 8-a: base table used recreated as temporary table
create table t1 (a int); create table t1 (a int);
prepare stmt from "select * from t1"; prepare stmt from "select * from t1";
...@@ -430,6 +451,25 @@ call p_verify_reprepare_count(0); ...@@ -430,6 +451,25 @@ call p_verify_reprepare_count(0);
drop table t1; drop table t1;
deallocate prepare stmt; 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 =====================================================================
--echo Part 9: TABLE -> VIEW transitions --echo Part 9: TABLE -> VIEW transitions
--echo ===================================================================== --echo =====================================================================
...@@ -471,6 +511,7 @@ deallocate prepare stmt; ...@@ -471,6 +511,7 @@ deallocate prepare stmt;
--echo Part 11: TEMPORARY TABLE -> TABLE transitions --echo Part 11: TEMPORARY TABLE -> TABLE transitions
--echo ===================================================================== --echo =====================================================================
--echo # Test 11-a: temporary table replaced by base table
create table t1 (a int); create table t1 (a int);
insert into t1 (a) value (1); insert into t1 (a) value (1);
create temporary table t1 (a int); create temporary table t1 (a int);
...@@ -488,6 +529,27 @@ select * from t1; ...@@ -488,6 +529,27 @@ select * from t1;
drop table t1; drop table t1;
deallocate prepare stmt; 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 =====================================================================
--echo Part 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions --echo Part 12: TEMPORARY TABLE -> TEMPORARY TABLE (DDL) transitions
--echo ===================================================================== --echo =====================================================================
...@@ -674,7 +736,7 @@ drop procedure p1; ...@@ -674,7 +736,7 @@ drop procedure p1;
create procedure p1(out x int) select max(a) from t2 into x; create procedure p1(out x int) select max(a) from t2 into x;
--echo # XXX: bug. The prelocked list is not invalidated --echo # XXX: bug. The prelocked list is not invalidated
--echo # and we keep opening table t1, whereas the procedure --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 --error ER_VIEW_INVALID
execute stmt; execute stmt;
call p_verify_reprepare_count(0); call p_verify_reprepare_count(0);
...@@ -702,7 +764,7 @@ execute stmt; ...@@ -702,7 +764,7 @@ execute stmt;
call p_verify_reprepare_count(1); call p_verify_reprepare_count(1);
execute stmt; execute stmt;
--echo # Test 18-d: dependent TABLE has changed --echo # Test 18-d: dependent TABLE has changed
drop view v2; drop view v2;
create table v2 as select * from t1; create table v2 as select * from t1;
execute stmt; execute stmt;
call p_verify_reprepare_count(1); call p_verify_reprepare_count(1);
...@@ -854,7 +916,7 @@ execute stmt; ...@@ -854,7 +916,7 @@ execute stmt;
drop table t1; drop table t1;
create table t1 (a1 int, a2 int); 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; execute stmt;
alter table t1 drop column b; alter table t1 drop column b;
...@@ -881,7 +943,7 @@ drop table t1; ...@@ -881,7 +943,7 @@ drop table t1;
create table t1 (a1 int, a2 int); create table t1 (a1 int, a2 int);
insert into t1 values (1, 10), (2, 20), (3, 30); 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; execute stmt;
alter table t1 add column b varchar(50) default NULL; alter table t1 add column b varchar(50) default NULL;
...@@ -1190,16 +1252,16 @@ insert into t_27430_2 values ...@@ -1190,16 +1252,16 @@ insert into t_27430_2 values
(1234, 3), (1234, 3),
(1234, 4); (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"; "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); call p_verify_reprepare_count(0);
drop table t_27430_1, t_27430_2; drop table t_27430_1, t_27430_2;
create table t_27430_1 (a int, oref int, key(a)); 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, 1),
(1, NULL), (1, NULL),
(2, 3), (2, 3),
...@@ -1237,7 +1299,7 @@ insert into t_27690_1 values (1,1),(2,2); ...@@ -1237,7 +1299,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_1 as select * from t_27690_1;
create table v_27690_2 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;
execute stmt; execute stmt;
...@@ -1327,17 +1389,17 @@ drop procedure p_12093_unrelated; ...@@ -1327,17 +1389,17 @@ drop procedure p_12093_unrelated;
connection default; connection default;
--echo # XXX: bug --echo # XXX: bug
--error ER_SP_DOES_NOT_EXIST --error ER_SP_DOES_NOT_EXIST
execute stmt_sf; execute stmt_sf;
--echo # XXX: bug --echo # XXX: bug
--error ER_SP_DOES_NOT_EXIST --error ER_SP_DOES_NOT_EXIST
execute stmt_sp; execute stmt_sp;
--echo # XXX: bug --echo # XXX: bug
--error ER_SP_DOES_NOT_EXIST --error ER_SP_DOES_NOT_EXIST
execute stmt_sf; execute stmt_sf;
--echo # XXX: bug --echo # XXX: bug
--error ER_SP_DOES_NOT_EXIST --error ER_SP_DOES_NOT_EXIST
execute stmt_sp; execute stmt_sp;
call p_verify_reprepare_count(0); call p_verify_reprepare_count(0);
...@@ -1351,16 +1413,18 @@ deallocate prepare stmt_sp; ...@@ -1351,16 +1413,18 @@ deallocate prepare stmt_sp;
--echo ===================================================================== --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 SQL statement where it is needed.
--echo ===================================================================== --echo =====================================================================
--echo #
--echo # SQLCOM_SELECT
--echo #
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
create table t1 (a int); 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)"; prepare stmt from "select 1 as res from dual where (1) in (select * from t1)";
drop table t1; drop table t1;
create table t1 (x int); create table t1 (x int);
...@@ -1368,16 +1432,16 @@ execute stmt; ...@@ -1368,16 +1432,16 @@ execute stmt;
drop table t1; drop table t1;
deallocate prepare stmt; deallocate prepare stmt;
call p_verify_reprepare_count(1); call p_verify_reprepare_count(1);
--echo # --echo #
--echo # SQLCOM_CREATE_TABLE --echo # SQLCOM_CREATE_TABLE
--echo # --echo #
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1;
drop table if exists t2; drop table if exists t2;
--enable_warnings --enable_warnings
create table t1 (a int); create table t1 (a int);
prepare stmt from 'create table t2 as select * from t1'; prepare stmt from 'create table t2 as select * from t1';
execute stmt; execute stmt;
drop table t2; drop table t2;
...@@ -1385,6 +1449,7 @@ execute stmt; ...@@ -1385,6 +1449,7 @@ execute stmt;
drop table t2; drop table t2;
execute stmt; execute stmt;
call p_verify_reprepare_count(0); call p_verify_reprepare_count(0);
# Base table with name of table to be created exists
--error ER_TABLE_EXISTS_ERROR --error ER_TABLE_EXISTS_ERROR
execute stmt; execute stmt;
call p_verify_reprepare_count(1); call p_verify_reprepare_count(1);
...@@ -1392,6 +1457,7 @@ call p_verify_reprepare_count(1); ...@@ -1392,6 +1457,7 @@ call p_verify_reprepare_count(1);
execute stmt; execute stmt;
call p_verify_reprepare_count(0); call p_verify_reprepare_count(0);
drop table t2; drop table t2;
# Temporary table with name of table to be created exists
create temporary table t2 (a int); create temporary table t2 (a int);
--error ER_TABLE_EXISTS_ERROR --error ER_TABLE_EXISTS_ERROR
execute stmt; execute stmt;
...@@ -1406,7 +1472,23 @@ drop table t2; ...@@ -1406,7 +1472,23 @@ drop table t2;
execute stmt; execute stmt;
call p_verify_reprepare_count(0); call p_verify_reprepare_count(0);
drop table t2; 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; drop table t1;
# Table to be used recreated (drop,create) with different layout
create table t1 (x varchar(20)); create table t1 (x varchar(20));
execute stmt; execute stmt;
call p_verify_reprepare_count(1); call p_verify_reprepare_count(1);
...@@ -1415,13 +1497,21 @@ drop table t2; ...@@ -1415,13 +1497,21 @@ drop table t2;
execute stmt; execute stmt;
call p_verify_reprepare_count(0); call p_verify_reprepare_count(0);
drop table t2; 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; drop table t1;
deallocate prepare stmt; deallocate prepare stmt;
--echo # XXX: no validation of the first table in case of --echo # XXX: no validation of the first table in case of
--echo # CREATE TEMPORARY TABLE. This is a shortcoming of the current code, --echo # CREATE TEMPORARY TABLE. This is a shortcoming of the current code,
--echo # but since validation is not strictly necessary, nothing is done --echo # but since validation is not strictly necessary, nothing is done
--echo # about it. --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" --echo # temporary tables"
create table t1 (a int); create table t1 (a int);
insert into t1 (a) values (1); insert into t1 (a) values (1);
...@@ -1445,9 +1535,47 @@ call p_verify_reprepare_count(1); ...@@ -1445,9 +1535,47 @@ call p_verify_reprepare_count(1);
execute stmt; execute stmt;
call p_verify_reprepare_count(0); call p_verify_reprepare_count(0);
drop table t1; 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; drop table t2;
deallocate prepare stmt; deallocate prepare stmt;
--echo # --echo #
--echo # SQLCOM_UPDATE --echo # SQLCOM_UPDATE
--echo # --echo #
...@@ -1697,12 +1825,12 @@ drop table t1; ...@@ -1697,12 +1825,12 @@ drop table t1;
deallocate prepare stmt; deallocate prepare stmt;
--echo # --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 # SQLCOM_SHOW_ENGINE_MUTEX, SQLCOM_SHOW_PROCESSLIST
--echo # --echo #
--echo # Currently can not have a where clause, need to be covered --echo # Currently can not have a where clause, need to be covered
--echo # with tests --echo # with tests
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1;
...@@ -1932,7 +2060,7 @@ prepare stmt from "alter view v1 as select 2"; ...@@ -1932,7 +2060,7 @@ prepare stmt from "alter view v1 as select 2";
drop view v1; drop view v1;
--echo # Cleanup --echo # Cleanup
--echo # --echo #
--disable_warnings --disable_warnings
drop temporary table if exists t1, t2, t3; drop temporary table if exists t1, t2, t3;
drop table if exists t1, t2, t3, v1, v2; drop table if exists t1, t2, t3, v1, v2;
......
#
# Testing the behavior of 'PREPARE', 'DDL', 'EXECUTE' scenarios
#
# There are several subtests which are probably "superfluous" because a DDL
# statement before the EXECUTE <prepared stmt handle> 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)
# {
# <tests to disable>
# }.
# 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(<col>) + 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(<col>) + 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment