Commit d3681335 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.4 into 10.5

parents 996431fd 57022dfb
...@@ -691,13 +691,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -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 <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.h_id 2 100.00
1 PRIMARY <derived3> ref key0 key0 5 c.w_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 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 <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) 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 <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) 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 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: 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` 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 # simple mutual recursion
...@@ -1302,12 +1302,12 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -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 1 PRIMARY <derived4> ALL NULL NULL NULL NULL 24
4 DERIVED folks ALL NULL NULL NULL NULL 12 Using where 4 DERIVED folks ALL NULL NULL NULL NULL 12 Using where
6 RECURSIVE UNION <derived3> ALL NULL NULL NULL NULL 12 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 3 DERIVED folks ALL NULL NULL NULL NULL 12 Using where
2 RECURSIVE UNION folks ALL PRIMARY NULL NULL NULL 12 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) 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 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 explain FORMAT=JSON
with recursive with recursive
prev_gen prev_gen
...@@ -3372,13 +3372,13 @@ select * from cte1, cte2; ...@@ -3372,13 +3372,13 @@ select * from cte1, cte2;
id select_type table type possible_keys key key_len ref rows filtered Extra 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 <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) 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 <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) 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 <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) 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: 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` 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 prepare stmt from "with recursive
...@@ -3437,6 +3437,65 @@ cte2 as ...@@ -3437,6 +3437,65 @@ cte2 as
(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7) (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; select * from cte1, cte2 where cte1.c1 = 3;
c1 c2 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 procedure p;
drop table t1,t2; drop table t1,t2;
# #
...@@ -3843,7 +3902,104 @@ ANALYZE ...@@ -3843,7 +3902,104 @@ ANALYZE
} }
drop function f1; drop function f1;
drop table t1,t2; 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 # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
# #
......
...@@ -2424,6 +2424,30 @@ select * from cte1, cte2 where cte1.c1 = 3; ...@@ -2424,6 +2424,30 @@ select * from cte1, cte2 where cte1.c1 = 3;
eval $q3; 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 procedure p;
drop table t1,t2; drop table t1,t2;
...@@ -2609,7 +2633,51 @@ eval analyze format=json $q; ...@@ -2609,7 +2633,51 @@ eval analyze format=json $q;
drop function f1; drop function f1;
drop table t1,t2; 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 #
--echo # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field --echo # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
......
...@@ -607,6 +607,40 @@ ERROR HY000: Unknown system variable 'password' ...@@ -607,6 +607,40 @@ ERROR HY000: Unknown system variable 'password'
SELECT @@GLOBAL.role; SELECT @@GLOBAL.role;
ERROR HY000: Unknown system variable '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 # End of 10.3 tests
# #
# #
......
...@@ -409,6 +409,53 @@ SELECT @@GLOBAL.password; ...@@ -409,6 +409,53 @@ SELECT @@GLOBAL.password;
SELECT @@GLOBAL.role; 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 #
--echo # End of 10.3 tests --echo # End of 10.3 tests
--echo # --echo #
......
...@@ -238,3 +238,14 @@ select next value for t1; ...@@ -238,3 +238,14 @@ select next value for t1;
next value for t1 next value for t1
90 90
drop sequence t1; 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;
...@@ -139,3 +139,24 @@ select next value for t1; ...@@ -139,3 +139,24 @@ select next value for t1;
alter sequence t1 restart with 90; alter sequence t1 restart with 90;
select next value for t1; select next value for t1;
drop sequence 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;
...@@ -375,6 +375,40 @@ CREATE OR REPLACE TABLE t1 ( ...@@ -375,6 +375,40 @@ CREATE OR REPLACE TABLE t1 (
key key1 (next_not_cached_value) key key1 (next_not_cached_value)
) sequence=1; ) sequence=1;
ERROR HY000: Sequence 'test.t1' table structure is invalid (Sequence tables cannot have any keys) 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; drop sequence if exists t1;
Warnings: Warnings:
Note 4091 Unknown SEQUENCE: 'test.t1' Note 4091 Unknown SEQUENCE: 'test.t1'
......
...@@ -270,6 +270,48 @@ CREATE OR REPLACE TABLE t1 ( ...@@ -270,6 +270,48 @@ CREATE OR REPLACE TABLE t1 (
key key1 (next_not_cached_value) key key1 (next_not_cached_value)
) sequence=1; ) 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; drop sequence if exists t1;
# #
......
...@@ -1163,6 +1163,7 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem) ...@@ -1163,6 +1163,7 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
{ {
derived= with_elem->spec; derived= with_elem->spec;
if (derived != select_lex->master_unit() && if (derived != select_lex->master_unit() &&
!with_elem->is_recursive &&
!is_with_table_recursive_reference()) !is_with_table_recursive_reference())
{ {
derived->move_as_slave(select_lex); derived->move_as_slave(select_lex);
......
/* /*
Copyright (c) 2002, 2011, Oracle and/or its affiliates. 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 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 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) ...@@ -1197,7 +1197,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
DBUG_ASSERT(derived->table && derived->table->is_created()); DBUG_ASSERT(derived->table && derived->table->is_created());
select_unit *derived_result= derived->derived_result; select_unit *derived_result= derived->derived_result;
SELECT_LEX *save_current_select= lex->current_select; SELECT_LEX *save_current_select= lex->current_select;
bool derived_recursive_is_filled= false;
if (derived->pushdown_derived) if (derived->pushdown_derived)
{ {
...@@ -1238,7 +1237,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -1238,7 +1237,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
{ {
/* In this case all iteration are performed */ /* In this case all iteration are performed */
res= derived->fill_recursive(thd); res= derived->fill_recursive(thd);
derived_recursive_is_filled= true;
} }
} }
else if (unit->is_unit_op()) else if (unit->is_unit_op())
...@@ -1293,8 +1291,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -1293,8 +1291,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
} }
} }
err: err:
if (res || (!lex->describe && !unit->uncacheable && if (res || (!derived_is_recursive && !lex->describe && !unit->uncacheable))
(!derived_is_recursive || derived_recursive_is_filled)))
unit->cleanup(); unit->cleanup();
lex->current_select= save_current_select; lex->current_select= save_current_select;
......
...@@ -203,6 +203,16 @@ bool check_sequence_fields(LEX *lex, List<Create_field> *fields) ...@@ -203,6 +203,16 @@ bool check_sequence_fields(LEX *lex, List<Create_field> *fields)
reason= "Sequence tables cannot have any keys"; reason= "Sequence tables cannot have any keys";
goto err; 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++) for (field_no= 0; (field= it++); field_no++)
{ {
...@@ -210,7 +220,8 @@ bool check_sequence_fields(LEX *lex, List<Create_field> *fields) ...@@ -210,7 +220,8 @@ bool check_sequence_fields(LEX *lex, List<Create_field> *fields)
if (my_strcasecmp(system_charset_info, field_def->field_name, if (my_strcasecmp(system_charset_info, field_def->field_name,
field->field_name.str) || field->field_name.str) ||
field->flags != field_def->flags || 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; reason= field->field_name.str;
goto err; goto err;
......
...@@ -2712,6 +2712,19 @@ bool st_select_lex::cleanup() ...@@ -2712,6 +2712,19 @@ bool st_select_lex::cleanup()
delete join; delete join;
join= 0; 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 ; for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
lex_unit= lex_unit->next_unit()) lex_unit= lex_unit->next_unit())
{ {
......
...@@ -19070,7 +19070,7 @@ sp_labeled_block: ...@@ -19070,7 +19070,7 @@ sp_labeled_block:
{ {
Lex->sp_block_init(thd, &$1); 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))) if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
MYSQL_YYABORT; MYSQL_YYABORT;
...@@ -19112,7 +19112,7 @@ sp_unlabeled_block: ...@@ -19112,7 +19112,7 @@ sp_unlabeled_block:
MYSQL_YYABORT; MYSQL_YYABORT;
Lex->sp_block_init(thd); Lex->sp_block_init(thd);
} }
sp_decl_body_list opt_sp_decl_body_list
{ {
if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
MYSQL_YYABORT; MYSQL_YYABORT;
......
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