summaryrefslogtreecommitdiffstats
path: root/mysql-test/main/sp_validation.result
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/main/sp_validation.result')
-rw-r--r--mysql-test/main/sp_validation.result1996
1 files changed, 1996 insertions, 0 deletions
diff --git a/mysql-test/main/sp_validation.result b/mysql-test/main/sp_validation.result
new file mode 100644
index 00000000..b95e84aa
--- /dev/null
+++ b/mysql-test/main/sp_validation.result
@@ -0,0 +1,1996 @@
+
+#
+# WL#4179: Stored programs: validation of stored program statements.
+#
+
+SET @orig_debug=@@debug_dbug;
+# The test case below demonstrates that meta-data changes are detected
+# by triggers.
+SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT, b INT);
+CREATE TABLE t3 (a INT);
+INSERT INTO t2 VALUES (11, 12), (21, 22);
+CREATE TRIGGER t3_ai AFTER INSERT ON t3 FOR EACH ROW
+INSERT INTO t1 SELECT * FROM t2;
+INSERT INTO t3 (a) VALUES (1);
+SELECT * FROM t1;
+a b
+11 12
+21 22
+SELECT * FROM t2;
+a b
+11 12
+21 22
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+ALTER TABLE t1 ADD COLUMN c INT;
+ALTER TABLE t2 ADD COLUMN c INT;
+INSERT INTO t2 VALUES (31, 32, 33);
+INSERT INTO t3 (a) VALUES (2);
+SELECT * FROM t1;
+a b c
+11 12 NULL
+21 22 NULL
+11 12 NULL
+21 22 NULL
+31 32 33
+SELECT * FROM t2;
+a b c
+11 12 NULL
+21 22 NULL
+31 32 33
+SET @@debug_dbug=@orig_dbug;
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
+# Check that NEW/OLD rows work within triggers.
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1(a) VALUES (1);
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+BEGIN
+SET @a = OLD.a;
+SET @b = NEW.a;
+SELECT OLD.a INTO @c;
+SELECT NEW.a INTO @d;
+SET NEW.a = NEW.a * 2;
+END|
+UPDATE t1 SET a = a * 10;
+SELECT @a, @c, @b, @d;
+@a @c @b @d
+1 1 10 10
+SELECT a FROM t1;
+a
+20
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+CREATE PROCEDURE p1()
+SELECT * FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a
+1
+2
+
+# 1.1 Check if added column into table is recognized correctly
+# in a stored procedure.
+ALTER TABLE t1 ADD COLUMN b INT DEFAULT 0;
+CALL p1();
+a b
+1 0
+2 0
+
+# 1.2 Check if dropped column is not appeared in SELECT query
+# executed inside a stored procedure.
+ALTER TABLE t1 DROP COLUMN a;
+CALL p1();
+b
+0
+0
+
+# 1.3 Check if changed column is picked up properly.
+ALTER TABLE t1 CHANGE COLUMN b b VARCHAR(255) DEFAULT 'n/a';
+DELETE FROM t1;
+INSERT INTO t1 VALUES (b), ('hello');
+CALL p1();
+b
+n/a
+hello
+SET @@debug_dbug=@orig_dbug;
+
+# 1.4 Check if table's recreation is handled correctly
+# inside a call of stored procedure.
+DROP TABLE t1;
+DROP PROCEDURE p1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+CREATE PROCEDURE p1()
+SELECT * FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a
+1
+2
+DROP TABLE t1;
+CALL p1();
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+CALL p1();
+a
+1
+2
+SET @@debug_dbug=@orig_dbug;
+
+# 1.5 Recreate table t1 with another set of columns and
+# re-call a stored procedure.
+DROP TABLE t1;
+DROP PROCEDURE p1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+CREATE PROCEDURE p1()
+SELECT * FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a
+1
+2
+DROP TABLE t1;
+CALL p1();
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (b VARCHAR(10), c VARCHAR(10));
+INSERT INTO t1 VALUES ('a', 'b'), ('c', 'd');
+CALL p1();
+b c
+a b
+c d
+SET @@debug_dbug=@orig_dbug;
+DROP TABLE t1;
+DROP PROCEDURE p1;
+
+# 2.1 Stored program that uses query like 'SELECT * FROM v' must be
+# re-executed successfully if some columns were added into the view
+# definition by ALTER VIEW;
+CREATE VIEW v1 AS SELECT 1, 2, 3;
+CREATE PROCEDURE p1()
+SELECT * FROM v1;
+CALL p1();
+1 2 3
+1 2 3
+ALTER VIEW v1 AS SELECT 1, 2, 3, 4, 5;
+CALL p1();
+1 2 3 4 5
+1 2 3 4 5
+
+# 2.2 Stored program that uses query like 'SELECT * FROM v' must be
+# re-executed successfully if some columns were removed from the view
+# definition by ALTER VIEW;
+ALTER VIEW v1 AS SELECT 1, 5;
+CALL p1();
+1 5
+1 5
+
+# 2.3 Stored program that uses query like 'SELECT * FROM v' must be
+# re-executed successfully if a base table for the view being used was
+# extended by new columns (by ALTER TABLE);
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+DROP VIEW v1;
+CREATE VIEW v1 AS SELECT * FROM t1;
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1()
+SELECT * FROM v1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a b
+1 2
+ALTER TABLE t1 ADD COLUMN c INT DEFAULT 3;
+CALL p1();
+a b
+1 2
+SET @@debug_dbug=@orig_dbug;
+
+# 2.4 Stored program that uses query like 'SELECT * FROM v' must be
+# re-executed successfully if not used columns were removed from the
+# base table of this view (by ALTER TABLE);
+DROP TABLE t1;
+CREATE TABLE t1(a INT, b INT, c INT);
+INSERT INTO t1 VALUES (1, 2, 3);
+DROP VIEW v1;
+CREATE VIEW v1 AS SELECT b, c FROM t1;
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1()
+SELECT * FROM v1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+b c
+2 3
+ALTER TABLE t1 DROP COLUMN a;
+CALL p1();
+b c
+2 3
+ALTER TABLE t1 DROP COLUMN b;
+CALL p1();
+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
+SET @@debug_dbug=@orig_dbug;
+
+# 2.5 Stored program that uses query like 'SELECT * FROM v' must be
+# re-executed successfully if a type of some base table's columns were
+# changed (by ALTER TABLE);
+DROP TABLE t1;
+CREATE TABLE t1(a INT, b INT, c INT);
+INSERT INTO t1 VALUES (1, 2, 3);
+DROP VIEW v1;
+CREATE VIEW v1 AS SELECT b, c FROM t1;
+DROP PROCEDURE p1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CREATE PROCEDURE p1()
+SELECT * FROM v1;
+CALL p1();
+b c
+2 3
+ALTER TABLE t1 CHANGE COLUMN b b VARCHAR(255) DEFAULT 'n/a';
+DELETE FROM t1;
+INSERT INTO t1(a, c) VALUES (10, 30);
+CALL p1();
+b c
+n/a 30
+SET @@debug_dbug=@orig_dbug;
+
+# 2.6 Stored program that uses query like 'SELECT * FROM v' must be
+# re-executed successfully if the view 'v' was dropped and created again
+# with the same definition;
+#
+# 2.7 Stored program that uses query like 'SELECT * FROM v' must be
+# re-executed successfully if the view 'v' was dropped and created again
+# with different, but compatible definition.
+DROP VIEW v1;
+DROP TABLE t1;
+DROP PROCEDURE p1;
+CREATE VIEW v1 AS SELECT 1, 2, 3;
+CREATE PROCEDURE p1()
+SELECT * FROM v1;
+CALL p1();
+1 2 3
+1 2 3
+DROP VIEW v1;
+CALL p1();
+ERROR 42S02: Table 'test.v1' doesn't exist
+CREATE VIEW v1 AS SELECT 4, 5, 6;
+CALL p1();
+4 5 6
+4 5 6
+
+# 2.8 Stored program that uses query like 'SELECT * FROM v' must be
+# re-executed successfully if the view base tables have been re-created
+# using the same or compatible definition.
+DROP VIEW v1;
+DROP PROCEDURE p1;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE PROCEDURE p1()
+SELECT * FROM v1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a b
+1 2
+DROP TABLE t1;
+CALL p1();
+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
+CREATE TABLE t1(a VARCHAR(255), b VARCHAR(255));
+INSERT INTO t1 VALUES ('a', 'b'), ('c', 'd');
+CALL p1();
+a b
+a b
+c d
+SET @@debug_dbug=@orig_dbug;
+DROP VIEW v1;
+DROP TABLE t1;
+DROP PROCEDURE p1;
+
+# 3.1 Stored program that uses query like 'SELECT * FROM t' must be
+# re-executed successfully if some columns were added into temporary table
+# table 't' (by ALTER TABLE);
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1() SELECT * FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a b
+1 2
+ALTER TABLE t1 ADD COLUMN c INT DEFAULT 3;
+CALL p1();
+a b c
+1 2 3
+
+# 3.2 Stored program that uses query like 'SELECT * FROM t' must be
+# re-executed successfully if some columns were removed from temporary
+# table 't' (by ALTER TABLE);
+ALTER TABLE t1 DROP COLUMN a;
+CALL p1();
+b c
+2 3
+
+# 3.3 Stored program that uses query like 'SELECT * FROM t' must be
+# re-executed successfully if a type of some temporary table's columns were
+# changed (by ALTER TABLE);
+ALTER TABLE t1 CHANGE COLUMN b b VARCHAR(255) DEFAULT 'n/a';
+INSERT INTO t1(c) VALUES (4);
+CALL p1();
+b c
+2 3
+n/a 4
+
+# 3.4 Stored program that uses query like 'SELECT * FROM t' must be
+# re-executed successfully if the temporary table 't' was dropped and
+# created again with the same definition;
+#
+# 3.5 Stored program that uses query like 'SELECT * FROM t' must be
+# re-executed successfully if the temporary table 't' was dropped and
+# created again with different, but compatible definition.
+DROP TEMPORARY TABLE t1;
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CALL p1();
+a b
+1 2
+DROP TEMPORARY TABLE t1;
+CREATE TEMPORARY TABLE t1(a VARCHAR(255), b VARCHAR(255), c VARCHAR(255));
+INSERT INTO t1 VALUES ('aa', 'bb', 'cc');
+CALL p1();
+a b c
+aa bb cc
+SET @@debug_dbug=@orig_dbug;
+DROP TEMPORARY TABLE t1;
+DROP PROCEDURE p1;
+
+# 4.1 Stored program must fail when it is re-executed after a table's column
+# that this program is referenced to has been removed;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1() SELECT a, b FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a b
+1 2
+ALTER TABLE t1 DROP COLUMN b;
+CALL p1();
+ERROR 42S22: Unknown column 'b' in 'field list'
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+# 4.2 Stored program must fail when it is re-executed after a temporary
+# table's column that this program is referenced to has been removed;
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1() SELECT a, b FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a b
+1 2
+ALTER TABLE t1 DROP COLUMN b;
+CALL p1();
+ERROR 42S22: Unknown column 'b' in 'field list'
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP TEMPORARY TABLE t1;
+
+# 4.3 Stored program must fail when it is re-executed after a view's
+# column that this program is referenced to has been removed;
+CREATE VIEW v1 AS SELECT 1 AS a, 2 AS b;
+CREATE PROCEDURE p1() SELECT a, b FROM v1;
+CALL p1();
+a b
+1 2
+ALTER VIEW v1 AS SELECT 1 AS a;
+CALL p1();
+ERROR 42S22: Unknown column 'b' in 'field list'
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP VIEW v1;
+
+# 4.4 Stored program must fail when it is re-executed after a regular table
+# that this program referenced to was removed;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1() SELECT a, b FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a b
+1 2
+DROP TABLE t1;
+CALL p1();
+ERROR 42S02: Table 'test.t1' doesn't exist
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+
+# 4.5 Stored program must fail when it is re-executed after a view that
+# this program referenced to was removed;
+CREATE VIEW v1 AS SELECT 1 AS a, 2 AS b;
+CREATE PROCEDURE p1() SELECT a, b FROM v1;
+CALL p1();
+a b
+1 2
+DROP VIEW v1;
+CALL p1();
+ERROR 42S02: Table 'test.v1' doesn't exist
+DROP PROCEDURE p1;
+
+# 4.6 Stored program must fail when it is re-executed after a temporary
+# table that this program referenced to was removed;
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1() SELECT a, b FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a b
+1 2
+DROP TABLE t1;
+CALL p1();
+ERROR 42S02: Table 'test.t1' doesn't exist
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+
+# 4.7 Stored program must fail if the program executes some
+# SQL-statement and afterwards re-executes it again when some table 't'
+# referenced by the statement was dropped in the period between statement
+# execution;
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(a INT);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE CONTINUE HANDLER FOR 1146
+SELECT 'Table t1 does not exist anymore' as msg;
+SELECT * FROM t1;
+INSERT INTO t2 VALUES (1);
+SELECT GET_LOCK('m1', 10000);
+SELECT * FROM t1;
+END|
+
+# -- connection: con1
+connect con1, localhost, root;
+SELECT GET_LOCK('m1', 0);
+GET_LOCK('m1', 0)
+1
+
+# -- connection: default
+connection default;
+CALL p1();
+
+# -- connection: con1
+connection con1;
+DROP TABLE t1;
+SELECT RELEASE_LOCK('m1');
+RELEASE_LOCK('m1')
+1
+
+# -- connection: default
+connection default;
+a
+GET_LOCK('m1', 10000)
+1
+msg
+Table t1 does not exist anymore
+disconnect con1;
+DROP TABLE t2;
+DROP PROCEDURE p1;
+
+# 5.1 Regular table -> View
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1() SELECT * FROM t1;
+CALL p1();
+a b
+1 2
+DROP TABLE t1;
+CREATE VIEW t1 AS SELECT 1 AS a, 2 AS b;
+CALL p1();
+a b
+1 2
+DROP PROCEDURE p1;
+DROP VIEW t1;
+
+# 5.2 Regular table -> Temporary table
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1() SELECT * FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a b
+1 2
+DROP TABLE t1;
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CALL p1();
+a b
+1 2
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP TEMPORARY TABLE t1;
+
+# 5.3 View -> Regular table
+CREATE VIEW t1 AS SELECT 1 AS a, 2 AS b;
+CREATE PROCEDURE p1() SELECT * FROM t1;
+CALL p1();
+a b
+1 2
+DROP VIEW t1;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CALL p1();
+a b
+1 2
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+# 5.4 View -> Temporary table
+CREATE VIEW t1 AS SELECT 1 AS a, 2 AS b;
+CREATE PROCEDURE p1() SELECT * FROM t1;
+CALL p1();
+a b
+1 2
+DROP VIEW t1;
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CALL p1();
+a b
+1 2
+DROP PROCEDURE p1;
+DROP TEMPORARY TABLE t1;
+
+# 5.5 Temporary table -> View
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1() SELECT * FROM t1;
+CALL p1();
+a b
+1 2
+DROP TEMPORARY TABLE t1;
+CREATE VIEW t1 AS SELECT 1 AS a, 2 AS b;
+CALL p1();
+a b
+1 2
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP VIEW t1;
+
+# 5.6 Temporary table -> Regular table
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1() SELECT * FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a b
+1 2
+DROP TEMPORARY TABLE t1;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CALL p1();
+a b
+1 2
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+# 6.1 Trigger that uses column 'a' of table 't' via pseudo-variable NEW
+# must be re-executed successfully if the table definition has been changed
+# in a compatible way. "Compatible way" in this case is that if the table
+# 't' still has a column named 'a' and the column type is compatible with
+# the operation that NEW.a takes part of.
+#
+# 6.2 Trigger that uses column 'a' of table 't' via pseudo-variable OLD
+# must be re-executed successfully if the table definition has been changed
+# in a compatible way. "Compatible way" in this case is that if the table
+# 't' still has a column named 'a' and the column type is compatible with
+# the operation that OLD.a takes part of.
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+BEGIN
+SET @x = OLD.a;
+SET @y = NEW.a;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+SET @x = 0, @y = 0;
+UPDATE t1 SET a = 3, b = 4;
+SELECT @x, @y;
+@x @y
+1 3
+
+ALTER TABLE t1 ADD COLUMN c INT DEFAULT -1;
+
+SET @x = 0, @y = 0;
+UPDATE t1 SET a = 5, b = 6;
+SELECT @x, @y;
+@x @y
+3 5
+
+ALTER TABLE t1 CHANGE COLUMN a a VARCHAR(255);
+
+SET @x = 0, @y = 0;
+UPDATE t1 SET a = CONCAT('xxx_', a), b = 7;
+SELECT @x, @y;
+@x @y
+5 xxx_5
+SET @@debug_dbug=@orig_dbug;
+
+DROP TABLE t1;
+
+# 6.3 Re-execution of a trigger that uses column 'a' of table 't' via
+# pseudo-variable NEW must fail if the table definition has been changed in
+# the way that the column 'a' does not exist anymore.
+#
+# 6.4 Re-execution of a trigger that uses column 'a' of table 't' via
+# pseudo-variable OLD must fail if the table definition has been changed in
+# the way that the column 'a' does not exist anymore.
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+BEGIN
+SET @x = OLD.a;
+SET @y = NEW.b;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+UPDATE t1 SET a = 3, b = 4;
+
+ALTER TABLE t1 CHANGE COLUMN a a2 INT;
+
+UPDATE t1 SET a2 = 5, b = 6;
+ERROR 42S22: Unknown column 'a' in 'OLD'
+
+ALTER TABLE t1 CHANGE COLUMN a2 a INT;
+ALTER TABLE t1 CHANGE COLUMN b b2 INT;
+
+UPDATE t1 SET a = 5, b2 = 6;
+ERROR 42S22: Unknown column 'b' in 'NEW'
+SET @@debug_dbug=@orig_dbug;
+
+DROP TABLE t1;
+
+# 7.1 Setup:
+# - stored program 'a', which alters regular table 't' in a compatible
+# way;
+# - stored program 'b', which calls 'a' and uses 't' before and after the
+# call;
+# Stored program 'b' must be executed successfully.
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1()
+ALTER TABLE t1 ADD COLUMN c INT DEFAULT 3|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT a, b FROM t1;
+CALL p1();
+SELECT a, b FROM t1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p2();
+a b
+1 2
+a b
+1 2
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
+
+# 7.2 Setup:
+# - stored program 'a', which alters temporary table 't' in a compatible
+# way;
+# - stored program 'b', which calls 'a' and uses 't' before and after the
+# call;
+# Stored program 'b' must be executed successfully.
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1()
+ALTER TABLE t1 ADD COLUMN c INT DEFAULT 3|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT a, b FROM t1;
+CALL p1();
+SELECT a, b FROM t1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p2();
+a b
+1 2
+a b
+1 2
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TEMPORARY TABLE t1;
+
+# 7.3 Setup:
+# - stored program 'a', which re-creates regular table 't' in a
+# compatible way;
+# - stored program 'b', which calls 'a' and uses 't' before and after the
+# call;
+# Stored program 'b' must be executed successfully.
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1()
+BEGIN
+DROP TABLE t1;
+CREATE TABLE t1(a INT, b INT, c INT);
+INSERT INTO t1 VALUES (1, 2, 3);
+END|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT a, b FROM t1;
+CALL p1();
+SELECT a, b FROM t1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p2();
+a b
+1 2
+a b
+1 2
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
+
+# 7.4 Setup:
+# - stored program 'a', which re-creates temporary table 't' in a
+# compatible way;
+# - stored program 'b', which calls 'a' and uses 't' before and after the
+# call;
+# Stored program 'b' must be executed successfully.
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1()
+BEGIN
+DROP TEMPORARY TABLE t1;
+CREATE TEMPORARY TABLE t1(a INT, b INT, c INT);
+INSERT INTO t1 VALUES (1, 2, 3);
+END|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT a, b FROM t1;
+CALL p1();
+SELECT a, b FROM t1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p2();
+a b
+1 2
+a b
+1 2
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TEMPORARY TABLE t1;
+
+# 7.5 Setup:
+# - stored program 'a', which re-creates view 'v' in a compatible way;
+# - stored program 'b', which calls 'a' and uses 'v' before and after the
+# call;
+# Stored program 'b' must be executed successfully.
+CREATE VIEW v1 AS SELECT 1 AS a, 2 AS b;
+CREATE PROCEDURE p1()
+BEGIN
+DROP VIEW v1;
+CREATE VIEW v1 AS SELECT 1 AS a, 2 AS b, 3 AS c;
+END|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT a, b FROM v1;
+CALL p1();
+SELECT a, b FROM v1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p2();
+a b
+1 2
+a b
+1 2
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP VIEW v1;
+
+# 7.6 Setup:
+# - stored program 'a', which alters regular table 't' in an incompatible
+# way;
+# - stored program 'b', which calls 'a' and uses 't' before and after the
+# call;
+# Stored program 'b' must fail on access to the table after its
+# modification.
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1()
+ALTER TABLE t1 DROP COLUMN a|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT a, b FROM t1;
+CALL p1();
+SELECT a, b FROM t1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p2();
+a b
+1 2
+ERROR 42S22: Unknown column 'a' in 'field list'
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
+
+# 7.7 Setup:
+# - stored program 'a', which alters temporary table 't' in an
+# incompatible way;
+# - stored program 'b', which calls 'a' and uses 't' before and after the
+# call;
+# Stored program 'b' must fail on access to the table after its
+# modification.
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1()
+ALTER TABLE t1 DROP COLUMN a|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT a, b FROM t1;
+CALL p1();
+SELECT a, b FROM t1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p2();
+a b
+1 2
+ERROR 42S22: Unknown column 'a' in 'field list'
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TEMPORARY TABLE t1;
+
+# 7.8 Setup:
+# - stored program 'a', which re-creates regular table 't' in an
+# incompatible way;
+# - stored program 'b', which calls 'a' and uses 't' before and after the
+# call;
+# Stored program 'b' must fail on access to the table after its
+# modification.
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1()
+BEGIN
+DROP TABLE t1;
+CREATE TABLE t1(b INT, c INT);
+INSERT INTO t1 VALUES (2, 3);
+END|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT a, b FROM t1;
+CALL p1();
+SELECT a, b FROM t1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p2();
+a b
+1 2
+ERROR 42S22: Unknown column 'a' in 'field list'
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
+
+# 7.9 Setup:
+# - stored program 'a', which re-creates temporary table 't' in an
+# incompatible way;
+# - stored program 'b', which calls 'a' and uses 't' before and after the
+# call;
+# Stored program 'b' must fail on access to the table after its
+# modification.
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+CREATE PROCEDURE p1()
+BEGIN
+DROP TEMPORARY TABLE t1;
+CREATE TEMPORARY TABLE t1(b INT, c INT);
+INSERT INTO t1 VALUES (2, 3);
+END|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT a, b FROM t1;
+CALL p1();
+SELECT a, b FROM t1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p2();
+a b
+1 2
+ERROR 42S22: Unknown column 'a' in 'field list'
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TEMPORARY TABLE t1;
+
+# 7.10 Setup:
+# - stored program 'a', which re-creates view 'v' in an incompatible way;
+# - stored program 'b', which calls 'a' and uses 'v' before and after the
+# call;
+# Stored program 'b' must fail on access to the view after its
+# modification.
+CREATE VIEW v1 AS SELECT 1 AS a, 2 AS b;
+CREATE PROCEDURE p1()
+BEGIN
+DROP VIEW v1;
+CREATE VIEW v1 AS SELECT 2 AS b, 3 AS c;
+END|
+CREATE PROCEDURE p2()
+BEGIN
+SELECT a, b FROM v1;
+CALL p1();
+SELECT a, b FROM v1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p2();
+a b
+1 2
+ERROR 42S22: Unknown column 'a' in 'field list'
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP VIEW v1;
+# 8. Stored program must be executed successfully when:
+# a. the program uses a table/view/temporary table that doesn't exist
+# at the time of start program execution
+# b. failed reference to the missed table/view/temporary table handled
+# by stored program
+# c. this table/view/temporary table is created as part of the
+# program execution
+# d. stored program gets access to newly created table/view/temporary
+# table from some SQL-statement during subsequent stored program execution.
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+SELECT 'SQLEXCEPTION caught' AS msg;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+END;
+SELECT * FROM t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+END|
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+SELECT 'SQLEXCEPTION caught' AS msg;
+CREATE TEMPORARY TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1, 2);
+END;
+SELECT * FROM t1;
+SELECT * FROM t1;
+DROP TEMPORARY TABLE t1;
+END|
+CREATE PROCEDURE p3()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+SELECT 'SQLEXCEPTION caught' AS msg;
+CREATE VIEW v1 AS SELECT 1 AS a, 2 AS b;
+END;
+SELECT * FROM v1;
+SELECT * FROM v1;
+DROP VIEW v1;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+msg
+SQLEXCEPTION caught
+a b
+1 2
+CALL p2();
+msg
+SQLEXCEPTION caught
+a b
+1 2
+CALL p3();
+msg
+SQLEXCEPTION caught
+a b
+1 2
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+
+# 9. Stored program must be executed successfully when
+# - the stored program has an expression in one of the following
+# statements
+# - RETURN
+# - IF
+# - CASE
+# - WHILE
+# - UNTIL
+# - SET
+# - the expression depends on the meta-data of some table/view/temporary table;
+# - the meta-data of dependent object has changed in a compatible way.
+#
+# Note, that CASE-expression must be evaluated once even if (some)
+# CASE-expressions need to be re-parsed.
+#
+# 10. Subsequent executions of a stored program must fail when
+# - the stored program has an expression in one of the following
+# statements
+# - RETURN
+# - IF
+# - CASE
+# - WHILE
+# - UNTIL
+# - SET
+# - the expression depends on the meta-data of some table/view/temporary table;
+# - the meta-data of dependent object has changed in a non-compatible way.
+#
+# Note, that CASE-expression must be evaluated once even if (some)
+# CASE-expressions need to be re-parsed.
+
+# Check IF-statement.
+
+CREATE PROCEDURE p1()
+BEGIN
+IF(SELECT * FROM t1)THEN
+SELECT 1;
+ELSE
+SELECT 2;
+END IF;
+END|
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE v INT DEFAULT 1;
+IF v * (SELECT * FROM t1) THEN
+SELECT 1;
+ELSE
+SELECT 2;
+END IF;
+END|
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+IF (SELECT * FROM t1) THEN
+RETURN 1;
+ELSE
+RETURN 2;
+END IF;
+RETURN 3;
+END|
+CREATE FUNCTION f2() RETURNS INT
+BEGIN
+DECLARE v INT DEFAULT 1;
+IF v * (SELECT * FROM t1) THEN
+RETURN 1;
+ELSE
+RETURN 2;
+END IF;
+RETURN 3;
+END|
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1);
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p1();
+1
+1
+CALL p2();
+1
+1
+SELECT f1();
+f1()
+1
+SELECT f2();
+f2()
+1
+
+UPDATE t1 SET a = 0;
+
+CALL p1();
+2
+2
+CALL p2();
+2
+2
+SELECT f1();
+f1()
+2
+SELECT f2();
+f2()
+2
+
+ALTER TABLE t1 ADD COLUMN b INT DEFAULT 1;
+
+CALL p1();
+ERROR 21000: Operand should contain 1 column(s)
+CALL p2();
+ERROR HY000: Illegal parameter data types int and row for operation '*'
+SELECT f1();
+ERROR 21000: Operand should contain 1 column(s)
+SELECT f2();
+ERROR HY000: Illegal parameter data types int and row for operation '*'
+
+ALTER TABLE t1 DROP COLUMN a;
+
+CALL p1();
+1
+1
+CALL p2();
+1
+1
+SELECT f1();
+f1()
+1
+SELECT f2();
+f2()
+1
+
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP FUNCTION f1;
+DROP FUNCTION f2;
+DROP TABLE t1;
+
+# Check WHILE-statement.
+
+CREATE PROCEDURE p1(x INT)
+BEGIN
+WHILE(SELECT * FROM t1)DO
+SELECT x;
+UPDATE t1 SET a = x;
+SET x = x - 1;
+END WHILE;
+END|
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0);
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1(3);
+UPDATE t1 SET a = 1;
+CALL p1(3);
+x
+3
+x
+2
+x
+1
+x
+0
+UPDATE t1 SET a = 1;
+ALTER TABLE t1 ADD COLUMN b INT DEFAULT 1;
+CALL p1(3);
+ERROR 21000: Operand should contain 1 column(s)
+ALTER TABLE t1 DROP COLUMN a;
+CALL p1(3);
+x
+3
+ERROR 42S22: Unknown column 'a' in 'field list'
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+# Check REPEAT-statement.
+
+CREATE PROCEDURE p1(x INT)
+BEGIN
+REPEAT
+SELECT x;
+UPDATE t1 SET a = x;
+SET x = x - 1;
+UNTIL(NOT (SELECT * FROM t1))END REPEAT;
+END|
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0);
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1(3);
+x
+3
+x
+2
+x
+1
+x
+0
+UPDATE t1 SET a = 1;
+CALL p1(3);
+x
+3
+x
+2
+x
+1
+x
+0
+UPDATE t1 SET a = 1;
+ALTER TABLE t1 ADD COLUMN b INT DEFAULT 1;
+CALL p1(3);
+x
+3
+ERROR 21000: Operand should contain 1 column(s)
+ALTER TABLE t1 DROP COLUMN a;
+CALL p1(3);
+x
+3
+ERROR 42S22: Unknown column 'a' in 'field list'
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+# Check CASE-statement (round #1).
+
+CREATE PROCEDURE p1()
+BEGIN
+CASE
+WHEN (SELECT * FROM t1) = 1 THEN SELECT 'a1';
+WHEN (SELECT * FROM t1) = 2 THEN SELECT 'a2';
+WHEN (SELECT * FROM t1) = 3 THEN SELECT 'a3';
+ELSE SELECT 'a4';
+END CASE;
+END|
+CREATE PROCEDURE p2()
+BEGIN
+CASE (SELECT * FROM t1)
+WHEN 1 THEN SELECT 'a1';
+WHEN 2 THEN SELECT 'a2';
+WHEN 3 THEN SELECT 'a3';
+ELSE SELECT 'a4';
+END CASE;
+END|
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0);
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p1();
+a4
+a4
+CALL p2();
+a4
+a4
+
+UPDATE t1 SET a = 3;
+
+CALL p1();
+a3
+a3
+CALL p2();
+a3
+a3
+
+ALTER TABLE t1 ADD COLUMN b INT DEFAULT 2;
+
+CALL p1();
+ERROR HY000: Illegal parameter data types row and int for operation '='
+CALL p2();
+ERROR 21000: Operand should contain 1 column(s)
+
+ALTER TABLE t1 DROP COLUMN a;
+
+CALL p1();
+a2
+a2
+CALL p2();
+a2
+a2
+SET @@debug_dbug=@orig_dbug;
+
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
+
+# Check CASE-statement (round #2).
+#
+# Check that CASE-expression is executed once even if the metadata, used
+# in a WHEN-expression, have changed.
+
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(a INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+SET @x = @x + 1;
+RETURN (SELECT a FROM t1);
+END|
+CREATE PROCEDURE p1()
+BEGIN
+CASE f1()
+WHEN 1 THEN SELECT 'a1';
+WHEN 2 THEN SELECT 'a2';
+WHEN (SELECT * FROM t2) THEN SELECT 'subselect';
+ELSE SELECT 'else';
+END CASE;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+SET @x = 0;
+CALL p1();
+a1
+a1
+SELECT @x;
+@x
+1
+
+UPDATE t1 SET a = 3;
+ALTER TABLE t2 ADD COLUMN b INT DEFAULT 3;
+
+SET @x = 0;
+CALL p1();
+ERROR HY000: Illegal parameter data types int and row for operation '='
+SELECT @x;
+@x
+1
+
+ALTER TABLE t2 DROP COLUMN a;
+
+SET @x = 0;
+CALL p1();
+subselect
+subselect
+SELECT @x;
+@x
+1
+SET @@debug_dbug=@orig_dbug;
+
+DROP PROCEDURE p1;
+DROP FUNCTION f1;
+DROP TABLE t1;
+DROP TABLE t2;
+
+# Check DEFAULT clause.
+#
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE v INT DEFAULT (SELECT * FROM t1);
+SELECT v;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p1();
+v
+1
+
+ALTER TABLE t1 ADD COLUMN b INT DEFAULT 2;
+
+CALL p1();
+ERROR HY000: Cannot cast 'row' as 'int' in assignment of `v`
+
+ALTER TABLE t1 DROP COLUMN a;
+
+CALL p1();
+v
+2
+SET @@debug_dbug=@orig_dbug;
+
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+# Check SET.
+#
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2(a INT);
+INSERT INTO t2 VALUES (1);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE x INT;
+SET x = (SELECT * FROM t1);
+SELECT x;
+END|
+CREATE PROCEDURE p2()
+BEGIN
+SET @x = NULL;
+SET @x = (SELECT * FROM t1);
+SELECT @x;
+END|
+CREATE TRIGGER t2_bu BEFORE UPDATE ON t2 FOR EACH ROW
+BEGIN
+SET NEW.a = (SELECT * FROM t1) * 2;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p1();
+x
+1
+
+CALL p2();
+@x
+1
+
+UPDATE t2 SET a = 10;
+
+ALTER TABLE t1 ADD COLUMN b INT DEFAULT 2;
+
+CALL p1();
+ERROR HY000: Cannot cast 'row' as 'int' in assignment of `x`
+
+CALL p2();
+ERROR 21000: Operand should contain 1 column(s)
+
+UPDATE t2 SET a = 20;
+ERROR HY000: Illegal parameter data types row and int for operation '*'
+
+ALTER TABLE t1 DROP COLUMN a;
+
+CALL p1();
+x
+2
+
+CALL p2();
+@x
+2
+
+UPDATE t2 SET a = 30;
+SET @@debug_dbug=@orig_dbug;
+
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
+DROP TABLE t2;
+
+# 11.1 If metadata of the objects (regular tables, temporary tables,
+# views), used in SELECT-statement changed between DECLARE CURSOR and
+# OPEN statements, the SELECT-statement should be re-parsed to use
+# up-to-date metadata.
+
+
+# - Regular table.
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE v INT;
+DECLARE c CURSOR FOR SELECT * FROM t1;
+ALTER TABLE t1 ADD COLUMN b INT DEFAULT 2;
+ALTER TABLE t1 DROP COLUMN a;
+OPEN c;
+FETCH c INTO v;
+CLOSE c;
+SELECT v;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p1();
+v
+2
+SET @@debug_dbug=@orig_dbug;
+
+DROP TABLE t1;
+DROP PROCEDURE p1;
+
+# - Temporary table.
+
+CREATE TEMPORARY TABLE t1(a INT);
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE v INT;
+DECLARE c CURSOR FOR SELECT * FROM t1;
+ALTER TABLE t1 ADD COLUMN b INT DEFAULT 2;
+ALTER TABLE t1 DROP COLUMN a;
+OPEN c;
+FETCH c INTO v;
+CLOSE c;
+SELECT v;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p1();
+v
+2
+SET @@debug_dbug=@orig_dbug;
+
+DROP TEMPORARY TABLE t1;
+DROP PROCEDURE p1;
+
+# 11.2 If the metadata changed between OPEN and FETCH or CLOSE
+# statements, those changes should not be noticed.
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE v INT;
+DECLARE c CURSOR FOR SELECT * FROM t1;
+OPEN c;
+ALTER TABLE t1 ADD COLUMN b INT DEFAULT 2;
+ALTER TABLE t1 DROP COLUMN a;
+FETCH c INTO v;
+CLOSE c;
+SELECT v;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p1();
+v
+1
+SET @@debug_dbug=@orig_dbug;
+
+DROP TABLE t1;
+DROP PROCEDURE p1;
+
+# 11.3 Re-parsing of the SELECT-statement should be made correctly
+# (in the correct parsing context) if the metadata changed between
+# DECLARE CURSOR and OPEN statements, and those statements reside in different
+# parsing contexts.
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE f1 INT;
+DECLARE f2 INT;
+DECLARE f3 INT;
+DECLARE x INT DEFAULT 1;
+DECLARE y INT DEFAULT 2;
+DECLARE c CURSOR FOR SELECT x, y, t1.a FROM t1;
+ALTER TABLE t1 ADD COLUMN b INT;
+BEGIN
+DECLARE x INT DEFAULT 10;
+DECLARE y INT DEFAULT 20;
+OPEN c;
+FETCH c INTO f1, f2, f3;
+SELECT f1, f2, f3;
+CLOSE c;
+END;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+CALL p1();
+f1 f2 f3
+1 2 1
+SET @@debug_dbug=@orig_dbug;
+
+DROP TABLE t1;
+DROP PROCEDURE p1;
+
+# Test procedure behaviour after view recreation.
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE PROCEDURE p1()
+SELECT * FROM v1;
+CALL p1();
+a
+1
+2
+# Alter underlying table and recreate the view.
+ALTER TABLE t1 ADD COLUMN (b INT);
+ALTER VIEW v1 AS SELECT * FROM t1;
+# And check whether the call of stored procedure handles it correctly.
+CALL p1();
+a b
+1 NULL
+2 NULL
+DROP VIEW v1;
+DROP TABLE t1;
+DROP PROCEDURE p1;
+# Test if metadata changes for temporary table is handled
+# correctly inside a stored procedure.
+CREATE TEMPORARY TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+CREATE PROCEDURE p1()
+SELECT * FROM t1;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1();
+a
+1
+2
+# Test if added temporary table's column is recognized during
+# procedure invocation.
+ALTER TABLE t1 ADD COLUMN (b INT);
+CALL p1();
+a b
+1 NULL
+2 NULL
+# Test if dropped temporary table's column is not appeared
+# in procedure's result.
+ALTER TABLE t1 DROP COLUMN a;
+CALL p1();
+b
+NULL
+NULL
+SET @@debug_dbug=@orig_dbug;
+DROP PROCEDURE p1;
+DROP TABLE t1;
+# Test handle of metadata changes with stored function.
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+CREATE TEMPORARY TABLE t1_result_set AS SELECT * FROM t1;
+RETURN 0;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+SELECT f1();
+f1()
+0
+SELECT * FROM t1_result_set;
+a
+1
+2
+DROP TABLE t1_result_set;
+# Check if added column is noticed by invocation of stored function.
+ALTER TABLE t1 ADD COLUMN (b INT);
+SELECT f1();
+f1()
+0
+SELECT * FROM t1_result_set;
+a b
+1 NULL
+2 NULL
+DROP TABLE t1_result_set;
+# Check if dropped column is noticed by invocation of stored function.
+ALTER TABLE t1 DROP COLUMN a;
+SELECT f1();
+f1()
+0
+SELECT * FROM t1_result_set;
+b
+NULL
+NULL
+SET @@debug_dbug=@orig_dbug;
+DROP TABLE t1_result_set;
+DROP TABLE t1;
+DROP FUNCTION f1;
+# Test if table's recreation is handled correctly
+# inside a stored function.
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+CREATE TEMPORARY TABLE t1_result_set AS SELECT * FROM t1;
+RETURN 0;
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+SELECT f1();
+f1()
+0
+SELECT * FROM t1_result_set;
+a
+1
+2
+DROP TABLE t1_result_set;
+# Recreate table and check if it is handled correctly
+# by function invocation.
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+SELECT f1();
+f1()
+0
+SELECT * FROM t1_result_set;
+a
+1
+2
+SET @@debug_dbug=@orig_dbug;
+DROP TABLE t1_result_set;
+DROP FUNCTION f1;
+DROP TABLE t1;
+# Test if changes in the view's metadata is handled
+# correctly by function call.
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+CREATE TEMPORARY TABLE t1_result_set AS SELECT * FROM v1;
+RETURN 0;
+END|
+SELECT f1();
+f1()
+0
+SELECT * FROM t1_result_set;
+a
+1
+2
+DROP TABLE t1_result_set;
+ALTER TABLE t1 ADD COLUMN (b INT);
+ALTER VIEW v1 AS SELECT * FROM t1;
+SELECT f1();
+f1()
+0
+SELECT * FROM t1_result_set;
+a b
+1 NULL
+2 NULL
+DROP TABLE t1_result_set;
+DROP TABLE t1;
+DROP VIEW v1;
+DROP FUNCTION f1;
+# Check if queried object's type substitution (table->view, view->table,
+# table->temp table, etc.) is handled correctly during invocation of
+# stored function/procedure.
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+CREATE TEMPORARY TABLE t1_result_set AS SELECT * FROM t1;
+RETURN 0;
+END|
+CREATE PROCEDURE p1()
+SELECT * FROM t1|
+CALL p1();
+a
+1
+2
+SELECT f1();
+f1()
+0
+SELECT * FROM t1_result_set;
+a
+1
+2
+DROP TABLE t1_result_set;
+DROP TABLE t1;
+CREATE TEMPORARY TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+CALL p1;
+a
+1
+2
+SELECT f1();
+f1()
+0
+SELECT * FROM t1_result_set;
+a
+1
+2
+DROP TABLE t1_result_set;
+SET @@debug_dbug=@orig_dbug;
+DROP TABLE t1;
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 VALUES (1), (2);
+CREATE VIEW t1 AS SELECT * FROM t2;
+CALL p1;
+a
+1
+2
+SELECT f1();
+f1()
+0
+SELECT * FROM t1_result_set;
+a
+1
+2
+DROP TABLE t1_result_set;
+DROP TABLE t2;
+DROP VIEW t1;
+DROP FUNCTION f1;
+DROP PROCEDURE p1;
+# Test handle of metadata changes with triggers.
+CREATE TABLE t1 (a INT);
+CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
+SET new.a = new.a + 100;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+INSERT INTO t1 VALUES (1), (2);
+SELECT * FROM t1;
+a
+101
+102
+# Check if added table's column is handled correctly inside trigger.
+ALTER TABLE t1 ADD COLUMN (b INT);
+INSERT INTO t1 VALUES (3, 4);
+SELECT * FROM t1;
+a b
+101 NULL
+102 NULL
+103 4
+SET @@debug_dbug=@orig_dbug;
+DROP TRIGGER trg1;
+DROP TABLE t1;
+# Test if deleted column is handled correctly by trigger invocation.
+CREATE TABLE t1 (a INT, b INT);
+CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
+SET new.a = new.a + 100;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+INSERT INTO t1 VALUES (1, 2), (3, 4);
+SELECT * FROM t1;
+a b
+101 2
+103 4
+ALTER TABLE t1 DROP COLUMN b;
+INSERT INTO t1 VALUES (5);
+SELECT * FROM t1;
+a
+101
+103
+105
+SET @@debug_dbug=@orig_dbug;
+DROP TRIGGER trg1;
+DROP TABLE t1;
+# Check if server returns and error when was dropped a column
+# that is used inside a trigger body.
+CREATE TABLE t1 (a INT, b INT);
+CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
+SET new.a = new.a + 100;
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+INSERT INTO t1 VALUES (1, 2), (3, 4);
+SELECT * FROM t1;
+a b
+101 2
+103 4
+ALTER TABLE t1 DROP COLUMN a;
+INSERT INTO t1 VALUES (5);
+ERROR 42S22: Unknown column 'a' in 'NEW'
+SET @@debug_dbug=@orig_dbug;
+DROP TRIGGER trg1;
+DROP TABLE t1;
+
+# Check updateable views inside triggers.
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2(a INT);
+INSERT INTO t2 VALUES (1);
+CREATE VIEW v1 AS SELECT a FROM t1;
+CREATE TRIGGER t2_bu BEFORE UPDATE ON t2 FOR EACH ROW
+BEGIN
+INSERT INTO v1 VALUES (NEW.a);
+SET @x = (SELECT CHARSET(a) FROM v1 LIMIT 1);
+END|
+SET @@debug_dbug='+d,check_sp_cache_not_invalidated';
+
+SET @x = NULL;
+UPDATE t2 SET a = 10;
+SELECT * FROM v1;
+a
+1
+10
+SELECT @x;
+@x
+binary
+
+ALTER TABLE t1 CHANGE COLUMN a a CHAR(2);
+
+SET @x = NULL;
+UPDATE t2 SET a = 20;
+SELECT * FROM v1;
+a
+1
+10
+20
+SELECT @x;
+@x
+latin1
+SET @@debug_dbug=@orig_dbug;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP VIEW v1;
+#
+# MDEV-31661: Assertion `thd->lex == sp_instr_lex' failed in LEX* sp_lex_instr::parse_expr(THD*, sp_head*, LEX*)
+#
+CREATE OR REPLACE PROCEDURE p1()
+BEGIN
+DECLARE c CURSOR FOR SELECT * FROM t1;
+OPEN c;
+CLOSE c;
+END;
+$
+CALL p1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (id INT);
+CALL p1;
+# Second execution of the stored procedure p1() after the dependent
+# table t1 has been created resulted in assert failure for server built
+# with debug
+CALL p1;
+# Clean up
+DROP PROCEDURE p1;
+DROP TABLE t1;
+#
+# MDEV-31799 Unexpected ER_TRG_NO_SUCH_ROW_IN_TRG and server crash after ALTER TABLE
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+CREATE TABLE t2 (b INT);
+# Check that AFTER DELETE trigger is re-compiled on changing table's metadata
+CREATE TRIGGER tr AFTER DELETE ON t1 FOR EACH ROW INSERT INTO t2 (b) VALUES (OLD.a);
+DELETE FROM t1 LIMIT 1;
+SELECT * FROM t2;
+b
+1
+ALTER TABLE t2 FORCE;
+DELETE FROM t1 LIMIT 1;
+SELECT * FROM t2;
+b
+1
+2
+DELETE FROM t1 LIMIT 1;
+SELECT * FROM t2;
+b
+1
+2
+3
+DROP TRIGGER tr;
+# Check that AFTER UPDATE trigger is re-compiled on changing table's metadata
+CREATE TRIGGER tr AFTER UPDATE ON t1 FOR EACH ROW INSERT INTO t2 (b) VALUES (OLD.a);
+# Remove records interted by AFTER DELETE trogger
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET a = 2;
+# Above statement should insert the row (1) into the table t2
+# Expected output contains one row: (1)
+SELECT * FROM t2;
+b
+1
+ALTER TABLE t2 FORCE;
+# The following statement should insert the row (2) into the table t2
+UPDATE t1 SET a = 3;
+# Expected output contains two rows: (1), (2)
+SELECT * FROM t2;
+b
+1
+2
+# The following statement should insert the row (3) into the table t2
+UPDATE t1 SET a = 5;
+# Expected output contains three rows: (1), (2), (3)
+SELECT * FROM t2;
+b
+1
+2
+3
+DROP TABLE t1, t2;
+#
+# MDEV-33525: Recreate/reuse temporary table
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1);
+CREATE FUNCTION f1()
+RETURNS INT
+BEGIN
+DECLARE res INT;
+DECLARE t1_cur CURSOR FOR SELECT 100 FROM t1, t1_tmp;
+CREATE TEMPORARY TABLE t1_tmp SELECT 1 a;
+OPEN t1_cur;
+CLOSE t1_cur;
+DROP TEMPORARY TABLE t1_tmp;
+RETURN 0;
+END
+|
+SELECT f1();
+f1()
+0
+# Without the patch, the second call of f1 would result in error:
+# ER_NO_SUCH_TABLE (1146): Table 'test.t1' doesn't exist
+SELECT f1();
+f1()
+0
+# Clean up
+DROP FUNCTION f1;
+DROP TABLE t1;
+SET sql_mode = default;