summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-06-08 11:45:28 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-06-08 11:45:28 +0300
commit57022dfb25b931a329905364d7056ac61950d300 (patch)
tree94a7131bfffa205d89a8563a5c749f843b920ecb
parenteb14e073ea121954fb5be6fac92fd84b7d57bb07 (diff)
parentbefb0bed68b555852e01859a846bf7ac40f15dbb (diff)
downloadmariadb-git-57022dfb25b931a329905364d7056ac61950d300.tar.gz
Merge 10.3 into 10.4
-rw-r--r--mysql-test/main/cte_recursive.result170
-rw-r--r--mysql-test/main/cte_recursive.test70
-rw-r--r--mysql-test/suite/compat/oracle/r/parser.result34
-rw-r--r--mysql-test/suite/compat/oracle/t/parser.test47
-rw-r--r--mysql-test/suite/sql_sequence/alter.result11
-rw-r--r--mysql-test/suite/sql_sequence/alter.test21
-rw-r--r--mysql-test/suite/sql_sequence/create.result34
-rw-r--r--mysql-test/suite/sql_sequence/create.test42
-rw-r--r--sql/sql_cte.cc1
-rw-r--r--sql/sql_derived.cc7
-rw-r--r--sql/sql_sequence.cc13
-rw-r--r--sql/sql_union.cc13
-rw-r--r--sql/sql_yacc_ora.yy4
-rw-r--r--storage/innobase/srv/srv0srv.cc4
-rw-r--r--storage/innobase/srv/srv0start.cc2
15 files changed, 454 insertions, 19 deletions
diff --git a/mysql-test/main/cte_recursive.result b/mysql-test/main/cte_recursive.result
index 8cb14e8d2da..7ed8a30136a 100644
--- a/mysql-test/main/cte_recursive.result
+++ b/mysql-test/main/cte_recursive.result
@@ -691,13 +691,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
1 PRIMARY <derived3> ref key0 key0 5 c.h_id 2 100.00
1 PRIMARY <derived3> ref key0 key0 5 c.w_id 2 100.00
-2 DERIVED <derived3> ALL NULL NULL NULL NULL 12 100.00 Using where
3 DERIVED folks ALL NULL NULL NULL NULL 12 100.00 Using where
4 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
4 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
5 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
5 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union3,4,5> ALL NULL NULL NULL NULL NULL NULL
+2 DERIVED <derived3> ALL NULL NULL NULL NULL 12 100.00 Using where
Warnings:
Note 1003 with recursive ancestor_couple_ids(h_id,w_id) as (/* select#2 */ select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where `a`.`father` is not null and `a`.`mother` is not null), coupled_ancestors(id,name,dob,father,mother) as (/* select#3 */ select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' union all /* select#4 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where `test`.`p`.`id` = `fa`.`h_id` union all /* select#5 */ select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where `test`.`p`.`id` = `ma`.`w_id`)/* select#1 */ select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where `h`.`id` = `c`.`h_id` and `w`.`id` = `c`.`w_id`
# simple mutual recursion
@@ -1302,12 +1302,12 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 24
4 DERIVED folks ALL NULL NULL NULL NULL 12 Using where
6 RECURSIVE UNION <derived3> ALL NULL NULL NULL NULL 12
+5 RECURSIVE UNION <derived4> ALL NULL NULL NULL NULL 24
+NULL UNION RESULT <union4,6,5> ALL NULL NULL NULL NULL NULL
3 DERIVED folks ALL NULL NULL NULL NULL 12 Using where
2 RECURSIVE UNION folks ALL PRIMARY NULL NULL NULL 12
2 RECURSIVE UNION <derived3> ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union3,2> ALL NULL NULL NULL NULL NULL
-5 RECURSIVE UNION <derived4> ALL NULL NULL NULL NULL 24
-NULL UNION RESULT <union4,6,5> ALL NULL NULL NULL NULL NULL
explain FORMAT=JSON
with recursive
prev_gen
@@ -3370,13 +3370,13 @@ select * from cte1, cte2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 6 100.00
1 PRIMARY <derived5> ALL NULL NULL NULL NULL 6 100.00 Using join buffer (flat, BNL join)
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
4 DERIVED <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
4 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
5 DERIVED <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
5 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
-2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
-3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 with recursive rcte(a) as (/* select#2 */ select 1 AS `a` union /* select#3 */ select cast(`rcte`.`a` + 1 as unsigned) AS `cast(a+1 as unsigned)` from `rcte` where `rcte`.`a` < 10), cte1 as (/* select#4 */ select count(0) AS `c1` from `rcte` join `test`.`t1` where `rcte`.`a` between 3 and 5 and `test`.`t1`.`id` = `rcte`.`a` - 3), cte2 as (/* select#5 */ select count(0) AS `c2` from `rcte` join `test`.`t1` where `rcte`.`a` between 7 and 8 and `test`.`t1`.`id` = `rcte`.`a` - 7)/* select#1 */ select `cte1`.`c1` AS `c1`,`cte2`.`c2` AS `c2` from `cte1` join `cte2`
prepare stmt from "with recursive
@@ -3435,6 +3435,65 @@ cte2 as
(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7)
select * from cte1, cte2 where cte1.c1 = 3;
c1 c2
+with recursive
+rcte(a) as
+(select 1 union select cast(a+1 as unsigned) from rcte where a < 10),
+cte1 as
+(select count(*) as c1 from rcte,t1 where a between 3 and 5 and id=a-3),
+cte2 as
+(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7)
+select * from cte2, cte1;
+c2 c1
+1 2
+explain extended with recursive
+rcte(a) as
+(select 1 union select cast(a+1 as unsigned) from rcte where a < 10),
+cte1 as
+(select count(*) as c1 from rcte,t1 where a between 3 and 5 and id=a-3),
+cte2 as
+(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7)
+select * from cte2, cte1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived5> ALL NULL NULL NULL NULL 6 100.00
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL 6 100.00 Using join buffer (flat, BNL join)
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+5 DERIVED <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
+5 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+4 DERIVED <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
+4 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 with recursive rcte(a) as (/* select#2 */ select 1 AS `a` union /* select#3 */ select cast(`rcte`.`a` + 1 as unsigned) AS `cast(a+1 as unsigned)` from `rcte` where `rcte`.`a` < 10), cte1 as (/* select#4 */ select count(0) AS `c1` from `rcte` join `test`.`t1` where `rcte`.`a` between 3 and 5 and `test`.`t1`.`id` = `rcte`.`a` - 3), cte2 as (/* select#5 */ select count(0) AS `c2` from `rcte` join `test`.`t1` where `rcte`.`a` between 7 and 8 and `test`.`t1`.`id` = `rcte`.`a` - 7)/* select#1 */ select `cte2`.`c2` AS `c2`,`cte1`.`c1` AS `c1` from `cte2` join `cte1`
+prepare stmt from "with recursive
+rcte(a) as
+(select 1 union select cast(a+1 as unsigned) from rcte where a < 10),
+cte1 as
+(select count(*) as c1 from rcte,t1 where a between 3 and 5 and id=a-3),
+cte2 as
+(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7)
+select * from cte2, cte1";
+execute stmt;
+c2 c1
+1 2
+execute stmt;
+c2 c1
+1 2
+drop procedure p;
+drop table t2;
+create table t2 (c1 int, c2 int);
+create procedure p() insert into t2 with recursive
+rcte(a) as
+(select 1 union select cast(a+1 as unsigned) from rcte where a < 10),
+cte1 as
+(select count(*) as c1 from rcte,t1 where a between 3 and 5 and id=a-3),
+cte2 as
+(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7)
+select * from cte2, cte1;
+call p();
+select * from t2;
+c1 c2
+1 2
drop procedure p;
drop table t1,t2;
#
@@ -3853,7 +3912,104 @@ ANALYZE
}
drop function f1;
drop table t1,t2;
-End of 10.2 tests
+#
+# MDEV-22748: two materialized CTEs using the same recursive CTE
+# (see also test case for MDEV-17024)
+#
+CREATE TABLE t1 (YEAR int(4), d1 date , d2 date) ;
+INSERT INTO t1 VALUES (2018,'2018-01-01','2018-09-20');
+CREATE TABLE t2 (id int, tm date);
+INSERT INTO t2 VALUES (1,'2018-08-30'),(2,'2018-08-30'),(3,'2018-08-30');
+CREATE TABLE t3 (id int, tm date);
+INSERT INTO t3 VALUES (1,'2018-08-30'),(2,'2018-08-30');
+WITH RECURSIVE
+cte AS
+(SELECT YEAR(t1.d1) AS YEAR, t1.d1 AS st, t1.d1 + INTERVAL 1 MONTH AS fn
+FROM t1
+UNION ALL
+SELECT YEAR(cte.st + INTERVAL 1 MONTH),
+cte.st + INTERVAL 1 MONTH, t1.d2 + INTERVAL 1 DAY
+FROM cte JOIN t1
+WHERE cte.st + INTERVAL 1 MONTH < t1.d2 ),
+cte2 AS (SELECT YEAR, COUNT(*)
+FROM cte JOIN t2 ON t2.tm BETWEEN cte.st AND cte.fn),
+cte3 AS (SELECT YEAR, COUNT(*)
+FROM cte JOIN t3 ON t3.tm BETWEEN cte.st AND cte.fn)
+SELECT t1.* FROM t1 JOIN cte2 USING (YEAR) JOIN cte3 USING (YEAR);
+YEAR d1 d2
+2018 2018-01-01 2018-09-20
+EXPLAIN EXTENDED WITH RECURSIVE
+cte AS
+(SELECT YEAR(t1.d1) AS YEAR, t1.d1 AS st, t1.d1 + INTERVAL 1 MONTH AS fn
+FROM t1
+UNION ALL
+SELECT YEAR(cte.st + INTERVAL 1 MONTH),
+cte.st + INTERVAL 1 MONTH, t1.d2 + INTERVAL 1 DAY
+FROM cte JOIN t1
+WHERE cte.st + INTERVAL 1 MONTH < t1.d2 ),
+cte2 AS (SELECT YEAR, COUNT(*)
+FROM cte JOIN t2 ON t2.tm BETWEEN cte.st AND cte.fn),
+cte3 AS (SELECT YEAR, COUNT(*)
+FROM cte JOIN t3 ON t3.tm BETWEEN cte.st AND cte.fn)
+SELECT t1.* FROM t1 JOIN cte2 USING (YEAR) JOIN cte3 USING (YEAR);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY <derived5> ref key0 key0 5 const 0 0.00
+1 PRIMARY <derived4> ref key0 key0 5 const 0 0.00
+2 DERIVED t1 system NULL NULL NULL NULL 1 100.00
+3 RECURSIVE UNION t1 system NULL NULL NULL NULL 1 100.00
+3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+4 DERIVED <derived2> ALL NULL NULL NULL NULL 2 100.00
+4 DERIVED t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+5 DERIVED <derived2> ALL NULL NULL NULL NULL 2 100.00
+5 DERIVED t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 with recursive cte as (/* select#2 */ select year(`test`.`t1`.`d1`) AS `YEAR`,`test`.`t1`.`d1` AS `st`,`test`.`t1`.`d1` + interval 1 month AS `fn` from `test`.`t1` union all /* select#3 */ select year(`cte`.`st` + interval 1 month) AS `YEAR(cte.st + INTERVAL 1 MONTH)`,`cte`.`st` + interval 1 month AS `cte.st + INTERVAL 1 MONTH`,`test`.`t1`.`d2` + interval 1 day AS `t1.d2 + INTERVAL 1 DAY` from `cte` join `test`.`t1` where `cte`.`st` + interval 1 month < `test`.`t1`.`d2`), cte2 as (/* select#4 */ select `cte`.`YEAR` AS `YEAR`,count(0) AS `COUNT(*)` from `cte` join `test`.`t2` where `test`.`t2`.`tm` between `cte`.`st` and `cte`.`fn`), cte3 as (/* select#5 */ select `cte`.`YEAR` AS `YEAR`,count(0) AS `COUNT(*)` from `cte` join `test`.`t3` where `test`.`t3`.`tm` between `cte`.`st` and `cte`.`fn`)/* select#1 */ select 2018 AS `YEAR`,'2018-01-01' AS `d1`,'2018-09-20' AS `d2` from `cte2` join `cte3` where `cte3`.`YEAR` = 2018 and `cte2`.`YEAR` = 2018
+PREPARE stmt FROM "WITH RECURSIVE
+cte AS
+(SELECT YEAR(t1.d1) AS YEAR, t1.d1 AS st, t1.d1 + INTERVAL 1 MONTH AS fn
+FROM t1
+UNION ALL
+SELECT YEAR(cte.st + INTERVAL 1 MONTH),
+cte.st + INTERVAL 1 MONTH, t1.d2 + INTERVAL 1 DAY
+FROM cte JOIN t1
+WHERE cte.st + INTERVAL 1 MONTH < t1.d2 ),
+cte2 AS (SELECT YEAR, COUNT(*)
+FROM cte JOIN t2 ON t2.tm BETWEEN cte.st AND cte.fn),
+cte3 AS (SELECT YEAR, COUNT(*)
+FROM cte JOIN t3 ON t3.tm BETWEEN cte.st AND cte.fn)
+SELECT t1.* FROM t1 JOIN cte2 USING (YEAR) JOIN cte3 USING (YEAR)";
+EXECUTE stmt;
+YEAR d1 d2
+2018 2018-01-01 2018-09-20
+EXECUTE stmt;
+YEAR d1 d2
+2018 2018-01-01 2018-09-20
+CREATE TABLE t4 (YEAR int(4), d1 date , d2 date);
+CREATE PROCEDURE p() INSERT INTO t4 WITH RECURSIVE
+cte AS
+(SELECT YEAR(t1.d1) AS YEAR, t1.d1 AS st, t1.d1 + INTERVAL 1 MONTH AS fn
+FROM t1
+UNION ALL
+SELECT YEAR(cte.st + INTERVAL 1 MONTH),
+cte.st + INTERVAL 1 MONTH, t1.d2 + INTERVAL 1 DAY
+FROM cte JOIN t1
+WHERE cte.st + INTERVAL 1 MONTH < t1.d2 ),
+cte2 AS (SELECT YEAR, COUNT(*)
+FROM cte JOIN t2 ON t2.tm BETWEEN cte.st AND cte.fn),
+cte3 AS (SELECT YEAR, COUNT(*)
+FROM cte JOIN t3 ON t3.tm BETWEEN cte.st AND cte.fn)
+SELECT t1.* FROM t1 JOIN cte2 USING (YEAR) JOIN cte3 USING (YEAR);
+CALL p();
+SELECT * FROM t4;
+YEAR d1 d2
+2018 2018-01-01 2018-09-20
+DROP PROCEDURE p;
+DROP TABLE t1,t2,t3,t4;
+#
+# End of 10.2 tests
+#
#
# MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
#
diff --git a/mysql-test/main/cte_recursive.test b/mysql-test/main/cte_recursive.test
index a134c4bd8f2..94da45b91ea 100644
--- a/mysql-test/main/cte_recursive.test
+++ b/mysql-test/main/cte_recursive.test
@@ -2424,6 +2424,30 @@ select * from cte1, cte2 where cte1.c1 = 3;
eval $q3;
+let $q4=
+with recursive
+rcte(a) as
+(select 1 union select cast(a+1 as unsigned) from rcte where a < 10),
+cte1 as
+(select count(*) as c1 from rcte,t1 where a between 3 and 5 and id=a-3),
+cte2 as
+(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7)
+select * from cte2, cte1;
+
+eval $q4;
+eval explain extended $q4;
+eval prepare stmt from "$q4";
+execute stmt;
+execute stmt;
+
+drop procedure p;
+drop table t2;
+
+create table t2 (c1 int, c2 int);
+eval create procedure p() insert into t2 $q4;
+call p();
+select * from t2;
+
drop procedure p;
drop table t1,t2;
@@ -2609,7 +2633,51 @@ eval analyze format=json $q;
drop function f1;
drop table t1,t2;
---echo End of 10.2 tests
+--echo #
+--echo # MDEV-22748: two materialized CTEs using the same recursive CTE
+--echo # (see also test case for MDEV-17024)
+--echo #
+
+CREATE TABLE t1 (YEAR int(4), d1 date , d2 date) ;
+INSERT INTO t1 VALUES (2018,'2018-01-01','2018-09-20');
+CREATE TABLE t2 (id int, tm date);
+INSERT INTO t2 VALUES (1,'2018-08-30'),(2,'2018-08-30'),(3,'2018-08-30');
+CREATE TABLE t3 (id int, tm date);
+INSERT INTO t3 VALUES (1,'2018-08-30'),(2,'2018-08-30');
+
+let $q=
+WITH RECURSIVE
+cte AS
+ (SELECT YEAR(t1.d1) AS YEAR, t1.d1 AS st, t1.d1 + INTERVAL 1 MONTH AS fn
+ FROM t1
+ UNION ALL
+ SELECT YEAR(cte.st + INTERVAL 1 MONTH),
+ cte.st + INTERVAL 1 MONTH, t1.d2 + INTERVAL 1 DAY
+ FROM cte JOIN t1
+ WHERE cte.st + INTERVAL 1 MONTH < t1.d2 ),
+cte2 AS (SELECT YEAR, COUNT(*)
+ FROM cte JOIN t2 ON t2.tm BETWEEN cte.st AND cte.fn),
+cte3 AS (SELECT YEAR, COUNT(*)
+ FROM cte JOIN t3 ON t3.tm BETWEEN cte.st AND cte.fn)
+SELECT t1.* FROM t1 JOIN cte2 USING (YEAR) JOIN cte3 USING (YEAR);
+
+eval $q;
+eval EXPLAIN EXTENDED $q;
+eval PREPARE stmt FROM "$q";
+EXECUTE stmt;
+EXECUTE stmt;
+
+CREATE TABLE t4 (YEAR int(4), d1 date , d2 date);
+eval CREATE PROCEDURE p() INSERT INTO t4 $q;
+CALL p();
+SELECT * FROM t4;
+
+DROP PROCEDURE p;
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
--echo #
--echo # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
diff --git a/mysql-test/suite/compat/oracle/r/parser.result b/mysql-test/suite/compat/oracle/r/parser.result
index 1c60c1434a3..0b573027c6d 100644
--- a/mysql-test/suite/compat/oracle/r/parser.result
+++ b/mysql-test/suite/compat/oracle/r/parser.result
@@ -607,5 +607,39 @@ ERROR HY000: Unknown system variable 'password'
SELECT @@GLOBAL.role;
ERROR HY000: Unknown system variable 'role'
#
+# MDEV-22822 sql_mode="oracle" cannot declare without variable errors
+#
+# It's OK to have no declarations between DECLARE and BEGIN.
+#
+BEGIN
+DECLARE
+BEGIN
+NULL;
+END;
+EXCEPTION
+WHEN OTHERS THEN
+NULL;
+END;
+//
+DECLARE
+BEGIN
+NULL;
+EXCEPTION
+WHEN OTHERS THEN
+NULL;
+END;
+//
+BEGIN
+<<lab>>
+DECLARE
+BEGIN
+NULL;
+END;
+EXCEPTION
+WHEN OTHERS THEN
+NULL;
+END;
+//
+#
# End of 10.3 tests
#
diff --git a/mysql-test/suite/compat/oracle/t/parser.test b/mysql-test/suite/compat/oracle/t/parser.test
index 067fd9beb48..4d558c5d153 100644
--- a/mysql-test/suite/compat/oracle/t/parser.test
+++ b/mysql-test/suite/compat/oracle/t/parser.test
@@ -410,5 +410,52 @@ SELECT @@GLOBAL.role;
--echo #
+--echo # MDEV-22822 sql_mode="oracle" cannot declare without variable errors
+--echo #
+--echo # It's OK to have no declarations between DECLARE and BEGIN.
+--echo #
+
+DELIMITER //;
+BEGIN
+ DECLARE
+ BEGIN
+ NULL;
+ END;
+EXCEPTION
+WHEN OTHERS THEN
+ NULL;
+END;
+//
+DELIMITER ;//
+
+
+DELIMITER //;
+DECLARE
+BEGIN
+ NULL;
+EXCEPTION
+WHEN OTHERS THEN
+ NULL;
+END;
+//
+DELIMITER ;//
+
+
+DELIMITER //;
+BEGIN
+<<lab>>
+ DECLARE
+ BEGIN
+ NULL;
+ END;
+EXCEPTION
+WHEN OTHERS THEN
+ NULL;
+END;
+//
+DELIMITER ;//
+
+
+--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/mysql-test/suite/sql_sequence/alter.result b/mysql-test/suite/sql_sequence/alter.result
index 3cf085bc948..612e2201d26 100644
--- a/mysql-test/suite/sql_sequence/alter.result
+++ b/mysql-test/suite/sql_sequence/alter.result
@@ -238,3 +238,14 @@ select next value for t1;
next value for t1
90
drop sequence t1;
+CREATE SEQUENCE t1 engine=innodb;
+ALTER IGNORE TABLE t1 ADD CHECK (start_value < minimum_value);
+ERROR HY000: Sequence 'test.t1' table structure is invalid (Sequence tables cannot have any constraints)
+DROP SEQUENCE t1;
+CREATE SEQUENCE s;
+ALTER TABLE s ORDER BY cache_size;
+ERROR HY000: Sequence 'test.s' table structure is invalid (ORDER BY)
+SELECT NEXTVAL(s);
+NEXTVAL(s)
+1
+DROP SEQUENCE s;
diff --git a/mysql-test/suite/sql_sequence/alter.test b/mysql-test/suite/sql_sequence/alter.test
index fd1809ccd2f..53f71018337 100644
--- a/mysql-test/suite/sql_sequence/alter.test
+++ b/mysql-test/suite/sql_sequence/alter.test
@@ -139,3 +139,24 @@ select next value for t1;
alter sequence t1 restart with 90;
select next value for t1;
drop sequence t1;
+
+#
+# MDEV-19977 Assertion `(0xFUL & mode) == LOCK_S || (0xFUL & mode) == LOCK_X'
+# failed in lock_rec_lock
+#
+
+CREATE SEQUENCE t1 engine=innodb;
+--error ER_SEQUENCE_INVALID_TABLE_STRUCTURE
+ALTER IGNORE TABLE t1 ADD CHECK (start_value < minimum_value);
+DROP SEQUENCE t1;
+
+#
+# MDEV-19320 Sequence gets corrupted and produces ER_KEY_NOT_FOUND (Can't
+# find record) after ALTER .. ORDER BY
+#
+
+CREATE SEQUENCE s;
+--error ER_SEQUENCE_INVALID_TABLE_STRUCTURE
+ALTER TABLE s ORDER BY cache_size;
+SELECT NEXTVAL(s);
+DROP SEQUENCE s;
diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result
index 55d45a75abf..14464c60e99 100644
--- a/mysql-test/suite/sql_sequence/create.result
+++ b/mysql-test/suite/sql_sequence/create.result
@@ -375,6 +375,40 @@ CREATE OR REPLACE TABLE t1 (
key key1 (next_not_cached_value)
) sequence=1;
ERROR HY000: Sequence 'test.t1' table structure is invalid (Sequence tables cannot have any keys)
+CREATE TABLE t1 (
+`next_not_cached_value` bigint(21) NOT NULL,
+`minimum_value` bigint(21) NOT NULL,
+`maximum_value` bigint(21) NOT NULL,
+`start_value` bigint(21) NOT NULL,
+`increment` bigint(21) NOT NULL,
+`cache_size` bigint(21) unsigned NOT NULL,
+`cycle_option` tinyint(1) unsigned NOT NULL,
+`cycle_count` bigint(21) NOT NULL,
+CHECK (start_value < minimum_value)
+) sequence=1;
+ERROR HY000: Sequence 'test.t1' table structure is invalid (Sequence tables cannot have any constraints)
+CREATE TABLE t1 (
+`next_not_cached_value` bigint(21) NOT NULL,
+`minimum_value` bigint(21) NOT NULL,
+`maximum_value` bigint(21) NOT NULL,
+`start_value` bigint(21) NOT NULL CHECK (start_value < minimum_value),
+`increment` bigint(21) NOT NULL,
+`cache_size` bigint(21) unsigned NOT NULL,
+`cycle_option` tinyint(1) unsigned NOT NULL,
+`cycle_count` bigint(21) NOT NULL
+) sequence=1;
+ERROR HY000: Sequence 'test.t1' table structure is invalid (start_value)
+CREATE TABLE t1 (
+`next_not_cached_value` bigint(21) NOT NULL,
+`minimum_value` bigint(21) NOT NULL,
+`maximum_value` bigint(21) NOT NULL,
+`start_value` bigint(21) NOT NULL,
+`increment` bigint(21) NOT NULL,
+`cache_size` bigint(21) unsigned NOT NULL,
+`cycle_option` tinyint(1) unsigned NOT NULL,
+`cycle_count` bigint(21) generated always as (1) virtual
+) sequence=1;
+ERROR HY000: Sequence 'test.t1' table structure is invalid (cycle_count)
drop sequence if exists t1;
Warnings:
Note 4091 Unknown SEQUENCE: 'test.t1'
diff --git a/mysql-test/suite/sql_sequence/create.test b/mysql-test/suite/sql_sequence/create.test
index 1bc62117526..2c41fb3658b 100644
--- a/mysql-test/suite/sql_sequence/create.test
+++ b/mysql-test/suite/sql_sequence/create.test
@@ -270,6 +270,48 @@ CREATE OR REPLACE TABLE t1 (
key key1 (next_not_cached_value)
) sequence=1;
+# Check constraint
+
+--error ER_SEQUENCE_INVALID_TABLE_STRUCTURE
+CREATE TABLE t1 (
+ `next_not_cached_value` bigint(21) NOT NULL,
+ `minimum_value` bigint(21) NOT NULL,
+ `maximum_value` bigint(21) NOT NULL,
+ `start_value` bigint(21) NOT NULL,
+ `increment` bigint(21) NOT NULL,
+ `cache_size` bigint(21) unsigned NOT NULL,
+ `cycle_option` tinyint(1) unsigned NOT NULL,
+ `cycle_count` bigint(21) NOT NULL,
+ CHECK (start_value < minimum_value)
+) sequence=1;
+
+--error ER_SEQUENCE_INVALID_TABLE_STRUCTURE
+CREATE TABLE t1 (
+ `next_not_cached_value` bigint(21) NOT NULL,
+ `minimum_value` bigint(21) NOT NULL,
+ `maximum_value` bigint(21) NOT NULL,
+ `start_value` bigint(21) NOT NULL CHECK (start_value < minimum_value),
+ `increment` bigint(21) NOT NULL,
+ `cache_size` bigint(21) unsigned NOT NULL,
+ `cycle_option` tinyint(1) unsigned NOT NULL,
+ `cycle_count` bigint(21) NOT NULL
+) sequence=1;
+
+
+# Virtual field
+
+--error ER_SEQUENCE_INVALID_TABLE_STRUCTURE
+CREATE TABLE t1 (
+ `next_not_cached_value` bigint(21) NOT NULL,
+ `minimum_value` bigint(21) NOT NULL,
+ `maximum_value` bigint(21) NOT NULL,
+ `start_value` bigint(21) NOT NULL,
+ `increment` bigint(21) NOT NULL,
+ `cache_size` bigint(21) unsigned NOT NULL,
+ `cycle_option` tinyint(1) unsigned NOT NULL,
+ `cycle_count` bigint(21) generated always as (1) virtual
+) sequence=1;
+
drop sequence if exists t1;
#
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index e452196a271..d4b6d815118 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -1123,6 +1123,7 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
{
derived= with_elem->spec;
if (derived != select_lex->master_unit() &&
+ !with_elem->is_recursive &&
!is_with_table_recursive_reference())
{
derived->move_as_slave(select_lex);
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 8396fd89433..3b312225937 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2002, 2011, Oracle and/or its affiliates.
- Copyright (c) 2010, 2015, MariaDB
+ Copyright (c) 2010, 2020, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1197,7 +1197,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
DBUG_ASSERT(derived->table && derived->table->is_created());
select_unit *derived_result= derived->derived_result;
SELECT_LEX *save_current_select= lex->current_select;
- bool derived_recursive_is_filled= false;
if (derived->pushdown_derived)
{
@@ -1238,7 +1237,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
{
/* In this case all iteration are performed */
res= derived->fill_recursive(thd);
- derived_recursive_is_filled= true;
}
}
else if (unit->is_unit_op())
@@ -1294,8 +1292,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
}
}
err:
- if (res || (!lex->describe && !unit->uncacheable &&
- (!derived_is_recursive || derived_recursive_is_filled)))
+ if (res || (!derived_is_recursive && !lex->describe && !unit->uncacheable))
unit->cleanup();
lex->current_select= save_current_select;
diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc
index 0b73f3ef629..91959f85e64 100644
--- a/sql/sql_sequence.cc
+++ b/sql/sql_sequence.cc
@@ -203,6 +203,16 @@ bool check_sequence_fields(LEX *lex, List<Create_field> *fields)
reason= "Sequence tables cannot have any keys";
goto err;
}
+ if (lex->alter_info.check_constraint_list.elements > 0)
+ {
+ reason= "Sequence tables cannot have any constraints";
+ goto err;
+ }
+ if (lex->alter_info.flags & ALTER_ORDER)
+ {
+ reason= "ORDER BY";
+ goto err;
+ }
for (field_no= 0; (field= it++); field_no++)
{
@@ -210,7 +220,8 @@ bool check_sequence_fields(LEX *lex, List<Create_field> *fields)
if (my_strcasecmp(system_charset_info, field_def->field_name,
field->field_name.str) ||
field->flags != field_def->flags ||
- field->type_handler() != field_def->type_handler)
+ field->type_handler() != field_def->type_handler ||
+ field->check_constraint || field->vcol_info)
{
reason= field->field_name.str;
goto err;
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 5ff88e02f5d..26f08a165b3 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -2071,6 +2071,19 @@ bool st_select_lex::cleanup()
delete join;
join= 0;
}
+ for (TABLE_LIST *tbl= get_table_list(); tbl; tbl= tbl->next_local)
+ {
+ if (tbl->is_recursive_with_table() &&
+ !tbl->is_with_table_recursive_reference())
+ {
+ /*
+ If query is killed before open_and_process_table() for tbl
+ is called then 'with' is already set, but 'derived' is not.
+ */
+ st_select_lex_unit *unit= tbl->with->spec;
+ error|= (bool) error | (uint) unit->cleanup();
+ }
+ }
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
lex_unit= lex_unit->next_unit())
{
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 6d6dc188457..c42c8e68e96 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -4569,7 +4569,7 @@ sp_labeled_block:
{
Lex->sp_block_init(thd, &$1);
}
- sp_decl_body_list
+ opt_sp_decl_body_list
{
if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
MYSQL_YYABORT;
@@ -4611,7 +4611,7 @@ sp_unlabeled_block:
MYSQL_YYABORT;
Lex->sp_block_init(thd);
}
- sp_decl_body_list
+ opt_sp_decl_body_list
{
if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
MYSQL_YYABORT;
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 505d8bbeebd..f9d5ede3794 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -2657,7 +2657,7 @@ srv_purge_coordinator_suspend(
rw_lock_x_lock(&purge_sys.latch);
- stop = srv_shutdown_state == SRV_SHUTDOWN_NONE
+ stop = srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
&& purge_sys.paused();
if (!stop) {
@@ -2722,7 +2722,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
/* If there are no records to purge or the last
purge didn't purge any records then wait for activity. */
- if (srv_shutdown_state == SRV_SHUTDOWN_NONE
+ if (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
&& srv_undo_sources
&& (n_total_purged == 0 || purge_sys.paused())) {
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index c3558a2fe00..edae63c0e47 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -2320,7 +2320,7 @@ skip_monitors:
thread_started[5 + i + SRV_MAX_N_IO_THREADS] = true;
}
- while (srv_shutdown_state == SRV_SHUTDOWN_NONE
+ while (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
&& srv_force_recovery < SRV_FORCE_NO_BACKGROUND
&& !purge_sys.enabled()) {
ib::info() << "Waiting for purge to start";