summaryrefslogtreecommitdiffstats
path: root/mysql-test/main/cte_recursive.result
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/main/cte_recursive.result')
-rw-r--r--mysql-test/main/cte_recursive.result5971
1 files changed, 5971 insertions, 0 deletions
diff --git a/mysql-test/main/cte_recursive.result b/mysql-test/main/cte_recursive.result
new file mode 100644
index 00000000..ef0920bf
--- /dev/null
+++ b/mysql-test/main/cte_recursive.result
@@ -0,0 +1,5971 @@
+create table t1 (a int, b varchar(32));
+insert into t1 values
+(4,'aaaa' ), (7,'bb'), (1,'ccc'), (4,'dd');
+insert into t1 values
+(3,'eee'), (7,'bb'), (1,'fff'), (4,'ggg');
+with recursive
+t as
+(
+select * from t1 where t1.b >= 'c'
+ union
+select * from r
+),
+r as
+(
+select * from t
+union
+select t1.* from t1,r where r.a+1 = t1.a
+)
+select * from r;
+ERROR HY000: Unacceptable mutual recursion with anchored table 't'
+with recursive
+a1(a,b) as
+(select * from t1 where t1.a>3
+union
+select * from b1 where b1.a >3
+union
+select * from c1 where c1.a>3),
+b1(a,b) as
+(select * from a1 where a1.b > 'ccc'
+union
+select * from c1 where c1.b > 'ddd'),
+c1(a,b) as
+(select * from a1 where a1.a<6 and a1.b< 'zz'
+union
+select * from b1 where b1.b > 'auu')
+select * from c1;
+ERROR HY000: Unacceptable mutual recursion with anchored table 'a1'
+drop table t1;
+# WITH RECURSIVE vs just WITH
+create table t1 (a int);
+insert into t1 values
+(0), (1), (2), (3), (4);
+create table t2 (a int);
+insert into t2 values
+(1), (2), (3), (4), (5);
+# just WITH : s refers to t defined after s
+with
+s(a) as (select t.a + 10 from t),
+t(a) as (select t1.a from t1)
+select * from s;
+ERROR 42S02: Table 'test.t' doesn't exist
+# WITH RECURSIVE: s refers to t defined after s
+with recursive
+s(a) as (select t.a + 10 from t),
+t(a) as (select t1.a from t1)
+select * from s;
+a
+10
+11
+12
+13
+14
+# just WITH : defined t1 is non-recursive and uses base tables t1,t2
+with
+t1 as
+(
+select a from t2 where t2.a=3
+union
+select t2.a from t1,t2 where t1.a+1=t2.a
+)
+select * from t1;
+a
+3
+1
+2
+4
+5
+explain
+with
+t1 as
+(
+select a from t2 where t2.a=3
+union
+select t2.a from t1,t2 where t1.a+1=t2.a
+)
+select * from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 30
+2 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where
+3 UNION t1 ALL NULL NULL NULL NULL 5
+3 UNION t2 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+#WITH RECURSIVE : defined t1 is recursive and uses only base table t2
+with recursive
+t1 as
+(
+select a from t2 where t2.a=3
+union
+select t2.a from t1,t2 where t1.a+1=t2.a
+)
+select * from t1;
+a
+3
+4
+5
+explain
+with recursive
+t1 as
+(
+select a from t2 where t2.a=3
+union
+select t2.a from t1,t2 where t1.a+1=t2.a
+)
+select * from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
+2 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where
+3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 5
+3 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+# just WITH : types of t1 columns are determined by all parts of union
+create view v1 as
+with
+t1 as
+(
+select a from t2 where t2.a=3
+union
+select t2.a+1 from t1,t2 where t1.a=t2.a
+)
+select * from t1;
+show columns from v1;
+Field Type Null Key Default Extra
+a bigint(12) YES NULL
+# WITH RECURSIVE : types of t1 columns are determined by anchor parts
+create view v2 as
+with recursive
+t1 as
+(
+select a from t2 where t2.a=3
+union
+select t2.a+1 from t1,t2 where t1.a=t2.a
+)
+select * from t1;
+show columns from v2;
+Field Type Null Key Default Extra
+a int(11) YES NULL
+drop view v1,v2;
+drop table t1,t2;
+create table folks(id int, name char(32), dob date, father int, mother int);
+insert into folks values
+(100, 'Me', '2000-01-01', 20, 30),
+(20, 'Dad', '1970-02-02', 10, 9),
+(30, 'Mom', '1975-03-03', 8, 7),
+(10, 'Grandpa Bill', '1940-04-05', null, null),
+(9, 'Grandma Ann', '1941-10-15', null, null),
+(25, 'Uncle Jim', '1968-11-18', 8, 7),
+(98, 'Sister Amy', '2001-06-20', 20, 30),
+(7, 'Grandma Sally', '1943-08-23', null, 6),
+(8, 'Grandpa Ben', '1940-10-21', null, null),
+(6, 'Grandgrandma Martha', '1923-05-17', null, null),
+(67, 'Cousin Eddie', '1992-02-28', 25, 27),
+(27, 'Auntie Melinda', '1971-03-29', null, null);
+# simple recursion with one anchor and one recursive select
+# the anchor is the first select in the specification
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me' and dob = '2000-01-01'
+ union
+select p.id, p.name, p.dob, p.father, p.mother
+from folks as p, ancestors AS a
+where p.id = a.father or p.id = a.mother
+)
+select * from ancestors;
+id name dob father mother
+100 Me 2000-01-01 20 30
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+# simple recursion with one anchor and one recursive select
+# the anchor is the last select in the specification
+with recursive
+ancestors
+as
+(
+select p.*
+from folks as p, ancestors AS a
+where p.id = a.father or p.id = a.mother
+union
+select *
+from folks
+where name = 'Me' and dob = '2000-01-01'
+)
+select * from ancestors;
+id name dob father mother
+100 Me 2000-01-01 20 30
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+# simple recursion with one anchor and one recursive select
+# the anchor is the first select in the specification
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Cousin Eddie'
+ union
+select p.*
+from folks as p, ancestors as a
+where p.id = a.father or p.id = a.mother
+)
+select * from ancestors;
+id name dob father mother
+67 Cousin Eddie 1992-02-28 25 27
+25 Uncle Jim 1968-11-18 8 7
+27 Auntie Melinda 1971-03-29 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+# simple recursion with or in anchor and or in recursive part
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me' or name='Sister Amy'
+ union
+select p.*
+from folks as p, ancestors as a
+where p.id = a.father or p.id = a.mother
+)
+select * from ancestors;
+id name dob father mother
+100 Me 2000-01-01 20 30
+98 Sister Amy 2001-06-20 20 30
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+# two recursive definition, one uses another
+with recursive
+prev_gen
+as
+(
+select folks.*
+from folks, prev_gen
+where folks.id=prev_gen.father or folks.id=prev_gen.mother
+union
+select *
+from folks
+where name='Me'
+),
+ancestors
+as
+(
+select *
+from folks
+where name='Me'
+ union
+select *
+from ancestors
+union
+select *
+from prev_gen
+)
+select ancestors.name, ancestors.dob from ancestors;
+name dob
+Me 2000-01-01
+Dad 1970-02-02
+Mom 1975-03-03
+Grandpa Bill 1940-04-05
+Grandma Ann 1941-10-15
+Grandma Sally 1943-08-23
+Grandpa Ben 1940-10-21
+Grandgrandma Martha 1923-05-17
+# recursive definition with two attached non-recursive
+with recursive
+ancestors(id,name,dob)
+as
+(
+with
+father(child_id,id,name,dob)
+as
+(
+select folks.id, f.id, f.name, f.dob
+from folks, folks f
+where folks.father=f.id
+),
+mother(child_id,id,name,dob)
+as
+(
+select folks.id, m.id, m.name, m.dob
+from folks, folks m
+where folks.mother=m.id
+)
+select folks.id, folks.name, folks.dob
+from folks
+where name='Me'
+ union
+select f.id, f.name, f.dob
+from ancestors a, father f
+where f.child_id=a.id
+union
+select m.id, m.name, m.dob
+from ancestors a, mother m
+where m.child_id=a.id
+)
+select ancestors.name, ancestors.dob from ancestors;
+name dob
+Me 2000-01-01
+Dad 1970-02-02
+Mom 1975-03-03
+Grandpa Bill 1940-04-05
+Grandpa Ben 1940-10-21
+Grandma Ann 1941-10-15
+Grandma Sally 1943-08-23
+Grandgrandma Martha 1923-05-17
+# simple recursion with one anchor and one recursive select
+# the anchor is the first select in the specification
+with recursive
+descendants
+as
+(
+select *
+from folks
+where name = 'Grandpa Bill'
+ union
+select folks.*
+from folks, descendants as d
+where d.id=folks.father or d.id=folks.mother
+)
+select * from descendants;
+id name dob father mother
+10 Grandpa Bill 1940-04-05 NULL NULL
+20 Dad 1970-02-02 10 9
+100 Me 2000-01-01 20 30
+98 Sister Amy 2001-06-20 20 30
+# simple recursion with one anchor and one recursive select
+# the anchor is the first select in the specification
+with recursive
+descendants
+as
+(
+select *
+from folks
+where name = 'Grandma Sally'
+ union
+select folks.*
+from folks, descendants as d
+where d.id=folks.father or d.id=folks.mother
+)
+select * from descendants;
+id name dob father mother
+7 Grandma Sally 1943-08-23 NULL 6
+30 Mom 1975-03-03 8 7
+25 Uncle Jim 1968-11-18 8 7
+100 Me 2000-01-01 20 30
+98 Sister Amy 2001-06-20 20 30
+67 Cousin Eddie 1992-02-28 25 27
+# simple recursive table used three times in the main query
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me' and dob = '2000-01-01'
+ union
+select p.*
+from folks as p, ancestors AS a
+where p.id = a.father OR p.id = a.mother
+)
+select *
+from ancestors t1, ancestors t2
+where exists (select * from ancestors a
+where a.father=t1.id AND a.mother=t2.id);
+id name dob father mother id name dob father mother
+20 Dad 1970-02-02 10 9 30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL 9 Grandma Ann 1941-10-15 NULL NULL
+8 Grandpa Ben 1940-10-21 NULL NULL 7 Grandma Sally 1943-08-23 NULL 6
+# simple recursive table used three times in the main query
+with
+ancestor_couples(husband, h_dob, wife, w_dob)
+as
+(
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me'
+ union
+select p.*
+from folks as p, ancestors AS a
+where p.id = a.father OR p.id = a.mother
+)
+select t1.name, t1.dob, t2.name, t2.dob
+from ancestors t1, ancestors t2
+where exists (select * from ancestors a
+where a.father=t1.id AND a.mother=t2.id)
+)
+select * from ancestor_couples;
+husband h_dob wife w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+# simple recursion with two selects in recursive part
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me'
+ union
+select p.*
+from folks as p, ancestors as fa
+where p.id = fa.father
+union
+select p.*
+from folks as p, ancestors as ma
+where p.id = ma.mother
+)
+select * from ancestors;
+id name dob father mother
+100 Me 2000-01-01 20 30
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+8 Grandpa Ben 1940-10-21 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+# mutual recursion with renaming
+with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+union
+select h.*, w.*
+from folks v, folks h, folks w
+where v.name = 'Me' and
+(v.father = h.id AND v.mother= w.id)
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples;
+h_name h_dob w_name w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+# mutual recursion with union all
+with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+union
+select h.*, w.*
+from folks v, folks h, folks w
+where v.name = 'Me' and
+(v.father = h.id AND v.mother= w.id)
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union all
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples;
+h_name h_dob w_name w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+# mutual recursion with renaming
+with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+union
+select h.*, w.*
+from folks v, folks h, folks w
+where v.name = 'Me' and
+(v.father = h.id AND v.mother= w.id)
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples;
+h_name h_dob w_name w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+# mutual recursion with union all
+with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select *
+from folks
+where name = 'Me'
+ union all
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union all
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples;
+h_name h_dob w_name w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+# mutual recursion with one select in the first definition
+with recursive
+ancestor_couple_ids(h_id, w_id)
+as
+(
+select a.father, a.mother
+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 *
+from folks
+where name = 'Me'
+ union all
+select p.*
+from folks p, ancestor_couple_ids fa
+where p.id = fa.h_id
+union all
+select p.*
+from folks p, ancestor_couple_ids ma
+where p.id = ma.w_id
+)
+select *
+from ancestor_couple_ids;
+h_id w_id
+20 30
+10 9
+8 7
+# join of a mutually recursive table with base tables
+with recursive
+ancestor_couple_ids(h_id, w_id)
+as
+(
+select a.father, a.mother
+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 *
+from folks
+where name = 'Me'
+ union all
+select p.*
+from folks p, ancestor_couple_ids fa
+where p.id = fa.h_id
+union all
+select p.*
+from folks p, ancestor_couple_ids ma
+where p.id = ma.w_id
+)
+select h.name, h.dob, w.name, w.dob
+from ancestor_couple_ids c, folks h, folks w
+where c.h_id = h.id and c.w_id= w.id;
+name dob name dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+# join of two mutually recursive tables
+with recursive
+ancestor_couple_ids(h_id, w_id)
+as
+(
+select a.father, a.mother
+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 *
+from folks
+where name = 'Me'
+ union all
+select p.*
+from folks p, ancestor_couple_ids fa
+where p.id = fa.h_id
+union all
+select p.*
+from folks p, ancestor_couple_ids ma
+where p.id = ma.w_id
+)
+select h.name, h.dob, w.name, w.dob
+from ancestor_couple_ids c, coupled_ancestors h, coupled_ancestors w
+where c.h_id = h.id and c.w_id= w.id;
+name dob name dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+explain extended
+with recursive
+ancestor_couple_ids(h_id, w_id)
+as
+(
+select a.father, a.mother
+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 *
+from folks
+where name = 'Me'
+ union all
+select p.*
+from folks p, ancestor_couple_ids fa
+where p.id = fa.h_id
+union all
+select p.*
+from folks p, ancestor_couple_ids ma
+where p.id = ma.w_id
+)
+select h.name, h.dob, w.name, w.dob
+from ancestor_couple_ids c, coupled_ancestors h, coupled_ancestors w
+where c.h_id = h.id and c.w_id= w.id;
+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
+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
+with recursive
+ancestor_couple_ids(h_id, w_id)
+as
+(
+select a.father, a.mother
+from coupled_ancestors a
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select *
+from folks
+where name = 'Me'
+ union all
+select p.*
+from folks p, ancestor_couple_ids fa
+where p.id = fa.h_id
+union all
+select p.*
+from folks p, ancestor_couple_ids ma
+where p.id = ma.w_id
+)
+select *
+from ancestor_couple_ids;
+h_id w_id
+20 30
+10 9
+8 7
+NULL NULL
+NULL NULL
+NULL NULL
+NULL 6
+NULL NULL
+# join of two mutually recursive tables
+with recursive
+ancestor_couple_ids(h_id, w_id)
+as
+(
+select a.father, a.mother
+from coupled_ancestors a
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select *
+from folks
+where name = 'Me'
+ union all
+select p.*
+from folks p, ancestor_couple_ids fa
+where p.id = fa.h_id
+union all
+select p.*
+from folks p, ancestor_couple_ids ma
+where p.id = ma.w_id
+)
+select h.name, h.dob, w.name, w.dob
+from ancestor_couple_ids c, coupled_ancestors h, coupled_ancestors w
+where c.h_id = h.id and c.w_id= w.id;
+name dob name dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+# execution of prepared query using a recursive table
+prepare stmt1 from "
+with recursive
+ancestors
+as
+(
+ select *
+ from folks
+ where name = 'Me' and dob = '2000-01-01'
+ union
+ select p.id, p.name, p.dob, p.father, p.mother
+ from folks as p, ancestors AS a
+ where p.id = a.father or p.id = a.mother
+)
+select * from ancestors;
+";
+execute stmt1;
+id name dob father mother
+100 Me 2000-01-01 20 30
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+execute stmt1;
+id name dob father mother
+100 Me 2000-01-01 20 30
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+deallocate prepare stmt1;
+# view using a recursive table
+create view v1 as
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me' and dob = '2000-01-01'
+ union
+select p.id, p.name, p.dob, p.father, p.mother
+from folks as p, ancestors AS a
+where p.id = a.father or p.id = a.mother
+)
+select * from ancestors;
+show create view v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS with recursive ancestors as (select `folks`.`id` AS `id`,`folks`.`name` AS `name`,`folks`.`dob` AS `dob`,`folks`.`father` AS `father`,`folks`.`mother` AS `mother` from `folks` where `folks`.`name` = 'Me' and `folks`.`dob` = '2000-01-01' union select `p`.`id` AS `id`,`p`.`name` AS `name`,`p`.`dob` AS `dob`,`p`.`father` AS `father`,`p`.`mother` AS `mother` from (`folks` `p` join `ancestors` `a`) where `p`.`id` = `a`.`father` or `p`.`id` = `a`.`mother`)select `ancestors`.`id` AS `id`,`ancestors`.`name` AS `name`,`ancestors`.`dob` AS `dob`,`ancestors`.`father` AS `father`,`ancestors`.`mother` AS `mother` from `ancestors` latin1 latin1_swedish_ci
+select * from v1;
+id name dob father mother
+100 Me 2000-01-01 20 30
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+create view v2 as
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me'
+ union
+select p.*
+from folks as p, ancestors as fa
+where p.id = fa.father
+union
+select p.*
+from folks as p, ancestors as ma
+where p.id = ma.mother
+)
+select * from ancestors;
+show create view v2;
+View Create View character_set_client collation_connection
+v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS with recursive ancestors as (select `folks`.`id` AS `id`,`folks`.`name` AS `name`,`folks`.`dob` AS `dob`,`folks`.`father` AS `father`,`folks`.`mother` AS `mother` from `folks` where `folks`.`name` = 'Me' union select `p`.`id` AS `id`,`p`.`name` AS `name`,`p`.`dob` AS `dob`,`p`.`father` AS `father`,`p`.`mother` AS `mother` from (`folks` `p` join `ancestors` `fa`) where `p`.`id` = `fa`.`father` union select `p`.`id` AS `id`,`p`.`name` AS `name`,`p`.`dob` AS `dob`,`p`.`father` AS `father`,`p`.`mother` AS `mother` from (`folks` `p` join `ancestors` `ma`) where `p`.`id` = `ma`.`mother`)select `ancestors`.`id` AS `id`,`ancestors`.`name` AS `name`,`ancestors`.`dob` AS `dob`,`ancestors`.`father` AS `father`,`ancestors`.`mother` AS `mother` from `ancestors` latin1 latin1_swedish_ci
+select * from v2;
+id name dob father mother
+100 Me 2000-01-01 20 30
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+8 Grandpa Ben 1940-10-21 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+drop view v1,v2;
+explain extended
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me' and dob = '2000-01-01'
+ union
+select p.id, p.name, p.dob, p.father, p.mother
+from folks as p, ancestors AS a
+where p.id = a.father or p.id = a.mother
+)
+select * from ancestors;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 12 100.00
+2 DERIVED folks ALL NULL NULL NULL NULL 12 100.00 Using where
+3 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00
+3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 with recursive ancestors as (/* select#2 */ 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' and `test`.`folks`.`dob` = DATE'2000-01-01' union /* select#3 */ select `p`.`id` AS `id`,`p`.`name` AS `name`,`p`.`dob` AS `dob`,`p`.`father` AS `father`,`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestors` `a` where `a`.`father` = `p`.`id` or `a`.`mother` = `p`.`id`)/* select#1 */ select `ancestors`.`id` AS `id`,`ancestors`.`name` AS `name`,`ancestors`.`dob` AS `dob`,`ancestors`.`father` AS `father`,`ancestors`.`mother` AS `mother` from `ancestors`
+# recursive spec with two anchor selects and two recursive ones
+with recursive
+ancestor_ids (id)
+as
+(
+select father from folks where name = 'Me'
+ union
+select mother from folks where name = 'Me'
+ union
+select father from folks, ancestor_ids a where folks.id = a.id
+union
+select mother from folks, ancestor_ids a where folks.id = a.id
+),
+ancestors
+as
+(
+select p.* from folks as p, ancestor_ids as a
+where p.id = a.id
+)
+select * from ancestors;
+id name dob father mother
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+# recursive spec using union all
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me'
+ union all
+select p.*
+from folks as p, ancestors as fa
+where p.id = fa.father
+union all
+select p.*
+from folks as p, ancestors as ma
+where p.id = ma.mother
+)
+select * from ancestors;
+id name dob father mother
+100 Me 2000-01-01 20 30
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+8 Grandpa Ben 1940-10-21 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+with recursive
+ancestor_ids (id, generation)
+as
+(
+select father, 1 from folks where name = 'Me' and father is not null
+union all
+select mother, 1 from folks where name = 'Me' and mother is not null
+union all
+select father, fa.generation+1 from folks, ancestor_ids fa
+where folks.id = fa.id and (father not in (select id from ancestor_ids))
+union all
+select mother, ma.generation+1 from folks, ancestor_ids ma
+where folks.id = ma.id and (mother not in (select id from ancestor_ids))
+)
+select generation, name from ancestor_ids a, folks
+where a.id = folks.id;
+ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'ancestor_ids'
+set standard_compliant_cte=0;
+with recursive
+ancestor_ids (id, generation)
+as
+(
+select father from folks where name = 'Me' and father is not null
+union all
+select mother from folks where name = 'Me' and mother is not null
+union all
+select father, fa.generation+1 from folks, ancestor_ids fa
+where folks.id = fa.id and (father not in (select id from ancestor_ids))
+union all
+select mother, ma.generation+1 from folks, ancestor_ids ma
+where folks.id = ma.id and (mother not in (select id from ancestor_ids))
+)
+select generation, name from ancestor_ids a, folks
+where a.id = folks.id;
+ERROR HY000: WITH column list and SELECT field list have different column counts
+with recursive
+ancestor_ids (id, generation)
+as
+(
+select father, 1 from folks where name = 'Me' and father is not null
+union all
+select mother, 1 from folks where name = 'Me' and mother is not null
+union all
+select father, fa.generation+1 from folks, ancestor_ids fa
+where folks.id = fa.id and father is not null and
+(father not in (select id from ancestor_ids))
+union all
+select mother, ma.generation+1 from folks, ancestor_ids ma
+where folks.id = ma.id and mother is not null and
+(mother not in (select id from ancestor_ids))
+)
+select generation, name from ancestor_ids a, folks
+where a.id = folks.id;
+generation name
+1 Dad
+1 Mom
+2 Grandpa Bill
+2 Grandma Ann
+2 Grandma Sally
+2 Grandpa Ben
+3 Grandgrandma Martha
+set standard_compliant_cte=1;
+with recursive
+coupled_ancestor_ids (id)
+as
+(
+select father from folks where name = 'Me' and father is not null
+union
+select mother from folks where name = 'Me' and mother is not null
+union
+select n.father
+from folks, coupled_ancestor_ids fa, coupled_ancestor_ids ma, folks n
+where folks.father = fa.id and folks.mother = ma.id and
+(fa.id = n.id or ma.id = n.id) and
+n.father is not null and n.mother is not null
+union
+select n.mother
+from folks, coupled_ancestor_ids fa, coupled_ancestor_ids ma, folks n
+where folks.father = fa.id and folks.mother = ma.id and
+(fa.id = n.id or ma.id = n.id) and
+n.father is not null and n.mother is not null
+)
+select p.* from coupled_ancestor_ids a, folks p
+where a.id = p.id;
+ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'coupled_ancestor_ids'
+set statement standard_compliant_cte=0 for
+with recursive
+coupled_ancestor_ids (id)
+as
+(
+select father from folks where name = 'Me' and father is not null
+union
+select mother from folks where name = 'Me' and mother is not null
+union
+select n.father
+from folks, coupled_ancestor_ids fa, coupled_ancestor_ids ma, folks n
+where folks.father = fa.id and folks.mother = ma.id and
+(fa.id = n.id or ma.id = n.id) and
+n.father is not null and n.mother is not null
+union
+select n.mother
+from folks, coupled_ancestor_ids fa, coupled_ancestor_ids ma, folks n
+where folks.father = fa.id and folks.mother = ma.id and
+(fa.id = n.id or ma.id = n.id) and
+n.father is not null and n.mother is not null
+)
+select p.* from coupled_ancestor_ids a, folks p
+where a.id = p.id;
+id name dob father mother
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+with recursive
+ancestor_ids (id)
+as
+(
+select father from folks where name = 'Me'
+ union
+select mother from folks where name = 'Me'
+ union
+select father from folks left join ancestor_ids a on folks.id = a.id
+union
+select mother from folks left join ancestor_ids a on folks.id = a.id
+),
+ancestors
+as
+(
+select p.* from folks as p, ancestor_ids as a
+where p.id = a.id
+)
+select * from ancestors;
+ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'ancestor_ids'
+set statement standard_compliant_cte=0 for
+with recursive
+ancestor_ids (id)
+as
+(
+select father from folks where name = 'Me'
+ union
+select mother from folks where name = 'Me'
+ union
+select father from folks left join ancestor_ids a on folks.id = a.id
+union
+select mother from folks left join ancestor_ids a on folks.id = a.id
+),
+ancestors
+as
+(
+select p.* from folks as p, ancestor_ids as a
+where p.id = a.id
+)
+select * from ancestors;
+id name dob father mother
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+25 Uncle Jim 1968-11-18 8 7
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+27 Auntie Melinda 1971-03-29 NULL NULL
+with recursive
+ancestor_ids (id, generation)
+as
+(
+select father, 1 from folks where name = 'Me'
+ union
+select mother, 1 from folks where name = 'Me'
+ union
+select father, a.generation+1 from folks, ancestor_ids a
+where folks.id = a.id
+union
+select mother, a.generation+1 from folks, ancestor_ids a
+where folks.id = a.id
+),
+ancestors
+as
+(
+select generation, name from folks as p, ancestor_ids as a
+where p.id = a.id
+)
+select * from ancestors;
+generation name
+1 Dad
+1 Mom
+2 Grandpa Bill
+2 Grandma Ann
+2 Grandma Sally
+2 Grandpa Ben
+3 Grandgrandma Martha
+with recursive
+ancestor_ids (id, generation)
+as
+(
+select father, 1 from folks where name = 'Me'
+ union
+select mother, 1 from folks where name = 'Me'
+ union
+select max(father), max(a.generation)+1 from folks, ancestor_ids a
+where folks.id = a.id
+group by a.generation
+union
+select max(mother), max(a.generation)+1 from folks, ancestor_ids a
+where folks.id = a.id
+group by a.generation
+),
+ancestors
+as
+(
+select generation, name from folks as p, ancestor_ids as a
+where p.id = a.id
+)
+select * from ancestors;
+ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'ancestor_ids'
+set statement standard_compliant_cte=0 for
+with recursive
+ancestor_ids (id, generation)
+as
+(
+select father, 1 from folks where name = 'Me'
+ union
+select mother, 1 from folks where name = 'Me'
+ union
+select max(father), a.generation+1 from folks, ancestor_ids a
+where folks.id = a.id
+group by a.generation
+union
+select max(mother), a.generation+1 from folks, ancestor_ids a
+where folks.id = a.id
+group by a.generation
+),
+ancestors
+as
+(
+select generation, name from folks as p, ancestor_ids as a
+where p.id = a.id
+)
+select * from ancestors;
+generation name
+1 Dad
+1 Mom
+2 Grandpa Bill
+2 Grandma Ann
+set statement max_recursive_iterations=1 for
+with recursive
+ancestor_ids (id, generation)
+as
+(
+select father, 1 from folks where name = 'Me'
+ union
+select mother, 1 from folks where name = 'Me'
+ union
+select father, a.generation+1 from folks, ancestor_ids a
+where folks.id = a.id
+union
+select mother, a.generation+1 from folks, ancestor_ids a
+where folks.id = a.id
+),
+ancestors
+as
+(
+select generation, name from folks as p, ancestor_ids as a
+where p.id = a.id
+)
+select * from ancestors;
+generation name
+1 Dad
+1 Mom
+2 Grandpa Bill
+2 Grandma Ann
+2 Grandma Sally
+2 Grandpa Ben
+Warnings:
+Warning 1931 Query execution was interrupted. The query exceeded max_recursive_iterations = 1. The query result may be incomplete
+# query with recursive tables using key access
+alter table folks add primary key (id);
+explain
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me'
+ union
+select p.*
+from folks as p, ancestors as fa
+where p.id = fa.father
+union
+select p.*
+from folks as p, ancestors as ma
+where p.id = ma.mother
+)
+select * from ancestors;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 12
+2 DERIVED folks ALL NULL NULL NULL NULL 12 Using where
+3 RECURSIVE UNION p ALL PRIMARY NULL NULL NULL 12
+3 RECURSIVE UNION <derived2> ref key0 key0 5 test.p.id 2
+4 RECURSIVE UNION p ALL PRIMARY NULL NULL NULL 12
+4 RECURSIVE UNION <derived2> ref key0 key0 5 test.p.id 2
+NULL UNION RESULT <union2,3,4> ALL NULL NULL NULL NULL NULL
+with recursive
+ancestors
+as
+(
+select *
+from folks
+where name = 'Me'
+ union
+select p.*
+from folks as p, ancestors as fa
+where p.id = fa.father
+union
+select p.*
+from folks as p, ancestors as ma
+where p.id = ma.mother
+)
+select * from ancestors;
+id name dob father mother
+100 Me 2000-01-01 20 30
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+8 Grandpa Ben 1940-10-21 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+#
+# EXPLAIN FORMAT=JSON on a query where one recursive CTE uses another:
+#
+explain
+with recursive
+prev_gen
+as
+(
+select folks.*
+from folks, prev_gen
+where folks.id=prev_gen.father or folks.id=prev_gen.mother
+union
+select *
+from folks
+where name='Me'
+),
+ancestors
+as
+(
+select *
+from folks
+where name='Me'
+ union
+select *
+from ancestors
+union
+select *
+from prev_gen
+)
+select ancestors.name, ancestors.dob from ancestors;
+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 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
+explain FORMAT=JSON
+with recursive
+prev_gen
+as
+(
+select folks.*
+from folks, prev_gen
+where folks.id=prev_gen.father or folks.id=prev_gen.mother
+union
+select *
+from folks
+where name='Me'
+),
+ancestors
+as
+(
+select *
+from folks
+where name='Me2'
+ union
+select *
+from ancestors where id < 234
+union
+select *
+from prev_gen where id < 345
+)
+select ancestors.name, ancestors.dob from ancestors;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived4>",
+ "access_type": "ALL",
+ "rows": 24,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "recursive_union": {
+ "table_name": "<union4,6,5>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 4,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "folks",
+ "access_type": "ALL",
+ "rows": 12,
+ "filtered": 100,
+ "attached_condition": "folks.`name` = 'Me2'"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 6,
+ "operation": "UNION",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 12,
+ "filtered": 100,
+ "attached_condition": "prev_gen.`id` < 345",
+ "materialized": {
+ "query_block": {
+ "recursive_union": {
+ "table_name": "<union3,2>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 3,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "folks",
+ "access_type": "ALL",
+ "rows": 12,
+ "filtered": 100,
+ "attached_condition": "folks.`name` = 'Me'"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 2,
+ "operation": "UNION",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "folks",
+ "access_type": "ALL",
+ "possible_keys": ["PRIMARY"],
+ "rows": 12,
+ "filtered": 100
+ }
+ },
+ {
+ "block-nl-join": {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 12,
+ "filtered": 100
+ },
+ "buffer_type": "flat",
+ "buffer_size": "686",
+ "join_type": "BNL",
+ "attached_condition": "prev_gen.father = folks.`id` or prev_gen.mother = folks.`id`"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 5,
+ "operation": "UNION",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived4>",
+ "access_type": "ALL",
+ "rows": 24,
+ "filtered": 100,
+ "attached_condition": "ancestors.`id` < 234"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+}
+#
+explain format=json
+with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+union
+select h.*, w.*
+from folks v, folks h, folks w
+where v.name = 'Me' and
+(v.father = h.id AND v.mother= w.id)
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union all
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 12,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "recursive_union": {
+ "table_name": "<union3,2>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 3,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "v",
+ "access_type": "ALL",
+ "rows": 12,
+ "filtered": 100,
+ "attached_condition": "v.`name` = 'Me' and v.father is not null and v.mother is not null"
+ }
+ },
+ {
+ "table": {
+ "table_name": "h",
+ "access_type": "eq_ref",
+ "possible_keys": ["PRIMARY"],
+ "key": "PRIMARY",
+ "key_length": "4",
+ "used_key_parts": ["id"],
+ "ref": ["test.v.father"],
+ "rows": 1,
+ "filtered": 100
+ }
+ },
+ {
+ "table": {
+ "table_name": "w",
+ "access_type": "eq_ref",
+ "possible_keys": ["PRIMARY"],
+ "key": "PRIMARY",
+ "key_length": "4",
+ "used_key_parts": ["id"],
+ "ref": ["test.v.mother"],
+ "rows": 1,
+ "filtered": 100
+ }
+ }
+ ]
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 2,
+ "operation": "UNION",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived4>",
+ "access_type": "ALL",
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "a.father is not null and a.mother is not null"
+ }
+ },
+ {
+ "table": {
+ "table_name": "h",
+ "access_type": "eq_ref",
+ "possible_keys": ["PRIMARY"],
+ "key": "PRIMARY",
+ "key_length": "4",
+ "used_key_parts": ["id"],
+ "ref": ["a.father"],
+ "rows": 1,
+ "filtered": 100
+ }
+ },
+ {
+ "table": {
+ "table_name": "w",
+ "access_type": "eq_ref",
+ "possible_keys": ["PRIMARY"],
+ "key": "PRIMARY",
+ "key_length": "4",
+ "used_key_parts": ["id"],
+ "ref": ["a.mother"],
+ "rows": 1,
+ "filtered": 100
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+}
+create table my_ancestors
+with recursive
+ancestor_ids (id)
+as
+(
+select father from folks where name = 'Me'
+ union
+select mother from folks where name = 'Me'
+ union
+select father from folks, ancestor_ids a where folks.id = a.id
+union
+select mother from folks, ancestor_ids a where folks.id = a.id
+)
+select p.* from folks as p, ancestor_ids as a where p.id = a.id;
+select * from my_ancestors;
+id name dob father mother
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+delete from my_ancestors;
+insert into my_ancestors
+with recursive
+ancestor_ids (id)
+as
+(
+select father from folks where name = 'Me'
+ union
+select mother from folks where name = 'Me'
+ union
+select father from folks, ancestor_ids a where folks.id = a.id
+union
+select mother from folks, ancestor_ids a where folks.id = a.id
+)
+select p.* from folks as p, ancestor_ids as a where p.id = a.id;
+select * from my_ancestors;
+id name dob father mother
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+drop table my_ancestors;
+WITH RECURSIVE
+positions(i) AS (
+VALUES(0)
+UNION SELECT ALL
+i+1 FROM positions WHERE i < 4*4-1
+),
+solutions(board, n_queens) AS (
+SELECT REPEAT('-', 4*4), 0
+FROM positions
+UNION
+SELECT
+concat(substr(board, 1, i),'*',substr(board, i+2)),n_queens + 1 AS n_queens
+FROM positions AS ps, solutions
+WHERE n_queens < 4
+AND substr(board,1,i) != '*'
+ AND NOT EXISTS (
+SELECT 1 FROM positions WHERE
+substr(board,i+1,1) = '*' AND
+(
+i % 4 = ps.i % 4 OR
+i div 4 = ps.i div 4 OR
+i div 4 + (i % 4) = ps.i div 4 + (ps.i % 4) OR
+i div 4 - (i % 4) = ps.i div 4 - (ps.i % 4)
+)
+)
+)
+SELECT regexp_replace(board,concat('(',REPEAT('.', 4),')'),'\\1\n') n_queens FROM solutions WHERE n_queens = 4;
+n_queens
+--*-
+*---
+---*
+-*--
+
+-*--
+---*
+*---
+--*-
+
+#
+# MDEV-10883: execution of prepared statement from SELECT
+# with recursive CTE that renames columns
+#
+prepare stmt from"
+with recursive
+ancestor_ids (id)
+as
+(
+ select father from folks where name = 'Me'
+ union
+ select mother from folks where name = 'Me'
+ union
+ select father from folks, ancestor_ids a where folks.id = a.id
+ union
+ select mother from folks, ancestor_ids a where folks.id = a.id
+)
+select p.* from folks as p, ancestor_ids as a where p.id = a.id;
+";
+execute stmt;
+id name dob father mother
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+deallocate prepare stmt;
+#
+# MDEV-10881: execution of prepared statement from
+# CREATE ... SELECT, INSERT ... SELECT
+#
+prepare stmt from"
+create table my_ancestors
+with recursive
+ancestor_ids (id)
+as
+(
+ select father from folks where name = 'Me'
+ union
+ select mother from folks where name = 'Me'
+ union
+ select father from folks, ancestor_ids a where folks.id = a.id
+ union
+ select mother from folks, ancestor_ids a where folks.id = a.id
+)
+select p.* from folks as p, ancestor_ids as a where p.id = a.id;
+";
+execute stmt;
+deallocate prepare stmt;
+select * from my_ancestors;
+id name dob father mother
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+delete from my_ancestors;
+prepare stmt from"
+insert into my_ancestors
+with recursive
+ancestor_ids (id)
+as
+(
+ select father from folks where name = 'Me'
+ union
+ select mother from folks where name = 'Me'
+ union
+ select father from folks, ancestor_ids a where folks.id = a.id
+ union
+ select mother from folks, ancestor_ids a where folks.id = a.id
+)
+select p.* from folks as p, ancestor_ids as a where p.id = a.id;
+";
+execute stmt;
+deallocate prepare stmt;
+select * from my_ancestors;
+id name dob father mother
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+drop table my_ancestors;
+#
+# MDEV-10933: WITH clause together with SELECT in parenthesis
+# CREATE SELECT
+#
+create table my_ancestors
+(
+with recursive
+ancestor_ids (id)
+as
+(
+select father from folks where name = 'Me'
+ union
+select mother from folks where name = 'Me'
+ union
+select father from folks, ancestor_ids a where folks.id = a.id
+union
+select mother from folks, ancestor_ids a where folks.id = a.id
+)
+select p.* from folks as p, ancestor_ids as a where p.id = a.id
+);
+select * from my_ancestors;
+id name dob father mother
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+drop table my_ancestors;
+drop table folks;
+#
+# MDEV-10372: [bb-10.2-mdev9864 tree] EXPLAIN with recursive CTE enters endless recursion
+#
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+explain format=json
+with recursive t as (select a from t1 union select a+10 from t where a < 1000)
+select * from t;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 10,
+ "filtered": 100,
+ "materialized": {
+ "query_block": {
+ "recursive_union": {
+ "table_name": "<union2,3>",
+ "access_type": "ALL",
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 10,
+ "filtered": 100
+ }
+ }
+ ]
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "UNION",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 10,
+ "filtered": 100,
+ "attached_condition": "t.a < 1000"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+}
+drop table t1;
+#
+# MDEV-10737: recursive union with several anchors at the end
+#
+WITH RECURSIVE cte(n) AS
+( SELECT n+1 FROM cte WHERE n < 5 UNION SELECT 1 UNION SELECT 1 )
+SELECT * FROM cte;
+n
+1
+2
+3
+4
+5
+#
+# MDEV-10736: recursive definition with anchor over a table with blob
+#
+CREATE TABLE t1 (f VARCHAR(1024));
+WITH RECURSIVE cte(f) AS
+(SELECT t1.f FROM t1 UNION ALL SELECT cte.f FROM cte)
+SELECT * FROM cte as t;
+f
+DROP TABLE t1;
+#
+# MDEV-10899: mergeable derived in the spec of recursive CTE
+#
+create table t1 (a int);
+insert into t1 values
+(0), (1), (2), (3), (4);
+create table t2 (a int);
+insert into t2 values
+(1), (2), (3), (4), (5);
+with recursive
+t1 as
+(
+select x.a from (select a from t2 where t2.a=3) x
+union
+select t2.a from t1,t2 where t1.a+1=t2.a
+)
+select * from t1;
+a
+3
+4
+5
+explain
+with recursive
+t1 as
+(
+select x.a from (select a from t2 where t2.a=3) x
+union
+select t2.a from t1,t2 where t1.a+1=t2.a
+)
+select * from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
+2 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where
+4 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 5
+4 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
+NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL
+drop table t1,t2;
+#
+# MDEV-11278: non-mergeable view in the spec of recursive CTE
+#
+create table t1 (a int);
+insert into t1 values
+(0), (1), (2), (3), (4);
+create table t2 (a int);
+insert into t2 values
+(1), (2), (3), (4), (5);
+create view v1 as
+select a from t2 where a < 3
+union
+select a from t2 where a > 4;
+with recursive
+t1 as
+(
+select a from v1 where a=1
+union
+select v1.a from t1,v1 where t1.a+1=v1.a
+)
+select * from t1;
+a
+1
+2
+drop view v1;
+drop table t1,t2;
+#
+# MDEV-11259: recursive CTE with concatenation operation
+#
+DROP TABLE IF EXISTS edges;
+Warnings:
+Note 1051 Unknown table 'test.edges'
+CREATE TABLE edges(
+a int(10) unsigned NOT NULL,
+b int(10) unsigned NOT NULL,
+PRIMARY KEY (a,b),
+KEY b(b)
+);
+INSERT INTO edges
+VALUES (1,3),(2,1),(2,4),(3,4),(3,5),(3,6),(4,7),(5,1),(5,6),(6,1);
+DROP TABLE IF EXISTS edges2;
+Warnings:
+Note 1051 Unknown table 'test.edges2'
+CREATE VIEW edges2 (a, b) AS
+SELECT a, b FROM edges UNION ALL SELECT b, a FROM edges;
+WITH RECURSIVE transitive_closure(a, b, distance, path_string) AS
+( SELECT a, b, 1 AS distance,
+concat(a, '.', b, '.') AS path_string
+FROM edges
+UNION ALL
+SELECT tc.a, e.b, tc.distance + 1,
+concat(tc.path_string, e.b, '.') AS path_string
+FROM edges AS e
+JOIN transitive_closure AS tc
+ON e.a = tc.b
+WHERE tc.path_string NOT LIKE concat('%', e.b, '.%')
+)
+SELECT * FROM transitive_closure
+ORDER BY a, b, distance;
+a b distance path_string
+1 3 1 1.3.
+1 4 2 1.3.4.
+1 5 2 1.3.5.
+1 6 2 1.3.6.
+1 6 3 1.3.5.6.
+1 7 3 1.3.4.7.
+2 1 1 2.1.
+2 3 2 2.1.3.
+2 4 1 2.4.
+2 4 3 2.1.3.4.
+2 5 3 2.1.3.5.
+2 6 3 2.1.3.6.
+2 6 4 2.1.3.5.6.
+2 7 2 2.4.7.
+2 7 4 2.1.3.4.7.
+3 1 2 3.5.1.
+3 1 2 3.6.1.
+3 1 3 3.5.6.1.
+3 4 1 3.4.
+3 5 1 3.5.
+3 6 1 3.6.
+3 6 2 3.5.6.
+3 7 2 3.4.7.
+4 7 1 4.7.
+5 1 1 5.1.
+5 1 2 5.6.1.
+5 3 2 5.1.3.
+5 3 3 5.6.1.3.
+5 4 3 5.1.3.4.
+5 4 4 5.6.1.3.4.
+5 6 1 5.6.
+5 6 3 5.1.3.6.
+5 7 4 5.1.3.4.7.
+5 7 5 5.6.1.3.4.7.
+6 1 1 6.1.
+6 3 2 6.1.3.
+6 4 3 6.1.3.4.
+6 5 3 6.1.3.5.
+6 7 4 6.1.3.4.7.
+WITH RECURSIVE transitive_closure(a, b, distance, path_string) AS
+( SELECT a, b, 1 AS distance,
+concat(a, '.', b, '.') AS path_string
+FROM edges
+WHERE a = 1 -- source
+UNION ALL
+SELECT tc.a, e.b, tc.distance + 1,
+concat(tc.path_string, e.b, '.') AS path_string
+FROM edges AS e
+JOIN transitive_closure AS tc ON e.a = tc.b
+WHERE tc.path_string NOT LIKE concat('%', e.b, '.%')
+)
+SELECT * FROM transitive_closure
+WHERE b = 6 -- destination
+ORDER BY a, b, distance;
+a b distance path_string
+1 6 2 1.3.6.
+1 6 3 1.3.5.6.
+WITH RECURSIVE transitive_closure(a, b, distance, path_string) AS
+( SELECT a, b, 1 AS distance,
+concat(a, '.', b, '.') AS path_string
+FROM edges2
+UNION ALL
+SELECT tc.a, e.b, tc.distance + 1,
+concat(tc.path_string, e.b, '.') AS path_string
+FROM edges2 AS e
+JOIN transitive_closure AS tc ON e.a = tc.b
+WHERE tc.path_string NOT LIKE concat('%', e.b, '.%')
+)
+SELECT * FROM transitive_closure
+ORDER BY a, b, distance;
+a b distance path_string
+1 2 1 1.2.
+1 2 3 1.3.4.2.
+1 2 4 1.5.3.4.2.
+1 2 4 1.6.3.4.2.
+1 2 5 1.5.6.3.4.2.
+1 2 5 1.6.5.3.4.2.
+1 3 1 1.3.
+1 3 2 1.5.3.
+1 3 2 1.6.3.
+1 3 3 1.2.4.3.
+1 3 3 1.5.6.3.
+1 3 3 1.6.5.3.
+1 4 2 1.2.4.
+1 4 2 1.3.4.
+1 4 3 1.5.3.4.
+1 4 3 1.6.3.4.
+1 4 4 1.5.6.3.4.
+1 4 4 1.6.5.3.4.
+1 5 1 1.5.
+1 5 2 1.3.5.
+1 5 2 1.6.5.
+1 5 3 1.3.6.5.
+1 5 3 1.6.3.5.
+1 5 4 1.2.4.3.5.
+1 5 5 1.2.4.3.6.5.
+1 6 1 1.6.
+1 6 2 1.3.6.
+1 6 2 1.5.6.
+1 6 3 1.3.5.6.
+1 6 3 1.5.3.6.
+1 6 4 1.2.4.3.6.
+1 6 5 1.2.4.3.5.6.
+1 7 3 1.2.4.7.
+1 7 3 1.3.4.7.
+1 7 4 1.5.3.4.7.
+1 7 4 1.6.3.4.7.
+1 7 5 1.5.6.3.4.7.
+1 7 5 1.6.5.3.4.7.
+2 1 1 2.1.
+2 1 3 2.4.3.1.
+2 1 4 2.4.3.5.1.
+2 1 4 2.4.3.6.1.
+2 1 5 2.4.3.5.6.1.
+2 1 5 2.4.3.6.5.1.
+2 3 2 2.1.3.
+2 3 2 2.4.3.
+2 3 3 2.1.5.3.
+2 3 3 2.1.6.3.
+2 3 4 2.1.5.6.3.
+2 3 4 2.1.6.5.3.
+2 4 1 2.4.
+2 4 3 2.1.3.4.
+2 4 4 2.1.5.3.4.
+2 4 4 2.1.6.3.4.
+2 4 5 2.1.5.6.3.4.
+2 4 5 2.1.6.5.3.4.
+2 5 2 2.1.5.
+2 5 3 2.1.3.5.
+2 5 3 2.1.6.5.
+2 5 3 2.4.3.5.
+2 5 4 2.1.3.6.5.
+2 5 4 2.1.6.3.5.
+2 5 4 2.4.3.1.5.
+2 5 4 2.4.3.6.5.
+2 5 5 2.4.3.1.6.5.
+2 5 5 2.4.3.6.1.5.
+2 6 2 2.1.6.
+2 6 3 2.1.3.6.
+2 6 3 2.1.5.6.
+2 6 3 2.4.3.6.
+2 6 4 2.1.3.5.6.
+2 6 4 2.1.5.3.6.
+2 6 4 2.4.3.1.6.
+2 6 4 2.4.3.5.6.
+2 6 5 2.4.3.1.5.6.
+2 6 5 2.4.3.5.1.6.
+2 7 2 2.4.7.
+2 7 4 2.1.3.4.7.
+2 7 5 2.1.5.3.4.7.
+2 7 5 2.1.6.3.4.7.
+2 7 6 2.1.5.6.3.4.7.
+2 7 6 2.1.6.5.3.4.7.
+3 1 1 3.1.
+3 1 2 3.5.1.
+3 1 2 3.6.1.
+3 1 3 3.4.2.1.
+3 1 3 3.5.6.1.
+3 1 3 3.6.5.1.
+3 2 2 3.1.2.
+3 2 2 3.4.2.
+3 2 3 3.5.1.2.
+3 2 3 3.6.1.2.
+3 2 4 3.5.6.1.2.
+3 2 4 3.6.5.1.2.
+3 4 1 3.4.
+3 4 3 3.1.2.4.
+3 4 4 3.5.1.2.4.
+3 4 4 3.6.1.2.4.
+3 4 5 3.5.6.1.2.4.
+3 4 5 3.6.5.1.2.4.
+3 5 1 3.5.
+3 5 2 3.1.5.
+3 5 2 3.6.5.
+3 5 3 3.1.6.5.
+3 5 3 3.6.1.5.
+3 5 4 3.4.2.1.5.
+3 5 5 3.4.2.1.6.5.
+3 6 1 3.6.
+3 6 2 3.1.6.
+3 6 2 3.5.6.
+3 6 3 3.1.5.6.
+3 6 3 3.5.1.6.
+3 6 4 3.4.2.1.6.
+3 6 5 3.4.2.1.5.6.
+3 7 2 3.4.7.
+3 7 4 3.1.2.4.7.
+3 7 5 3.5.1.2.4.7.
+3 7 5 3.6.1.2.4.7.
+3 7 6 3.5.6.1.2.4.7.
+3 7 6 3.6.5.1.2.4.7.
+4 1 2 4.2.1.
+4 1 2 4.3.1.
+4 1 3 4.3.5.1.
+4 1 3 4.3.6.1.
+4 1 4 4.3.5.6.1.
+4 1 4 4.3.6.5.1.
+4 2 1 4.2.
+4 2 3 4.3.1.2.
+4 2 4 4.3.5.1.2.
+4 2 4 4.3.6.1.2.
+4 2 5 4.3.5.6.1.2.
+4 2 5 4.3.6.5.1.2.
+4 3 1 4.3.
+4 3 3 4.2.1.3.
+4 3 4 4.2.1.5.3.
+4 3 4 4.2.1.6.3.
+4 3 5 4.2.1.5.6.3.
+4 3 5 4.2.1.6.5.3.
+4 5 2 4.3.5.
+4 5 3 4.2.1.5.
+4 5 3 4.3.1.5.
+4 5 3 4.3.6.5.
+4 5 4 4.2.1.3.5.
+4 5 4 4.2.1.6.5.
+4 5 4 4.3.1.6.5.
+4 5 4 4.3.6.1.5.
+4 5 5 4.2.1.3.6.5.
+4 5 5 4.2.1.6.3.5.
+4 6 2 4.3.6.
+4 6 3 4.2.1.6.
+4 6 3 4.3.1.6.
+4 6 3 4.3.5.6.
+4 6 4 4.2.1.3.6.
+4 6 4 4.2.1.5.6.
+4 6 4 4.3.1.5.6.
+4 6 4 4.3.5.1.6.
+4 6 5 4.2.1.3.5.6.
+4 6 5 4.2.1.5.3.6.
+4 7 1 4.7.
+5 1 1 5.1.
+5 1 2 5.3.1.
+5 1 2 5.6.1.
+5 1 3 5.3.6.1.
+5 1 3 5.6.3.1.
+5 1 4 5.3.4.2.1.
+5 1 5 5.6.3.4.2.1.
+5 2 2 5.1.2.
+5 2 3 5.3.1.2.
+5 2 3 5.3.4.2.
+5 2 3 5.6.1.2.
+5 2 4 5.1.3.4.2.
+5 2 4 5.3.6.1.2.
+5 2 4 5.6.3.1.2.
+5 2 4 5.6.3.4.2.
+5 2 5 5.1.6.3.4.2.
+5 2 5 5.6.1.3.4.2.
+5 3 1 5.3.
+5 3 2 5.1.3.
+5 3 2 5.6.3.
+5 3 3 5.1.6.3.
+5 3 3 5.6.1.3.
+5 3 4 5.1.2.4.3.
+5 3 5 5.6.1.2.4.3.
+5 4 2 5.3.4.
+5 4 3 5.1.2.4.
+5 4 3 5.1.3.4.
+5 4 3 5.6.3.4.
+5 4 4 5.1.6.3.4.
+5 4 4 5.3.1.2.4.
+5 4 4 5.6.1.2.4.
+5 4 4 5.6.1.3.4.
+5 4 5 5.3.6.1.2.4.
+5 4 5 5.6.3.1.2.4.
+5 6 1 5.6.
+5 6 2 5.1.6.
+5 6 2 5.3.6.
+5 6 3 5.1.3.6.
+5 6 3 5.3.1.6.
+5 6 5 5.1.2.4.3.6.
+5 6 5 5.3.4.2.1.6.
+5 7 3 5.3.4.7.
+5 7 4 5.1.2.4.7.
+5 7 4 5.1.3.4.7.
+5 7 4 5.6.3.4.7.
+5 7 5 5.1.6.3.4.7.
+5 7 5 5.3.1.2.4.7.
+5 7 5 5.6.1.2.4.7.
+5 7 5 5.6.1.3.4.7.
+5 7 6 5.3.6.1.2.4.7.
+5 7 6 5.6.3.1.2.4.7.
+6 1 1 6.1.
+6 1 2 6.3.1.
+6 1 2 6.5.1.
+6 1 3 6.3.5.1.
+6 1 3 6.5.3.1.
+6 1 4 6.3.4.2.1.
+6 1 5 6.5.3.4.2.1.
+6 2 2 6.1.2.
+6 2 3 6.3.1.2.
+6 2 3 6.3.4.2.
+6 2 3 6.5.1.2.
+6 2 4 6.1.3.4.2.
+6 2 4 6.3.5.1.2.
+6 2 4 6.5.3.1.2.
+6 2 4 6.5.3.4.2.
+6 2 5 6.1.5.3.4.2.
+6 2 5 6.5.1.3.4.2.
+6 3 1 6.3.
+6 3 2 6.1.3.
+6 3 2 6.5.3.
+6 3 3 6.1.5.3.
+6 3 3 6.5.1.3.
+6 3 4 6.1.2.4.3.
+6 3 5 6.5.1.2.4.3.
+6 4 2 6.3.4.
+6 4 3 6.1.2.4.
+6 4 3 6.1.3.4.
+6 4 3 6.5.3.4.
+6 4 4 6.1.5.3.4.
+6 4 4 6.3.1.2.4.
+6 4 4 6.5.1.2.4.
+6 4 4 6.5.1.3.4.
+6 4 5 6.3.5.1.2.4.
+6 4 5 6.5.3.1.2.4.
+6 5 1 6.5.
+6 5 2 6.1.5.
+6 5 2 6.3.5.
+6 5 3 6.1.3.5.
+6 5 3 6.3.1.5.
+6 5 5 6.1.2.4.3.5.
+6 5 5 6.3.4.2.1.5.
+6 7 3 6.3.4.7.
+6 7 4 6.1.2.4.7.
+6 7 4 6.1.3.4.7.
+6 7 4 6.5.3.4.7.
+6 7 5 6.1.5.3.4.7.
+6 7 5 6.3.1.2.4.7.
+6 7 5 6.5.1.2.4.7.
+6 7 5 6.5.1.3.4.7.
+6 7 6 6.3.5.1.2.4.7.
+6 7 6 6.5.3.1.2.4.7.
+7 1 3 7.4.2.1.
+7 1 3 7.4.3.1.
+7 1 4 7.4.3.5.1.
+7 1 4 7.4.3.6.1.
+7 1 5 7.4.3.5.6.1.
+7 1 5 7.4.3.6.5.1.
+7 2 2 7.4.2.
+7 2 4 7.4.3.1.2.
+7 2 5 7.4.3.5.1.2.
+7 2 5 7.4.3.6.1.2.
+7 2 6 7.4.3.5.6.1.2.
+7 2 6 7.4.3.6.5.1.2.
+7 3 2 7.4.3.
+7 3 4 7.4.2.1.3.
+7 3 5 7.4.2.1.5.3.
+7 3 5 7.4.2.1.6.3.
+7 3 6 7.4.2.1.5.6.3.
+7 3 6 7.4.2.1.6.5.3.
+7 4 1 7.4.
+7 5 3 7.4.3.5.
+7 5 4 7.4.2.1.5.
+7 5 4 7.4.3.1.5.
+7 5 4 7.4.3.6.5.
+7 5 5 7.4.2.1.3.5.
+7 5 5 7.4.2.1.6.5.
+7 5 5 7.4.3.1.6.5.
+7 5 5 7.4.3.6.1.5.
+7 5 6 7.4.2.1.3.6.5.
+7 5 6 7.4.2.1.6.3.5.
+7 6 3 7.4.3.6.
+7 6 4 7.4.2.1.6.
+7 6 4 7.4.3.1.6.
+7 6 4 7.4.3.5.6.
+7 6 5 7.4.2.1.3.6.
+7 6 5 7.4.2.1.5.6.
+7 6 5 7.4.3.1.5.6.
+7 6 5 7.4.3.5.1.6.
+7 6 6 7.4.2.1.3.5.6.
+7 6 6 7.4.2.1.5.3.6.
+WITH RECURSIVE transitive_closure(a, b, distance, path_string)
+AS
+( SELECT a, b, 1 AS distance,
+concat(a, '.', b, '.') AS path_string
+FROM edges2
+UNION ALL
+SELECT tc.a, e.b, tc.distance + 1,
+concat(tc.path_string, e.b, '.') AS path_string
+FROM edges2 AS e
+JOIN transitive_closure AS tc ON e.a = tc.b
+WHERE tc.path_string NOT LIKE concat('%', e.b, '.%')
+)
+SELECT a, b, min(distance) AS dist FROM transitive_closure
+GROUP BY a, b
+ORDER BY a, dist, b;
+a b dist
+1 2 1
+1 3 1
+1 4 2
+1 5 1
+1 6 1
+1 7 3
+2 1 1
+2 3 2
+2 4 1
+2 5 2
+2 6 2
+2 7 2
+3 1 1
+3 2 2
+3 4 1
+3 5 1
+3 6 1
+3 7 2
+4 1 2
+4 2 1
+4 3 1
+4 5 2
+4 6 2
+4 7 1
+5 1 1
+5 2 2
+5 3 1
+5 4 2
+5 6 1
+5 7 3
+6 1 1
+6 2 2
+6 3 1
+6 4 2
+6 5 1
+6 7 3
+7 1 3
+7 2 2
+7 3 2
+7 4 1
+7 5 3
+7 6 3
+DROP VIEW edges2;
+DROP TABLE edges;
+#
+# MDEV-11674: recursive CTE table that cannot be stored
+# in a heap table
+#
+create table t1 (id int, test_data varchar(36));
+set @save_max_recursive_iterations= @@max_recursive_iterations;
+set max_recursive_iterations= 200000;
+insert into t1(id, test_data)
+select id, test_data
+from (
+with recursive data_generator(id, test_data) as (
+select 1 as id, uuid() as test_data
+union all
+select id + 1, uuid() from data_generator where id < 150000
+)
+select * from data_generator
+) as a;
+drop table t1;
+set max_recursive_iterations= @save_max_recursive_iterations;
+#
+# MDEV-10773: ANALYZE for query with recursive CTE
+#
+analyze format=json
+with recursive src(counter) as
+(select 1
+union
+select counter+1 from src where counter<10
+) select * from src;
+ANALYZE
+{
+ "query_optimization": {
+ "r_total_time_ms": "REPLACED"
+ },
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "r_loops": 1,
+ "rows": 2,
+ "r_rows": 10,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 100,
+ "r_filtered": 100,
+ "materialized": {
+ "query_block": {
+ "recursive_union": {
+ "table_name": "<union2,3>",
+ "access_type": "ALL",
+ "r_loops": 0,
+ "r_rows": null,
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "message": "No tables used"
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "UNION",
+ "r_loops": 10,
+ "r_total_time_ms": "REPLACED",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "r_loops": 10,
+ "rows": 2,
+ "r_rows": 1,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 100,
+ "r_filtered": 90,
+ "attached_condition": "src.counter < 10"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+}
+#
+# mdev-12360: recursive reference in left operand of LEFT JOIN
+#
+create table folks(id int, name char(32), dob date, father int, mother int);
+insert into folks values
+(100, 'Me', '2000-01-01', 20, 30),
+(20, 'Dad', '1970-02-02', 10, 9),
+(30, 'Mom', '1975-03-03', 8, 7),
+(10, 'Grandpa Bill', '1940-04-05', null, null),
+(9, 'Grandma Ann', '1941-10-15', null, null),
+(25, 'Uncle Jim', '1968-11-18', 8, 7),
+(98, 'Sister Amy', '2001-06-20', 20, 30),
+(7, 'Grandma Sally', '1943-08-23', null, 6),
+(8, 'Grandpa Ben', '1940-10-21', null, null),
+(6, 'Grandgrandma Martha', '1923-05-17', null, null),
+(67, 'Cousin Eddie', '1992-02-28', 25, 27),
+(27, 'Auntie Melinda', '1971-03-29', null, null);
+with recursive
+ancestor_ids (id)
+as
+(
+select father from folks where name = 'Me'
+ union
+select mother from folks where name = 'Me'
+ union
+select father from ancestor_ids as a left join folks on folks.id = a.id
+union
+select mother from ancestor_ids as a left join folks on folks.id = a.id
+),
+ancestors
+as
+(
+select p.* from folks as p, ancestor_ids as a
+where p.id = a.id
+)
+select * from ancestors;
+id name dob father mother
+20 Dad 1970-02-02 10 9
+30 Mom 1975-03-03 8 7
+10 Grandpa Bill 1940-04-05 NULL NULL
+9 Grandma Ann 1941-10-15 NULL NULL
+7 Grandma Sally 1943-08-23 NULL 6
+8 Grandpa Ben 1940-10-21 NULL NULL
+6 Grandgrandma Martha 1923-05-17 NULL NULL
+drop table folks;
+#
+# mdev-12368: crash with mutually recursive CTE
+# that arenot Standard compliant
+#
+create table value_nodes (v char(4));
+create table module_nodes(m char(4));
+create table module_arguments(m char(4), v char(4));
+create table module_results(m char(4), v char(4));
+with recursive
+reached_values as
+(
+select v from value_nodes where v in ('v3','v7','v9')
+union
+select module_results.v from module_results, applied_modules
+where module_results.m = applied_modules.m
+),
+applied_modules as
+(
+select module_nodes.m
+from
+module_nodes
+left join
+(
+module_arguments
+left join
+reached_values
+on module_arguments.v = reached_values.v
+)
+on reached_values.v is null and
+module_nodes.m = module_arguments.m
+where module_arguments.m is null
+)
+select * from reached_values;
+ERROR HY000: Restrictions imposed on recursive definitions are violated for table 'applied_modules'
+drop table value_nodes, module_nodes, module_arguments, module_results;
+#
+# mdev-12375: query using one of two mutually recursive CTEs
+# whose non-recursive part returns an empty set
+#
+create table value_nodes (v char(4));
+insert into value_nodes values
+('v1'), ('v2'), ('v3'), ('v4'), ('v5'), ('v6'), ('v7'), ('v8'), ('v9'),
+('v10'), ('v11'), ('v12'), ('v13'), ('v14'), ('v15'), ('v16');
+create table module_nodes(m char(4));
+insert into module_nodes values
+('m1'), ('m2'), ('m3'), ('m4'), ('m5'), ('m6'), ('m7');
+create table module_arguments(m char(4), v char(4));
+insert into module_arguments values
+('m1','v3'), ('m1','v9'),
+('m2','v4'), ('m2','v3'), ('m2','v7'),
+('m3','v6'),
+('m4','v4'), ('m4','v1'),
+('m5','v10'), ('m5','v8'), ('m5','v3'),
+('m6','v8'), ('m6','v1'),
+('m7','v11'), ('m7','v12');
+create table module_results(m char(4), v char(4));
+insert into module_results values
+('m1','v4'),
+('m2','v1'), ('m2','v6'),
+('m3','v10'),
+('m4','v8'),
+('m5','v11'), ('m5','v9'),
+('m6','v12'), ('m6','v4'),
+('m7','v2');
+set statement max_recursive_iterations=2, standard_compliant_cte=0 for
+with recursive
+reached_values as
+(
+select v from value_nodes where v in ('v3','v7','v9')
+union
+select module_results.v from module_results, applied_modules
+where module_results.m = applied_modules.m
+),
+applied_modules as
+(
+select * from module_nodes where 1=0
+union
+select module_nodes.m
+from
+module_nodes
+left join
+(
+module_arguments
+left join
+reached_values
+on module_arguments.v = reached_values.v
+)
+on reached_values.v is null and
+module_nodes.m = module_arguments.m
+where module_arguments.m is null
+)
+select * from applied_modules;
+m
+m1
+m2
+Warnings:
+Warning 1931 Query execution was interrupted. The query exceeded max_recursive_iterations = 2. The query result may be incomplete
+drop table value_nodes, module_nodes, module_arguments, module_results;
+#
+# mdev-12519: recursive references in subqueries
+#
+create table t1 (lp char(4) not null, rp char(4) not null);
+insert into t1 values
+('p1','p2'), ('p2','p3'), ('p3','p4'), ('p4','p5'),
+('p2','p7'), ('p7','p8'), ('p8','p3'), ('p8','p4');
+set standard_compliant_cte=0;
+with recursive
+reachables(p) as
+(
+select lp from t1 where lp = 'p1'
+ union
+select t1.rp from reachables, t1
+where t1.lp = reachables.p
+)
+select * from reachables;
+p
+p1
+p2
+p3
+p7
+p4
+p8
+p5
+with recursive
+reachables(p) as
+(
+select lp from t1 where lp = 'p1'
+ union
+select t1.rp from reachables, t1
+where 'p3' not in (select * from reachables) and
+t1.lp = reachables.p
+)
+select * from reachables;
+p
+p1
+p2
+p3
+p7
+with recursive
+reachables(p) as
+(
+select lp from t1 where lp = 'p1'
+ union
+select t1.rp from reachables, t1
+where 'p3' not in (select p from reachables where p <= 'p5'
+ union
+select p from reachables where p > 'p5') and
+t1.lp = reachables.p
+)
+select * from reachables;
+p
+p1
+p2
+p3
+p7
+prepare stmt from "
+with recursive
+reachables(p) as
+(
+ select lp from t1 where lp = 'p1'
+ union
+ select t1.rp from reachables, t1
+ where 'p3' not in (select p from reachables where p <= 'p5'
+ union
+ select p from reachables where p > 'p5') and
+ t1.lp = reachables.p
+)
+select * from reachables;
+";
+execute stmt;
+p
+p1
+p2
+p3
+p7
+execute stmt;
+p
+p1
+p2
+p3
+p7
+deallocate prepare stmt;
+drop table t1;
+create table objects(v char(4) not null);
+insert into objects values
+('v1'), ('v2'), ('v3'), ('v4'), ('v5'),
+('v6'), ('v7'), ('v8'), ('v9'), ('v10');
+create table modules(m char(4) not null);
+insert into modules values
+('m1'), ('m2'), ('m3'), ('m4');
+create table module_arguments(m char(4) not null, v char(4) not null);
+insert into module_arguments values
+('m1','v3'), ('m1','v9'),
+('m2','v4'), ('m2','v7'),
+('m3','v6'), ('m4','v2');
+create table module_results(m char(4) not null, v char(4) not null);
+insert into module_results values
+('m1','v4'),
+('m2','v1'), ('m2','v6'),
+('m3','v10'), ('m4','v7');
+set standard_compliant_cte=0;
+with recursive
+reached_objects as
+(
+select v, 'init' as m from objects where v in ('v3','v7','v9')
+union
+select module_results.v, module_results.m from module_results, applied_modules
+where module_results.m = applied_modules.m
+),
+applied_modules as
+(
+select * from modules where 1=0
+union
+select modules.m
+from
+modules
+where
+not exists (select * from module_arguments
+where module_arguments.m = modules.m and
+module_arguments.v not in
+(select v from reached_objects))
+)
+select * from reached_objects;
+v m
+v3 init
+v7 init
+v9 init
+v4 m1
+v1 m2
+v6 m2
+v10 m3
+with recursive
+reached_objects as
+(
+select v, 'init' as m from objects where v in ('v3','v7','v9')
+union
+select module_results.v, module_results.m from module_results, applied_modules
+where module_results.m = applied_modules.m
+),
+applied_modules as
+(
+select * from modules where 1=0
+union
+select modules.m
+from
+modules
+where
+'v6' not in (select v from reached_objects) and
+not exists (select * from module_arguments
+where module_arguments.m = modules.m and
+module_arguments.v not in
+(select v from reached_objects))
+)
+select * from reached_objects;
+v m
+v3 init
+v7 init
+v9 init
+v4 m1
+v1 m2
+v6 m2
+prepare stmt from "
+with recursive
+reached_objects as
+(
+ select v, 'init' as m from objects where v in ('v3','v7','v9')
+ union
+ select module_results.v, module_results.m from module_results, applied_modules
+ where module_results.m = applied_modules.m
+),
+applied_modules as
+(
+ select * from modules where 1=0
+ union
+ select modules.m
+ from
+ modules
+ where
+ 'v6' not in (select v from reached_objects) and
+ not exists (select * from module_arguments
+ where module_arguments.m = modules.m and
+ module_arguments.v not in
+ (select v from reached_objects))
+)
+select * from reached_objects;
+";
+execute stmt;
+v m
+v3 init
+v7 init
+v9 init
+v4 m1
+v1 m2
+v6 m2
+execute stmt;
+v m
+v3 init
+v7 init
+v9 init
+v4 m1
+v1 m2
+v6 m2
+deallocate prepare stmt;
+drop table objects, modules, module_arguments, module_results;
+set standard_compliant_cte=default;
+select @@standard_compliant_cte;
+@@standard_compliant_cte
+1
+#
+# mdev-12554: impossible where in recursive select
+#
+CREATE TABLE t1 (i int);
+INSERT INTO t1 VALUES (1),(2);
+WITH RECURSIVE
+cte(f) AS ( SELECT i FROM t1 UNION SELECT f FROM t1, cte WHERE 1=0 )
+SELECT * FROM cte;
+f
+1
+2
+DROP TABLE t1;
+#
+# mdev-12556: recursive execution uses Aria temporary tables
+#
+CREATE TABLE t (c1 varchar(255), c2 tinytext);
+INSERT INTO t VALUES ('a','a'),('b','b'),('c','c'),('d','d');
+ANALYZE WITH RECURSIVE cte(f) AS (
+SELECT c1 FROM t
+UNION
+SELECT c1 FROM t, cte
+) SELECT COUNT(*) FROM cte;
+id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
+2 DERIVED t ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
+3 RECURSIVE UNION t ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
+3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 4 4.00 100.00 100.00 Using join buffer (flat, BNL join)
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL 0.00 NULL NULL
+WITH RECURSIVE cte(f) AS (
+SELECT c1 FROM t
+UNION
+SELECT c1 FROM t, cte
+) SELECT COUNT(*) FROM cte;
+COUNT(*)
+4
+ANALYZE WITH RECURSIVE cte(f) AS (
+SELECT c2 FROM t
+UNION
+SELECT c2 FROM t, cte
+) SELECT COUNT(*) FROM cte;
+id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
+2 DERIVED t ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
+3 RECURSIVE UNION t ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
+3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 4 4.00 100.00 100.00 Using join buffer (flat, BNL join)
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL 0.00 NULL NULL
+WITH RECURSIVE cte(f) AS (
+SELECT c2 FROM t
+UNION
+SELECT c2 FROM t, cte
+) SELECT COUNT(*) FROM cte;
+COUNT(*)
+4
+DROP TABLE t;
+#
+# mdev-12563: no recursive references on the top level of the CTE spec
+#
+CREATE TABLE t (i int);
+INSERT INTO t VALUES (3), (1),(2);
+SET standard_compliant_cte=0;
+WITH RECURSIVE cte(f) AS (
+SELECT i FROM t
+UNION
+SELECT i FROM t WHERE i NOT IN ( SELECT * FROM cte )
+) SELECT * FROM cte;
+f
+3
+1
+2
+WITH RECURSIVE cte(f) AS (
+SELECT i FROM t
+UNION
+SELECT i FROM t WHERE i NOT IN ( SELECT * FROM cte WHERE i < 2 )
+UNION
+SELECT i FROM t WHERE i NOT IN ( SELECT * FROM cte WHERE i > 2 )
+) SELECT * FROM cte;
+f
+3
+1
+2
+WITH RECURSIVE cte(f) AS (
+SELECT i FROM t
+UNION
+SELECT i FROM t
+WHERE i NOT IN ( SELECT * FROM cte WHERE i < 2
+UNION
+SELECT * FROM cte WHERE i > 2)
+) SELECT * FROM cte;
+f
+3
+1
+2
+WITH RECURSIVE cte(f) AS (
+SELECT i FROM t
+UNION
+SELECT i FROM t
+WHERE i NOT IN ( SELECT * FROM t
+WHERE i IN ( SELECT * FROM cte ) GROUP BY i )
+) SELECT * FROM cte;
+f
+3
+1
+2
+WITH RECURSIVE cte(f) AS (
+SELECT i FROM t
+UNION
+SELECT i FROM t WHERE i NOT IN ( SELECT * FROM cte )
+UNION
+SELECT * FROM cte WHERE f > 2
+) SELECT * FROM cte;
+f
+3
+1
+2
+set standard_compliant_cte=default;
+DROP TABLE t;
+#
+# mdev-14184: recursive CTE embedded into CTE with multiple references
+#
+WITH
+cte1 AS (
+SELECT n FROM (
+WITH RECURSIVE rec_cte(n) AS (
+SELECT 1 as n1
+UNION ALL
+SELECT n+1 as n2 FROM rec_cte WHERE n < 3
+) SELECT n FROM rec_cte
+) AS X
+),
+cte2 as (
+SELECT 2 FROM cte1
+)
+SELECT *
+FROM cte1;
+n
+1
+2
+3
+#
+# mdev-14629: a user-defined variable is defined by the recursive CTE
+#
+set @var=
+(
+with recursive cte_tab(a) as (
+select 1
+union
+select a+1 from cte_tab
+where a<3)
+select count(*) from cte_tab
+);
+select @var;
+@var
+3
+create table t1(a int, b int);
+insert into t1 values (3,8),(1,5),(5,7),(7,4),(4,3);
+set @var=
+(
+with recursive summ(a,s) as (
+select 1, 0 union
+select t1.b, t1.b+summ.s from summ, t1
+where summ.a=t1.a)
+select s from summ
+order by a desc
+limit 1
+);
+select @var;
+@var
+27
+set @var=
+(
+with recursive
+cte_1 as (
+select 1
+union
+select * from cte_2),
+cte_2 as (
+select * from cte_1
+union
+select a from t1, cte_2
+where t1.a=cte_2.a)
+select * from cte_2
+limit 1
+);
+ERROR HY000: Unacceptable mutual recursion with anchored table 'cte_1'
+drop table t1;
+#
+# mdev-14777: crash caused by the same as in mdev-14755
+#
+CREATE TABLE t1 (i1 int NOT NULL, i2 int);
+CREATE TABLE t2 (d1 int NOT NULL PRIMARY KEY);
+CREATE TABLE t3 (i int );
+insert into t1 select seq,seq from seq_1_to_100000;
+insert into t2 select seq from seq_1000_to_100000;
+insert into t3 select seq from seq_1_to_1000;
+SELECT *
+FROM
+(
+SELECT *
+FROM
+(
+WITH RECURSIVE rt AS
+(
+SELECT i2 P, i1 C FROM t1 WHERE i1 IN (SELECT d1 FROM t2)
+UNION
+SELECT t1.i2 P, rt.C C FROM t1, rt
+)
+SELECT C,P
+FROM ( SELECT P,C FROM rt WHERE NOT EXISTS (SELECT 1 FROM t1) ) Y
+) X
+WHERE 1 = 1
+) K, t3;
+C P i
+drop table t1,t2,t3;
+#
+# mdev-14879: subquery with recursive reference in WHERE of CTE
+#
+create table flights
+(departure varchar(32),
+arrival varchar(32),
+carrier varchar(20),
+flight_number char(7));
+insert into flights values
+('Seattle', 'Frankfurt', 'Lufthansa', 'LH 491'),
+('Seattle', 'Chicago', 'American', 'AA 2573'),
+('Seattle', 'Los Angeles', 'Alaska Air', 'AS 410'),
+('Chicago', 'New York', 'American', 'AA 375'),
+('Chicago', 'Montreal', 'Air Canada', 'AC 3053'),
+('Los Angeles', 'New York', 'Delta', 'DL 1197'),
+('Moscow', 'Tokyo', 'Aeroflot', 'SU 264'),
+('New York', 'Paris', 'Air France', 'AF 23'),
+('Frankfurt', 'Moscow', 'Lufthansa', 'LH 1444'),
+('Tokyo', 'Seattle', 'ANA', 'NH 178'),
+('Los Angeles', 'Tokyo', 'ANA', 'NH 175'),
+('Moscow', 'Los Angeles', 'Aeroflot', 'SU 106'),
+('Montreal', 'Paris', 'Air Canada', 'AC 870'),
+('Cairo', 'Paris', 'Air France', 'AF 503'),
+('New York', 'Seattle', 'American', 'AA 45'),
+('Paris', 'Chicago', 'Air France', 'AF 6734');
+with recursive destinations (city) as
+( select a.arrival from flights a where a.departure='Cairo'
+ union
+select b.arrival from destinations r, flights b where r.city=b.departure)
+select * from destinations;
+city
+Paris
+Chicago
+New York
+Montreal
+Seattle
+Frankfurt
+Los Angeles
+Moscow
+Tokyo
+set standard_compliant_cte=0;
+with recursive destinations (city, legs) as
+(
+select a.arrival, 1 from flights a where a.departure='Cairo'
+ union
+select b.arrival, r.legs + 1 from destinations r, flights b
+where r.city=b.departure and b.arrival not in (select city from destinations)
+)
+select * from destinations;
+city legs
+Paris 1
+Chicago 2
+New York 3
+Montreal 3
+Seattle 4
+Frankfurt 5
+Los Angeles 5
+Moscow 6
+Tokyo 6
+explain extended with recursive destinations (city, legs) as
+(
+select a.arrival, 1 from flights a where a.departure='Cairo'
+ union
+select b.arrival, r.legs + 1 from destinations r, flights b
+where r.city=b.departure and b.arrival not in (select city from destinations)
+)
+select * from destinations;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 16 100.00
+2 DERIVED a ALL NULL NULL NULL NULL 16 100.00 Using where
+3 RECURSIVE UNION b ALL NULL NULL NULL NULL 16 100.00 Using where
+3 RECURSIVE UNION <derived2> ref key0 key0 35 test.b.departure 2 100.00
+4 DEPENDENT SUBQUERY <derived2> ALL NULL NULL NULL NULL 16 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 with recursive destinations(`city`,`legs`) as (/* select#2 */ select `test`.`a`.`arrival` AS `city`,1 AS `legs` from `test`.`flights` `a` where `test`.`a`.`departure` = 'Cairo' union /* select#3 */ select `test`.`b`.`arrival` AS `arrival`,`r`.`legs` + 1 AS `r.legs + 1` from `destinations` `r` join `test`.`flights` `b` where `r`.`city` = `test`.`b`.`departure` and !(<in_optimizer>(`test`.`b`.`arrival`,<exists>(/* select#4 */ select `destinations`.`city` from `destinations` where trigcond(`test`.`b`.`arrival` = `destinations`.`city` or `destinations`.`city` is null) having trigcond(`destinations`.`city` is null)))))/* select#1 */ select `destinations`.`city` AS `city`,`destinations`.`legs` AS `legs` from `destinations`
+set standard_compliant_cte=default;
+drop table flights;
+#
+# MDEV-15162: Setting user variable in recursive CTE
+#
+SET @c=1;
+WITH RECURSIVE cte AS
+(SELECT 5
+UNION
+SELECT @c:=@c+1 FROM cte WHERE @c<3)
+SELECT * FROM cte;
+5
+5
+2
+3
+#
+# MDEV-15575: using recursive cte with big_tables enabled
+#
+set tmp_memory_table_size=0;
+with recursive qn as
+(select 123 as a union all select 1+a from qn where a<130)
+select * from qn;
+a
+123
+124
+125
+126
+127
+128
+129
+130
+set tmp_memory_table_size=default;
+#
+# MDEV-15571: using recursive cte with big_tables enabled
+#
+create table t1 (a bigint);
+insert into t1 values(1);
+set tmp_memory_table_size=0;
+with recursive qn as
+(
+select a from t1
+union all
+select a*2000 from qn where a<10000000000000000000
+)
+select * from qn;
+ERROR 22003: BIGINT value is out of range in '`qn`.`a` * 2000'
+set tmp_memory_table_size=default;
+drop table t1;
+#
+# MDEV-15556: using recursive cte with big_tables enabled
+# when recursive tables are accessed by key
+#
+set tmp_memory_table_size=0;
+CREATE TABLE t1 (id int, name char(10), leftpar int, rightpar int);
+INSERT INTO t1 VALUES
+(1, "A", 2, 3), (2, "LA", 4, 5), (4, "LLA", 6, 7),
+(6, "LLLA", NULL, NULL), (7, "RLLA", NULL, NULL), (5, "RLA", 8, 9),
+(8, "LRLA", NULL, NULL), (9, "RRLA", NULL, NULL), (3, "RA", 10, 11),
+(10, "LRA", 12, 13), (11, "RRA", 14, 15), (15, "RRRA", NULL, NULL),
+(16, "B", 17, 18), (17, "LB", NULL, NULL), (18, "RB", NULL, NULL);
+CREATE TABLE t2 SELECT * FROM t1 ORDER BY rand();
+WITH RECURSIVE tree_of_a AS
+(SELECT *, cast(id AS char(200)) AS path FROM t2 WHERE name="A"
+ UNION ALL
+SELECT t2.*, concat(tree_of_a.path,",",t2.id)
+FROM t2 JOIN tree_of_a ON t2.id=tree_of_a.leftpar
+UNION ALL
+SELECT t2.*, concat(tree_of_a.path,",",t2.id)
+FROM t2 JOIN tree_of_a ON t2.id=tree_of_a.rightpar)
+SELECT * FROM tree_of_a
+ORDER BY path;
+id name leftpar rightpar path
+1 A 2 3 1
+2 LA 4 5 1,2
+4 LLA 6 7 1,2,4
+6 LLLA NULL NULL 1,2,4,6
+7 RLLA NULL NULL 1,2,4,7
+5 RLA 8 9 1,2,5
+8 LRLA NULL NULL 1,2,5,8
+9 RRLA NULL NULL 1,2,5,9
+3 RA 10 11 1,3
+10 LRA 12 13 1,3,10
+11 RRA 14 15 1,3,11
+15 RRRA NULL NULL 1,3,11,15
+EXPLAIN WITH RECURSIVE tree_of_a AS
+(SELECT *, cast(id AS char(200)) AS path FROM t2 WHERE name="A"
+ UNION ALL
+SELECT t2.*, concat(tree_of_a.path,",",t2.id)
+FROM t2 JOIN tree_of_a ON t2.id=tree_of_a.leftpar
+UNION ALL
+SELECT t2.*, concat(tree_of_a.path,",",t2.id)
+FROM t2 JOIN tree_of_a ON t2.id=tree_of_a.rightpar)
+SELECT * FROM tree_of_a
+ORDER BY path;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 15 Using filesort
+2 DERIVED t2 ALL NULL NULL NULL NULL 15 Using where
+3 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 15 Using where
+3 RECURSIVE UNION <derived2> ref key0 key0 5 test.t2.id 2
+4 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 15 Using where
+4 RECURSIVE UNION <derived2> ref key0 key0 5 test.t2.id 2
+NULL UNION RESULT <union2,3,4> ALL NULL NULL NULL NULL NULL
+DROP TABLE t1,t2;
+set tmp_memory_table_size=default;
+#
+# MDEV-15840: recursive tables are accessed by key
+# (the same problem as for MDEV-15556)
+#
+CREATE TABLE t1 (p1 text,k2 int, p2 text, k1 int);
+INSERT INTO t1 select seq, seq, seq, seq from seq_1_to_1000;
+CREATE PROCEDURE getNums()
+BEGIN
+WITH RECURSIVE cte as
+(
+SELECT * FROM t1
+UNION
+SELECT c.* FROM t1 c JOIN cte p ON c.p1 = p.p2 AND c.k2 = p.k1
+)
+SELECT * FROM cte LIMIT 10;
+END |
+call getNums();
+p1 k2 p2 k1
+1 1 1 1
+2 2 2 2
+3 3 3 3
+4 4 4 4
+5 5 5 5
+6 6 6 6
+7 7 7 7
+8 8 8 8
+9 9 9 9
+10 10 10 10
+DROP PROCEDURE getNums;
+DROP TABLE t1;
+#
+# MDEV-15894: aggregate/winfow functions in non-recorsive part
+#
+create table t1(b int);
+insert into t1 values(10),(20),(10);
+with recursive qn as
+(select max(b) as a from t1 union
+select a from qn)
+select * from qn;
+a
+20
+with recursive qn as
+(select rank() over (order by b) as a from t1 union
+select a from qn)
+select * from qn;
+a
+1
+3
+drop table t1;
+#
+# MDEV-16086: tmp table for CTE is created as ARIA tables
+#
+CREATE TABLE t1 (
+Id int(11) not null AUTO_INCREMENT,
+Parent varchar(15) not null,
+Child varchar(15) not null,
+PRIMARY KEY (Id)
+) ENGINE = MyISAM;
+INSERT INTO t1 (Parent, Child) VALUES
+('123', '456'),('456', '789'),('321', '654'),('654', '987');
+WITH RECURSIVE cte AS
+( SELECT b.Parent,
+b.Child,
+CAST(CONCAT(b.Child,',') AS CHAR(513)) Path
+FROM t1 b
+LEFT OUTER JOIN t1 bc ON b.Child = bc.Parent
+WHERE bc.Id IS NULL
+UNION ALL SELECT c.Parent,
+c.Child,
+CONCAT(p.Path,c.Child,',') Path
+FROM t1 c
+INNER JOIN cte p ON c.Child = p.Parent)
+SELECT *
+FROM cte
+ORDER BY Path;
+Parent Child Path
+456 789 789,
+123 456 789,456,
+654 987 987,
+321 654 987,654,
+DROP TABLE t1;
+#
+# MDEV-16212: recursive CTE with global ORDER BY
+#
+set statement max_recursive_iterations = 2 for
+WITH RECURSIVE qn AS (
+SELECT 1 FROM dual UNION ALL
+SELECT 1 FROM qn
+ORDER BY (SELECT * FROM qn))
+SELECT count(*) FROM qn;
+ERROR 42000: This version of MariaDB doesn't yet support 'global ORDER_BY/LIMIT in recursive CTE spec'
+#
+# MDEV-15581: mix of ALL and DISTINCT UNION in recursive CTE
+#
+create table t1(a int);
+insert into t1 values(1),(2);
+insert into t1 values(1),(2);
+set @c=0, @d=0;
+WITH RECURSIVE qn AS
+(
+select 1,0 as col from t1
+union distinct
+select 1,0 from t1
+union all
+select 3, 0*(@c:=@c+1) from qn where @c<1
+union all
+select 3, 0*(@d:=@d+1) from qn where @d<1
+)
+select * from qn;
+ERROR 42000: This version of MariaDB doesn't yet support 'mix of ALL and DISTINCT UNION operations in recursive CTE spec'
+drop table t1;
+#
+# MDEV-16629: function with recursive CTE using a base table
+#
+CREATE TABLE t1 (id int);
+INSERT INTO t1 VALUES (0), (1),(2);
+WITH recursive cte AS
+(SELECT id FROM t1 UNION SELECT 3 FROM cte)
+SELECT count(id) FROM cte;
+count(id)
+4
+CREATE OR REPLACE FUNCTION func() RETURNS int
+RETURN
+(
+WITH recursive cte AS
+(SELECT id FROM t1 UNION SELECT 3 FROM cte)
+SELECT count(id) FROM cte
+);
+SELECT func();
+func()
+4
+DROP FUNCTION func;
+DROP TABLE t1;
+#
+# MDEV-16661: function with recursive CTE using no base tables
+# (fixed by the patch for MDEV-16629)
+#
+CREATE OR REPLACE FUNCTION func() RETURNS int
+RETURN
+(
+WITH RECURSIVE cte AS
+(SELECT 1 as id UNION SELECT * FROM cte)
+SELECT count(id) FROM cte
+);
+SELECT func();
+func()
+1
+DROP FUNCTION func;
+#
+# MDEV-17024: two materialized CTEs using the same recursive CTE
+#
+create table t1 (id int);
+insert into t1 values (1), (2), (3);
+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 cte1, cte2;
+c1 c2
+2 1
+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 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)
+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
+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 cte1, cte2";
+execute stmt;
+c1 c2
+2 1
+execute stmt;
+c1 c2
+2 1
+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 cte1, cte2;
+call p();
+select * from t2;
+c1 c2
+2 1
+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 cte1;
+c1
+2
+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 t1),
+cte2 as
+(select count(*) as c2 from t2)
+select * from cte1,cte2;
+c1 c2
+3 1
+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 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;
+#
+# MDEV-17201: recursive part with LIMIT
+#
+CREATE TABLE purchases (
+id int unsigned NOT NULL AUTO_INCREMENT,
+pdate date NOT NULL,
+quantity int unsigned NOT NULL,
+p_id int unsigned NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO purchases(pdate, quantity, p_id) VALUES
+('2014-11-01',5 ,1),('2014-11-03', 3 ,1),
+('2014-11-01',2 ,2),('2014-11-03', 4 ,2);
+CREATE TABLE expired (
+edate date NOT NULL,
+quantity int unsigned NOT NULL,
+p_id int unsigned NOT NULL,
+PRIMARY KEY (edate,p_id)
+);
+INSERT INTO expired VALUES ('2014-11-12', 5 ,1),('2014-11-08', 1 ,2);
+WITH RECURSIVE expired_map AS (
+SELECT edate AS expired_date,
+CAST(NULL AS date) AS purchase_date,
+0 AS quantity,
+e.p_id,
+(SELECT MAX(id)+1 FROM purchases p
+WHERE pdate <= edate AND p.p_id =p_id) AS purchase_processed,
+quantity AS unresolved
+FROM expired e
+UNION
+( SELECT expired_date,
+pdate,
+IF(p.quantity < m.unresolved, p.quantity, m.unresolved),
+p.p_id,
+p.id,
+IF(p.quantity < m.unresolved, m.unresolved - p.quantity, 0)
+FROM purchases p JOIN expired_map m ON p.p_id = m.p_id
+WHERE p.id < m.purchase_processed AND m.unresolved > 0
+ORDER BY p.id DESC
+LIMIT 1
+)
+)
+SELECT * FROM expired_map;
+expired_date purchase_date quantity p_id purchase_processed unresolved
+2014-11-12 NULL 0 1 5 5
+2014-11-08 NULL 0 2 5 1
+2014-11-08 2014-11-03 1 2 4 0
+DROP TABLE purchases, expired;
+#
+# MDEV-17635: Two recursive CTEs, the second using the first
+#
+WITH RECURSIVE
+x AS (SELECT 0 as k UNION ALL SELECT k + 1 FROM x WHERE k < 1),
+z AS
+( SELECT k1 AS cx, k2 AS cy, k1, k2
+FROM (SELECT k AS k1 FROM x) x1 JOIN (SELECT k AS k2 FROM x) y1
+UNION
+SELECT 1,1,1,1 FROM z)
+SELECT * FROM z;
+cx cy k1 k2
+0 0 0 0
+1 0 1 0
+0 1 0 1
+1 1 1 1
+# https://wiki.postgresql.org/wiki/Mandelbrot_set:
+WITH RECURSIVE x(i) AS (
+SELECT CAST(0 AS DECIMAL(13, 10))
+UNION ALL
+SELECT i + 1
+FROM x
+WHERE i < 101
+),
+Z(Ix, Iy, Cx, Cy, X, Y, I) AS (
+SELECT Ix, Iy, X, Y, X, Y, 0
+FROM (SELECT CAST(-2.2 + 0.031 * i AS DECIMAL(13, 10)) AS X,
+i AS Ix FROM x) AS xgen
+CROSS JOIN (
+SELECT CAST(-1.5 + 0.031 * i AS DECIMAL(13, 10)) AS Y,
+i AS iY FROM x
+) AS ygen
+UNION ALL
+SELECT Ix, Iy, Cx, Cy,
+CAST(X * X - Y * Y + Cx AS DECIMAL(13, 10)) AS X,
+CAST(Y * X * 2 + Cy AS DECIMAL(13, 10)), I + 1
+FROM Z
+WHERE X * X + Y * Y < 16.0
+AND I < 27
+),
+Zt (Ix, Iy, I) AS (
+SELECT Ix, Iy, MAX(I) AS I
+FROM Z
+GROUP BY Iy, Ix
+ORDER BY Iy, Ix
+)
+SELECT GROUP_CONCAT(
+SUBSTRING(
+' .,,,-----++++%%%%@@@@#### ',
+GREATEST(I, 1),
+1
+) ORDER BY Ix SEPARATOR ''
+ ) AS 'Mandelbrot Set'
+ FROM Zt
+GROUP BY Iy
+ORDER BY Iy;
+Mandelbrot Set
+ ....................................................................................
+ .......................................................................................
+ .........................................................................................
+ ...........................................................................................
+ ....................................................,,,,,,,,,.................................
+ ................................................,,,,,,,,,,,,,,,,,,.............................
+ ..............................................,,,,,,,,,,,,,,,,,,,,,,,,..........................
+ ............................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,........................
+ ..........................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,......................
+ .........................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,....................
+ ........................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,...................
+ .......................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.................
+ .......................................,,,,,,,,,,,,,,,,,,,,,,,,--,,,,,,,,,,,,,,,,,,,,................
+......................................,,,,,,,,,,,,,,,,,,,,,,,,,,-+--,,,,,,,,,,,,,,,,,,,...............
+....................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----,,,,,,,,,,,,,,,,,,,..............
+...................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,--- -----,,,,,,,,,,,,,,,,,.............
+.................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---++--++,,,,,,,,,,,,,,,,,,............
+................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----%++---,,,,,,,,,,,,,,,,,............
+..............................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----+%----,,,,,,,,,,,,,,,,,,...........
+.............................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,----- %%+----,,,,,,,,,,,,,,,,,,..........
+...........................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---%-+% ----,,,,,,,,,,,,,,,,,,,.........
+..........................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---+ +## %+%---,,,,,,,,,,,,,,,,,,.........
+........................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----# # +---,,,,,,,,,,,,,,,,,,........
+.......................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-------% %-----,,,,,,,,,,,,,,,,,........
+.....................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---------+ ------,,,,,,,,,,,,,,,,,.......
+....................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----------+@ +-----------,,,,,,,,,,,,.......
+..................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,----@-------++ ++-----------,,,,,,,,,,,,......
+.................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,--+@% ---+ +@%%@ %%+@+@%------+-,,,,,,,,,,,......
+................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---- # ++% % @-----++--,,,,,,,,,,,.....
+..............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,----+ % %%++ %+%@-,,,,,,,,,,,.....
+.............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----+# #% ++-,,,,,,,,,,,,....
+............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,------+ @---,,,,,,,,,,,,....
+..........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-------++% ---,,,,,,,,,,,,....
+.........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,--------+ + %+---,,,,,,,,,,,,,...
+........,,,,,,,,,,,,,,,,,,,,,--------------------@ +----,,,,,,,,,,,,...
+.......,,,,,,,,,,,,,,,,,,,,,,- +-----------------+ ----,,,,,,,,,,,,...
+.......,,,,,,,,,,,,,,,,,,,,,--++------+---------+% +++--,,,,,,,,,,,,..
+......,,,,,,,,,,,,,,,,,,,,,,--%+-----++--------- #+-,,,,,,,,,,,,..
+.....,,,,,,,,,,,,,,,,,,,,,,----#%++--+@ -+-----+% --,,,,,,,,,,,,..
+.....,,,,,,,,,,,,,,,,,,,,,,-----+## ++@ + +----% +--,,,,,,,,,,,,,..
+....,,,,,,,,,,,,,,,,,,,,,,------+@ @ @@++++# +--,,,,,,,,,,,,,..
+....,,,,,,,,,,,,,,,,,,,,,-------% #++% -,,,,,,,,,,,,,..
+...,,,,,,,,,,,,,,,,,,,,,------++%# %%@ %-,,,,,,,,,,,,,,.
+...,,,,,,,,,,,,,,,,,,,--------+ % +--,,,,,,,,,,,,,,.
+...,,,,,,,,,,,,,,,,,,-----+--++@ # --,,,,,,,,,,,,,,.
+..,,,,,,,,,,,,,,,,,-------%+++% @--,,,,,,,,,,,,,,,.
+..,,,,,,,,,,,-------------+ @#@ ---,,,,,,,,,,,,,,,.
+..,,,,,,,,,---@--------@-+% +---,,,,,,,,,,,,,,,.
+..,,,,,------- +-++++-+%%% +----,,,,,,,,,,,,,,,.
+..,,,,,,------%--------++% +----,,,,,,,,,,,,,,,.
+..,,,,,,,,,,--+----------++# ---,,,,,,,,,,,,,,,.
+..,,,,,,,,,,,,------------+@@@% +--,,,,,,,,,,,,,,,.
+..,,,,,,,,,,,,,,,,,------- +++% %--,,,,,,,,,,,,,,,.
+...,,,,,,,,,,,,,,,,,,---------+@ @ --,,,,,,,,,,,,,,.
+...,,,,,,,,,,,,,,,,,,,,------- # %@ +--,,,,,,,,,,,,,,.
+...,,,,,,,,,,,,,,,,,,,,,-------++@ %+ %-,,,,,,,,,,,,,,.
+....,,,,,,,,,,,,,,,,,,,,,------- %++% %-,,,,,,,,,,,,,..
+....,,,,,,,,,,,,,,,,,,,,,,------+# %# #@ ++++ +--,,,,,,,,,,,,,..
+.....,,,,,,,,,,,,,,,,,,,,,,-----+ %%++% +@+----+ +--,,,,,,,,,,,,,..
+.....,,,,,,,,,,,,,,,,,,,,,,,---%+++--+#+--------% #--,,,,,,,,,,,,..
+......,,,,,,,,,,,,,,,,,,,,,,--++-----%%--------- @#--,,,,,,,,,,,,..
+.......,,,,,,,,,,,,,,,,,,,,,---------------------+@ +-++,,,,,,,,,,,,...
+........,,,,,,,,,,,,,,,,,,,,,--------------------+ ----,,,,,,,,,,,,...
+.........,,,,,,,,,,,,,,,,,,,,----,,,------------- #+----,,,,,,,,,,,,...
+..........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-------+ + +---,,,,,,,,,,,,,...
+...........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,--------+%# #---,,,,,,,,,,,,....
+............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,------+# @ @---,,,,,,,,,,,,....
+.............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----+# + @--,,,,,,,,,,,,....
+..............,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---+% %+@ %+-+ +++%-,,,,,,,,,,,.....
+................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,----% %@++ # % -----++-,,,,,,,,,,,,.....
+.................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-- ++ ---+ + +%@ %++++++------%-,,,,,,,,,,,......
+...................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---- -------++ +------------,,,,,,,,,,,,......
+....................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----------+% +--------,,,,,,,,,,,,,,,.......
+......................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,--------+# -----,,,,,,,,,,,,,,,,,,.......
+.......................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-------+ #----,,,,,,,,,,,,,,,,,,........
+.........................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,----+% %#---,,,,,,,,,,,,,,,,,,,........
+..........................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---+%+%@ %+%%--,,,,,,,,,,,,,,,,,,.........
+............................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---+-+% %----,,,,,,,,,,,,,,,,,,..........
+.............................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----+%@+---,,,,,,,,,,,,,,,,,,,..........
+...............................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----+%----,,,,,,,,,,,,,,,,,,...........
+................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-----%+ +--,,,,,,,,,,,,,,,,,............
+..................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,---++----,,,,,,,,,,,,,,,,,.............
+...................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,---@-----,,,,,,,,,,,,,,,,,.............
+.....................................,,,,,,,,,,,,,,,,,,,,,,,,,,,-----,,,,,,,,,,,,,,,,,,,..............
+ .....................................,,,,,,,,,,,,,,,,,,,,,,,,,,--%,,,,,,,,,,,,,,,,,,,,...............
+ .......................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.................
+ ........................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,..................
+ ........................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,...................
+ .........................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,....................
+ ..........................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,......................
+ ............................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,........................
+ .............................................,,,,,,,,,,,,,,,,,,,,,,,,..........................
+ ................................................,,,,,,,,,,,,,,,,,.............................
+ .....................................................,,,,....................................
+ ...........................................................................................
+ .........................................................................................
+ ......................................................................................
+ ....................................................................................
+ .................................................................................
+ ..............................................................................
+ ...........................................................................
+ ........................................................................
+#
+# MDEV-17871: EXPLAIN for query with not used recursive cte
+#
+create table t1 (a int);
+insert into t1 values (2), (1), (4), (3);
+explain extended
+with recursive cte as
+(select * from t1 where a=1 union select a+1 from cte where a<3)
+select * from cte as t;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 4 100.00 Using where
+3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 4 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 with recursive cte as (/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1 union /* select#3 */ select `cte`.`a` + 1 AS `a+1` from `cte` where `cte`.`a` < 3)/* select#1 */ select `t`.`a` AS `a` from `cte` `t`
+with recursive cte as
+(select * from t1 where a=1 union select a+1 from cte where a<3)
+select * from cte as t;
+a
+1
+2
+3
+explain extended
+with recursive cte as
+(select * from t1 where a=1 union select a+1 from cte where a<3)
+select * from t1 as t;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t ALL NULL NULL NULL NULL 4 100.00
+Warnings:
+Note 1003 with recursive cte as (/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1 union /* select#3 */ select `cte`.`a` + 1 AS `a+1` from `cte` where `cte`.`a` < 3)/* select#1 */ select `test`.`t`.`a` AS `a` from `test`.`t1` `t`
+with recursive cte as
+(select * from t1 where a=1 union select a+1 from cte where a<3)
+select * from t1 as t;
+a
+2
+1
+4
+3
+create table t2 ( i1 int, i2 int);
+insert into t2 values (1,1),(2,2);
+explain
+with recursive cte as
+( select * from t2 union select s1.* from t2 as s1, cte where s1.i1 = cte.i2 )
+select * from t2 as t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t ALL NULL NULL NULL NULL 2
+drop table t1,t2;
+#
+# MDEV-22042: ANALYZE of query using stored function and recursive CTE
+#
+create table t1 (a1 varchar(20),a2 varchar(20)) engine=myisam;
+insert into t1 values (1,1),(2,2),(3,3);
+create table t2 (
+a2 varchar(20) primary key, b1 varchar(20), key (b1)
+) engine=myisam;
+insert into t2 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7);
+insert into t2 values (11,11),(12,12),(13,13),(14,14),(15,15),(16,16),(17,17);
+create function f1(id varchar(20)) returns varchar(50)
+begin
+declare res varchar (50);
+select a2 into res from t2 where a2=id and b1=1 limit 1;
+return res;
+end$$
+select fv
+from (select t1.a1, f1(t1.a2) fv from t1) dt
+where (dt.a1) in (with recursive cte as (select a2 from t2 where a2='2'
+ union select tt2.a2 from t2 tt2 join cte on tt2.b1=cte.a2)
+select a2 from cte);
+fv
+NULL
+explain select fv
+from (select t1.a1, f1(t1.a2) fv from t1) dt
+where (dt.a1) in (with recursive cte as (select a2 from t2 where a2='2'
+ union select tt2.a2 from t2 tt2 join cte on tt2.b1=cte.a2)
+select a2 from cte);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY <derived3> ref key0 key0 23 test.t1.a1 1 FirstMatch(t1)
+3 DERIVED t2 const PRIMARY PRIMARY 22 const 1 Using index
+4 RECURSIVE UNION <derived3> ALL NULL NULL NULL NULL 2 Using where
+4 RECURSIVE UNION tt2 ref b1 b1 23 cte.a2 2
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+analyze format=json select fv
+from (select t1.a1, f1(t1.a2) fv from t1) dt
+where (dt.a1) in (with recursive cte as (select a2 from t2 where a2='2'
+ union select tt2.a2 from t2 tt2 join cte on tt2.b1=cte.a2)
+select a2 from cte);
+ANALYZE
+{
+ "query_optimization": {
+ "r_total_time_ms": "REPLACED"
+ },
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "r_loops": 1,
+ "rows": 3,
+ "r_rows": 3,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "r_engine_stats": REPLACED,
+ "filtered": 100,
+ "r_filtered": 100,
+ "attached_condition": "t1.a1 is not null"
+ }
+ },
+ {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "23",
+ "used_key_parts": ["a2"],
+ "ref": ["test.t1.a1"],
+ "r_loops": 3,
+ "rows": 1,
+ "r_rows": 0.333333333,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 100,
+ "r_filtered": 100,
+ "first_match": "t1",
+ "materialized": {
+ "query_block": {
+ "recursive_union": {
+ "table_name": "<union3,4>",
+ "access_type": "ALL",
+ "r_loops": 0,
+ "r_rows": null,
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 3,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t2",
+ "access_type": "const",
+ "possible_keys": ["PRIMARY"],
+ "key": "PRIMARY",
+ "key_length": "22",
+ "used_key_parts": ["a2"],
+ "ref": ["const"],
+ "r_loops": 0,
+ "rows": 1,
+ "r_rows": null,
+ "r_engine_stats": REPLACED,
+ "filtered": 100,
+ "r_filtered": null,
+ "using_index": true
+ }
+ }
+ ]
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 4,
+ "operation": "UNION",
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "r_loops": 1,
+ "rows": 2,
+ "r_rows": 1,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 100,
+ "r_filtered": 100,
+ "attached_condition": "cte.a2 is not null"
+ }
+ },
+ {
+ "table": {
+ "table_name": "tt2",
+ "access_type": "ref",
+ "possible_keys": ["b1"],
+ "key": "b1",
+ "key_length": "23",
+ "used_key_parts": ["b1"],
+ "ref": ["cte.a2"],
+ "r_loops": 1,
+ "rows": 2,
+ "r_rows": 1,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "r_engine_stats": REPLACED,
+ "filtered": 100,
+ "r_filtered": 100
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+}
+drop function f1;
+drop table t1,t2;
+#
+# 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;
+#
+# MDEV-23619: recursive CTE used only in the second operand of UNION
+#
+create table t1 (
+a bigint(10) not null auto_increment,
+b int(5) not null,
+c bigint(10) default null,
+primary key (a)
+) engine myisam;
+insert into t1 values
+(1,3,12), (2,7,15), (3,1,3), (4,3,1);
+explain with recursive r_cte as
+( select * from t1 as s
+union
+select t1.* from t1, r_cte as r where t1.c = r.a )
+select 0 as b FROM dual union all select b FROM r_cte as t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DERIVED s ALL NULL NULL NULL NULL 4
+3 RECURSIVE UNION t1 ALL NULL NULL NULL NULL 4 Using where
+3 RECURSIVE UNION <derived2> ref key0 key0 9 test.t1.c 2
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+4 UNION <derived2> ALL NULL NULL NULL NULL 4
+with recursive r_cte as
+( select * from t1 as s
+union
+select t1.* from t1, r_cte as r where t1.c = r.a )
+select 0 as b FROM dual union all select b FROM r_cte as t;
+b
+0
+3
+7
+1
+3
+analyze format=json with recursive r_cte as
+( select * from t1 as s
+union
+select t1.* from t1, r_cte as r where t1.c = r.a )
+select 0 as b FROM dual union all select b FROM r_cte as t;
+ANALYZE
+{
+ "query_optimization": {
+ "r_total_time_ms": "REPLACED"
+ },
+ "query_block": {
+ "union_result": {
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "message": "No tables used"
+ }
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 4,
+ "operation": "UNION",
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "r_loops": 1,
+ "rows": 4,
+ "r_rows": 4,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 100,
+ "r_filtered": 100,
+ "materialized": {
+ "query_block": {
+ "recursive_union": {
+ "table_name": "<union2,3>",
+ "access_type": "ALL",
+ "r_loops": 0,
+ "r_rows": null,
+ "query_specifications": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "s",
+ "access_type": "ALL",
+ "r_loops": 1,
+ "rows": 4,
+ "r_rows": 4,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "r_engine_stats": REPLACED,
+ "filtered": 100,
+ "r_filtered": 100
+ }
+ }
+ ]
+ }
+ },
+ {
+ "query_block": {
+ "select_id": 3,
+ "operation": "UNION",
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "r_loops": 1,
+ "rows": 4,
+ "r_rows": 4,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "r_engine_stats": REPLACED,
+ "filtered": 100,
+ "r_filtered": 100,
+ "attached_condition": "t1.c is not null"
+ }
+ },
+ {
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ref",
+ "possible_keys": ["key0"],
+ "key": "key0",
+ "key_length": "9",
+ "used_key_parts": ["a"],
+ "ref": ["test.t1.c"],
+ "r_loops": 4,
+ "rows": 2,
+ "r_rows": 0.5,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "filtered": 100,
+ "r_filtered": 100
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+}
+prepare stmt from "with recursive r_cte as
+( select * from t1 as s
+union
+select t1.* from t1, r_cte as r where t1.c = r.a )
+select 0 as b FROM dual union all select b FROM r_cte as t";
+execute stmt;
+b
+0
+3
+7
+1
+3
+execute stmt;
+b
+0
+3
+7
+1
+3
+deallocate prepare stmt;
+#checking hanging cte that uses a recursive cte
+explain with h_cte as
+( with recursive r_cte as
+( select * from t1 as s
+union
+select t1.* from t1, r_cte as r where t1.c = r.a )
+select 0 as b FROM dual union all select b FROM r_cte as t)
+select * from t1 as tt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY tt ALL NULL NULL NULL NULL 4
+with h_cte as
+( with recursive r_cte as
+( select * from t1 as s
+union
+select t1.* from t1, r_cte as r where t1.c = r.a )
+select 0 as b FROM dual union all select b FROM r_cte as t)
+select * from t1 as tt;
+a b c
+1 3 12
+2 7 15
+3 1 3
+4 3 1
+analyze format=json with h_cte as
+( with recursive r_cte as
+( select * from t1 as s
+union
+select t1.* from t1, r_cte as r where t1.c = r.a )
+select 0 as b FROM dual union all select b FROM r_cte as t)
+select * from t1 as tt;
+ANALYZE
+{
+ "query_optimization": {
+ "r_total_time_ms": "REPLACED"
+ },
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "nested_loop": [
+ {
+ "table": {
+ "table_name": "tt",
+ "access_type": "ALL",
+ "r_loops": 1,
+ "rows": 4,
+ "r_rows": 4,
+ "r_table_time_ms": "REPLACED",
+ "r_other_time_ms": "REPLACED",
+ "r_engine_stats": REPLACED,
+ "filtered": 100,
+ "r_filtered": 100
+ }
+ }
+ ]
+ }
+}
+prepare stmt from "with h_cte as
+( with recursive r_cte as
+( select * from t1 as s
+union
+select t1.* from t1, r_cte as r where t1.c = r.a )
+select 0 as b FROM dual union all select b FROM r_cte as t)
+select * from t1 as tt";
+execute stmt;
+a b c
+1 3 12
+2 7 15
+3 1 3
+4 3 1
+execute stmt;
+a b c
+1 3 12
+2 7 15
+3 1 3
+4 3 1
+deallocate prepare stmt;
+drop table t1;
+#
+# MDEV-24019: query with recursive CTE when no default database is set
+#
+create database dummy;
+use dummy;
+drop database dummy;
+with recursive a as
+(select 1 from dual union select * from a as r)
+select * from a;
+1
+1
+create database db1;
+create table db1.t1 (a int);
+insert into db1.t1 values (3), (7), (1);
+with recursive cte as
+(select * from db1.t1 union select * from (select * from cte) as t)
+select * from cte;
+a
+3
+7
+1
+explain with recursive cte as
+(select * from db1.t1 union select * from (select * from cte) as t)
+select * from cte;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+2 DERIVED t1 ALL NULL NULL NULL NULL 3
+3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 3
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+prepare stmt from "with recursive cte as
+(select * from db1.t1 union select * from (select * from cte) as t)
+select * from cte";
+execute stmt;
+a
+3
+7
+1
+execute stmt;
+a
+3
+7
+1
+deallocate prepare stmt;
+drop database db1;
+use test;
+#
+# MDEV-23406: query with mutually recursive CTEs when big_tables=1
+#
+set @save_big_tables=@@big_tables;
+set big_tables=1;
+Warnings:
+Warning 1287 '@@big_tables' is deprecated and will be removed in a future release
+create table folks(id int, name char(32), dob date, father int, mother int);
+insert into folks values
+(100, 'Me', '2000-01-01', 20, 30),
+(20, 'Dad', '1970-02-02', 10, 9),
+(30, 'Mom', '1975-03-03', 8, 7),
+(10, 'Grandpa Bill', '1940-04-05', null, null),
+(9, 'Grandma Ann', '1941-10-15', null, null),
+(25, 'Uncle Jim', '1968-11-18', 8, 7),
+(98, 'Sister Amy', '2001-06-20', 20, 30),
+(7, 'Grandma Sally', '1943-08-23', null, 6),
+(8, 'Grandpa Ben', '1940-10-21', null, null),
+(6, 'Grandgrandma Martha', '1923-05-17', null, null),
+(67, 'Cousin Eddie', '1992-02-28', 25, 27),
+(27, 'Auntie Melinda', '1971-03-29', null, null);
+with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+union
+select h.*, w.*
+from folks v, folks h, folks w
+where v.name = 'Me' and
+(v.father = h.id AND v.mother= w.id)
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples;
+h_name h_dob w_name w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+explain with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+union
+select h.*, w.*
+from folks v, folks h, folks w
+where v.name = 'Me' and
+(v.father = h.id AND v.mother= w.id)
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 1728
+4 DERIVED <derived3> ALL NULL NULL NULL NULL 1728
+5 RECURSIVE UNION <derived3> ALL NULL NULL NULL NULL 1728
+NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
+3 DERIVED v ALL NULL NULL NULL NULL 12 Using where
+3 DERIVED h ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+3 DERIVED w ALL NULL NULL NULL NULL 12 Using where; Using join buffer (incremental, BNL join)
+2 RECURSIVE UNION <derived4> ALL NULL NULL NULL NULL 2
+2 RECURSIVE UNION h ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+2 RECURSIVE UNION w ALL NULL NULL NULL NULL 12 Using where; Using join buffer (incremental, BNL join)
+NULL UNION RESULT <union3,2> ALL NULL NULL NULL NULL NULL
+prepare stmt from "with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+union
+select h.*, w.*
+from folks v, folks h, folks w
+where v.name = 'Me' and
+(v.father = h.id AND v.mother= w.id)
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples";
+execute stmt;
+h_name h_dob w_name w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+execute stmt;
+h_name h_dob w_name w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+deallocate prepare stmt;
+with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select *
+from folks
+where name = 'Me'
+ union all
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union all
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples;
+h_name h_dob w_name w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+explain with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select *
+from folks
+where name = 'Me'
+ union all
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union all
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+3 DERIVED folks ALL NULL NULL NULL NULL 12 Using where
+4 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2
+5 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2
+NULL UNION RESULT <union3,4,5> ALL NULL NULL NULL NULL NULL
+2 DERIVED h ALL NULL NULL NULL NULL 12
+2 DERIVED w ALL NULL NULL NULL NULL 12 Using join buffer (flat, BNL join)
+2 DERIVED <derived3> ALL NULL NULL NULL NULL 12 Using where; Using join buffer (incremental, BNL join)
+prepare stmt from "with recursive
+ancestor_couples(h_id, h_name, h_dob, h_father, h_mother,
+w_id, w_name, w_dob, w_father, w_mother)
+as
+(
+select h.*, w.*
+from folks h, folks w, coupled_ancestors a
+where a.father = h.id AND a.mother = w.id
+),
+coupled_ancestors (id, name, dob, father, mother)
+as
+(
+select *
+from folks
+where name = 'Me'
+ union all
+select h_id, h_name, h_dob, h_father, h_mother
+from ancestor_couples
+union all
+select w_id, w_name, w_dob, w_father, w_mother
+from ancestor_couples
+)
+select h_name, h_dob, w_name, w_dob
+from ancestor_couples";
+execute stmt;
+h_name h_dob w_name w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+execute stmt;
+h_name h_dob w_name w_dob
+Dad 1970-02-02 Mom 1975-03-03
+Grandpa Bill 1940-04-05 Grandma Ann 1941-10-15
+Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
+deallocate prepare stmt;
+drop table folks;
+set big_tables=@save_big_tables;
+Warnings:
+Warning 1287 '@@big_tables' is deprecated and will be removed in a future release
+#
+# MDEV-26135: execution of PS for query with hanging recursive CTE
+#
+create table t1 (a int);
+insert into t1 values (5), (7);
+create table t2 (b int);
+insert into t2 values (3), (7), (1);
+with recursive r as (select a from t1 union select a+1 from r where a < 10)
+select * from t2;
+b
+3
+7
+1
+prepare stmt from "with recursive r as (select a from t1 union select a+1 from r where a < 10)
+select * from t2";
+execute stmt;
+b
+3
+7
+1
+execute stmt;
+b
+3
+7
+1
+deallocate prepare stmt;
+drop table t1,t2;
+#
+# MDEV-26189: Unknown column reference within hanging recursive CTE
+#
+create table t1 (a int);
+insert into t1 values (3), (7), (1);
+with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b)
+select * from t1 as t;
+ERROR 42S22: Unknown column 'r.b' in 'where clause'
+explain with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b)
+select * from t1 as t;
+ERROR 42S22: Unknown column 'r.b' in 'where clause'
+create procedure sp1() with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.a = r.b)
+select * from t1 as t;
+call sp1();
+ERROR 42S22: Unknown column 'r.b' in 'where clause'
+call sp1();
+ERROR 42S22: Unknown column 'r.b' in 'where clause'
+with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a)
+select * from t1 as t;
+ERROR 42S22: Unknown column 's1.b' in 'where clause'
+explain with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a)
+select * from t1 as t;
+ERROR 42S22: Unknown column 's1.b' in 'where clause'
+create procedure sp2() with recursive
+r as (select * from t1 union select s1.* from t1 as s1, r where s1.b = r.a)
+select * from t1 as t;
+call sp2();
+ERROR 42S22: Unknown column 's1.b' in 'where clause'
+call sp2();
+ERROR 42S22: Unknown column 's1.b' in 'where clause'
+drop procedure sp1;
+drop procedure sp2;
+drop table t1;
+#
+# MDEV-26202: Recursive CTE used indirectly twice
+# (fixed by the patch forMDEV-26025)
+#
+with recursive
+rcte as ( SELECT 1 AS a
+UNION ALL
+SELECT cast(a + 1 as unsigned int) FROM rcte WHERE a < 3),
+cte1 AS (SELECT a FROM rcte),
+cte2 AS (SELECT a FROM cte1),
+cte3 AS ( SELECT a FROM cte2)
+SELECT * FROM cte2, cte3;
+a a
+1 1
+2 1
+3 1
+1 2
+2 2
+3 2
+1 3
+2 3
+3 3
+#
+# End of 10.2 tests
+#
+#
+# MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
+#
+CREATE TEMPORARY TABLE a_tbl (
+a VARCHAR(33) PRIMARY KEY,
+b VARCHAR(33)
+);
+INSERT INTO a_tbl VALUES ('block0', 'block0'), ('block1', NULL);
+WITH RECURSIVE Q0 AS (
+SELECT T0.a, T0.b, 5
+FROM a_tbl T0
+WHERE b IS NULL
+UNION ALL
+SELECT T1.a, T1.b
+FROM Q0
+JOIN a_tbl T1
+ON T1.a=Q0.a
+) SELECT distinct(Q0.a), Q0.b
+FROM Q0;
+ERROR 21000: The used SELECT statements have a different number of columns
+DROP TABLE a_tbl;
+WITH RECURSIVE x AS (SELECT 1,2 UNION ALL SELECT 1 FROM x) SELECT * FROM x;
+ERROR 21000: The used SELECT statements have a different number of columns
+#
+# MDEV-15162: Setting user variable in recursive CTE
+#
+SET @c=1;
+WITH RECURSIVE cte AS
+(SELECT 5
+UNION
+SELECT @c:=@c+1 FROM cte WHERE @c<3)
+SELECT * FROM cte;
+5
+5
+2
+3
+#
+# MDEV-14883: recursive references in operands of INTERSECT / EXCEPT
+#
+create table flights
+(departure varchar(32),
+arrival varchar(32),
+carrier varchar(20),
+flight_number char(7));
+insert into flights values
+('Seattle', 'Frankfurt', 'Lufthansa', 'LH 491'),
+('Seattle', 'Amsterdam', 'KLM', 'KL 6032'),
+('Seattle', 'Chicago', 'American', 'AA 2573'),
+('Seattle', 'Los Angeles', 'Alaska Air', 'AS 410'),
+('Chicago', 'New York', 'American', 'AA 375'),
+('Chicago', 'Montreal', 'Air Canada', 'AC 3053'),
+('Los Angeles', 'New York', 'Delta', 'DL 1197'),
+('New York', 'London', 'British Airways', 'BA 1511'),
+('London', 'Moscow', 'British Airways', 'BA 233'),
+('Moscow', 'Tokyo', 'Aeroflot', 'SU 264'),
+('Moscow', 'Dubai', 'Emirates', 'EK 2421'),
+('Dubai', 'Tokyo', 'Emirates', 'EK 318'),
+('Dubai', 'Bangkok', 'Emirates', 'EK 2142'),
+('Beijing', 'Bangkok', 'Air China', 'CA 757'),
+('Beijing', 'Tokyo', 'Air China', 'CA 6653'),
+('Moscow', 'Bangkok', 'Aeroflot', 'SU 270'),
+('New York', 'Reykjavik', 'Icelandair', 'FL 416'),
+('New York', 'Paris', 'Air France', 'AF 23'),
+('Amsterdam', 'Moscow', 'KLM', 'KL 903'),
+('Frankfurt', 'Dubai', 'Lufthansa', 'LH 630'),
+('Frankfurt', 'Moscow', 'Lufthansa', 'LH 1444'),
+('Reykjavik', 'London', 'British Airways', 'BA 2229'),
+('Frankfurt', 'Beijing', 'Air China', 'CA 966'),
+('Tokyo', 'Seattle', 'ANA', 'NH 178'),
+('Los Angeles', 'Tokyo', 'ANA', 'NH 175'),
+('Moscow', 'Los Angeles', 'Aeroflot', 'SU 106'),
+('Montreal', 'Paris', 'Air Canada', 'AC 870'),
+('London', 'Delhi', 'British Airways', 'BA 143'),
+('Delhi', 'Bangkok', 'Air India', 'AI 306'),
+('Delhi', 'Dubai', 'Air India', 'AI 995'),
+('Dubai', 'Cairo', 'Emirates', 'EK 927'),
+('Cairo', 'Paris', 'Air France', 'AF 503'),
+('Amsterdam', 'New York', 'Delta', 'DL 47'),
+('New York', 'Seattle', 'American', 'AA 45'),
+('Paris', 'Chicago', 'Air France', 'AF 6734');
+create table distances
+(city1 varchar(32),
+city2 varchar(32),
+dist int);
+insert into distances values
+('Seattle', 'Frankfurt', 5080),
+('Seattle', 'Amsterdam', 4859),
+('Seattle', 'Chicago', 1733),
+('Seattle', 'Los Angeles', 960),
+('Chicago', 'New York', 712),
+('Chicago', 'Montreal', 746),
+('Los Angeles', 'New York', 2446),
+('New York', 'London', 3459),
+('London', 'Moscow', 1554),
+('Moscow', 'Tokyo', 4647),
+('Moscow', 'Dubai', 2298),
+('Dubai', 'Tokyo', 4929),
+('Dubai', 'Bangkok', 3050),
+('Beijing', 'Bangkok', 2046),
+('Beijing', 'Tokyo', 1301),
+('Moscow', 'Bangkok', 4390),
+('New York', 'Reykjavik', 2613),
+('New York', 'Paris', 3625),
+('Amsterdam', 'Moscow', 1334),
+('Frankfurt', 'Dubai', 3003),
+('Frankfurt', 'Moscow', 1256),
+('Reykjavik', 'London', 1173),
+('Frankfurt', 'Beijing', 4836),
+('Tokyo', 'Seattle', 4783),
+('Los Angeles', 'Tokyo', 5479),
+('Moscow', 'Los Angeles', 6071),
+('Moscow', 'Reykjavik', 2052),
+('Montreal', 'Paris', 3425),
+('London', 'Delhi', 4159),
+('London', 'Paris', 214),
+('Delhi', 'Bangkok', 1810),
+('Delhi', 'Dubai', 1369),
+('Delhi', 'Beijing', 2350),
+('Dubai', 'Cairo', 1501),
+('Cairo', 'Paris', 1992),
+('Amsterdam', 'New York', 3643),
+('New York', 'Seattle', 2402),
+('Paris', 'Chicago', 4136),
+('Paris', 'Los Angeles', 5647);
+with recursive destinations (city) as
+(
+select a.arrival from flights a where a.departure = 'Seattle'
+ union
+select b.arrival from destinations r, flights b where r.city = b.departure
+)
+select * from destinations;
+city
+Frankfurt
+Amsterdam
+Chicago
+Los Angeles
+New York
+Montreal
+Moscow
+Dubai
+Beijing
+Tokyo
+London
+Bangkok
+Reykjavik
+Paris
+Seattle
+Cairo
+Delhi
+with recursive destinations (city) as
+(
+select a.arrival from flights a, distances d
+where a.departure = 'Seattle' and
+a.departure = d.city1 and a.arrival = d.city2 and
+d.dist < 4000
+union
+select b.arrival from destinations r, flights b, distances d
+where r.city = b.departure and
+b.departure = d.city1 and b.arrival = d.city2 and
+d.dist < 4000
+)
+select * from destinations;
+city
+Chicago
+Los Angeles
+New York
+Montreal
+London
+Reykjavik
+Paris
+Seattle
+Moscow
+Dubai
+Bangkok
+Cairo
+set standard_compliant_cte=0;
+with recursive legs_to_destinations
+(departure, arrival, dist, leg_no, acc_mileage) as
+(
+select a.departure, a.arrival, d.dist, 1, d.dist
+from flights a, distances d
+where a.departure = 'Seattle' and
+a.departure = d.city1 and a.arrival = d.city2 and
+d.dist < 4000
+union all
+select b.departure, b.arrival, d.dist, r.leg_no + 1, r.acc_mileage + d.dist
+from legs_to_destinations r, flights b, distances d
+where r.arrival = b.departure and
+b.departure = d.city1 and b.arrival = d.city2 and
+d.dist < 4000 and
+b.arrival not in (select arrival from legs_to_destinations)
+)
+select * from legs_to_destinations;
+departure arrival dist leg_no acc_mileage
+Seattle Chicago 1733 1 1733
+Seattle Los Angeles 960 1 960
+Chicago New York 712 2 2445
+Chicago Montreal 746 2 2479
+Los Angeles New York 2446 2 3406
+New York London 3459 3 6865
+New York London 3459 3 5904
+New York Reykjavik 2613 3 6019
+New York Reykjavik 2613 3 5058
+New York Paris 3625 3 7031
+New York Paris 3625 3 6070
+Montreal Paris 3425 3 5904
+New York Seattle 2402 3 5808
+New York Seattle 2402 3 4847
+London Moscow 1554 4 7458
+London Moscow 1554 4 8419
+Moscow Dubai 2298 5 10717
+Moscow Dubai 2298 5 9756
+Dubai Bangkok 3050 6 12806
+Dubai Bangkok 3050 6 13767
+Dubai Cairo 1501 6 11257
+Dubai Cairo 1501 6 12218
+set standard_compliant_cte=default;
+with recursive destinations (city) as
+(
+select a.arrival from flights a, distances d
+where a.departure = 'Seattle' and
+a.departure = d.city1 and a.arrival = d.city2 and
+d.dist < 4000
+union
+select b.arrival from destinations r, flights b
+where r.city = b.departure
+intersect
+select city2 from destinations s, distances d
+where s.city = d.city1 and d.dist < 4000
+)
+select * from destinations;
+city
+Chicago
+Los Angeles
+New York
+Montreal
+London
+Reykjavik
+Paris
+Seattle
+Moscow
+Dubai
+Bangkok
+Cairo
+with recursive destinations (city) as
+(
+select a.arrival from flights a where a.departure = 'Seattle'
+ union
+select * from
+(
+select b.arrival from destinations r, flights b
+where r.city = b.departure
+except
+select arrival from flights
+where arrival in
+('New York', 'London', 'Moscow', 'Dubai', 'Cairo', 'Tokyo')
+) t
+)
+select * from destinations;
+city
+Frankfurt
+Amsterdam
+Chicago
+Los Angeles
+Montreal
+Beijing
+Bangkok
+Paris
+drop table flights, distances;
+#
+# MDEV-15159: Forced nullability of columns in recursive CTE
+#
+WITH RECURSIVE cte AS (
+SELECT 1 AS a UNION ALL
+SELECT NULL FROM cte WHERE a IS NOT NULL)
+SELECT * FROM cte;
+a
+1
+NULL
+CREATE TABLE t1 (a int NOT NULL);
+INSERT INTO t1 VALUES (0);
+WITH RECURSIVE cte AS
+(SELECT a FROM t1 where a=0 UNION SELECT NULL FROM cte)
+SELECT * FROM cte;
+a
+0
+NULL
+DROP TABLE t1;
+#
+# MDEV-12325 Unexpected data type and truncation when using CTE
+#
+CREATE TABLE t1
+(
+id INT, mid INT, name TEXT
+);
+INSERT INTO t1 VALUES (0,NULL,'Name'),(1,0,'Name1'),(2,0,'Name2'),(11,1,'Name11'),(12,1,'Name12');
+WITH RECURSIVE
+cteReports (level, id, mid, name) AS
+(
+SELECT 1, id, mid, name FROM t1 WHERE mid IS NULL
+UNION ALL
+SELECT r.level + 1, e.id, e.mid + 1000000000000, e.name FROM t1 e
+INNER JOIN cteReports r ON e.mid = r.id
+)
+SELECT
+level, id, mid, name,
+(SELECT name FROM t1 WHERE id= cteReports.mid) AS mname
+FROM cteReports ORDER BY level, mid;
+ERROR 22003: Out of range value for column 'mid' at row 2
+create table t2 as WITH RECURSIVE
+cteReports (level, id, mid, name) AS
+(
+SELECT 1, id, mid, name FROM t1 WHERE mid IS NULL
+UNION ALL
+SELECT r.level + 1, e.id, e.mid + 1000000000000, e.name FROM t1 e
+INNER JOIN cteReports r ON e.mid = r.id
+)
+SELECT
+level, id, mid, name,
+(SELECT name FROM t1 WHERE id= cteReports.mid) AS mname
+FROM cteReports ORDER BY level, mid;;
+ERROR 22003: Out of range value for column 'mid' at row 2
+create table t2 ignore as WITH RECURSIVE
+cteReports (level, id, mid, name) AS
+(
+SELECT 1, id, mid, name FROM t1 WHERE mid IS NULL
+UNION ALL
+SELECT r.level + 1, e.id, e.mid + 1000000000000, e.name FROM t1 e
+INNER JOIN cteReports r ON e.mid = r.id
+)
+SELECT
+level, id, mid, name,
+(SELECT name FROM t1 WHERE id= cteReports.mid) AS mname
+FROM cteReports ORDER BY level, mid;;
+Warnings:
+Warning 1264 Out of range value for column 'mid' at row 2
+Warning 1264 Out of range value for column 'mid' at row 3
+Warning 1264 Out of range value for column 'mid' at row 4
+Warning 1264 Out of range value for column 'mid' at row 5
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `level` int(1) DEFAULT NULL,
+ `id` int(11) DEFAULT NULL,
+ `mid` int(11) DEFAULT NULL,
+ `name` text DEFAULT NULL,
+ `mname` text DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+insert into t2 WITH RECURSIVE
+cteReports (level, id, mid, name) AS
+(
+SELECT 1, id, mid, name FROM t1 WHERE mid IS NULL
+UNION ALL
+SELECT r.level + 1, e.id, e.mid + 1000000000000, e.name FROM t1 e
+INNER JOIN cteReports r ON e.mid = r.id
+)
+SELECT
+level, id, mid, name,
+(SELECT name FROM t1 WHERE id= cteReports.mid) AS mname
+FROM cteReports ORDER BY level, mid;;
+ERROR 22003: Out of range value for column 'mid' at row 2
+insert ignore into t2 WITH RECURSIVE
+cteReports (level, id, mid, name) AS
+(
+SELECT 1, id, mid, name FROM t1 WHERE mid IS NULL
+UNION ALL
+SELECT r.level + 1, e.id, e.mid + 1000000000000, e.name FROM t1 e
+INNER JOIN cteReports r ON e.mid = r.id
+)
+SELECT
+level, id, mid, name,
+(SELECT name FROM t1 WHERE id= cteReports.mid) AS mname
+FROM cteReports ORDER BY level, mid;;
+Warnings:
+Warning 1264 Out of range value for column 'mid' at row 2
+Warning 1264 Out of range value for column 'mid' at row 3
+Warning 1264 Out of range value for column 'mid' at row 4
+Warning 1264 Out of range value for column 'mid' at row 5
+drop table t2;
+set @@sql_mode="";
+WITH RECURSIVE
+cteReports (level, id, mid, name) AS
+(
+SELECT 1, id, mid, name FROM t1 WHERE mid IS NULL
+UNION ALL
+SELECT r.level + 1, e.id, e.mid + 1000000000000, e.name FROM t1 e
+INNER JOIN cteReports r ON e.mid = r.id
+)
+SELECT
+level, id, mid, name,
+(SELECT name FROM t1 WHERE id= cteReports.mid) AS mname
+FROM cteReports ORDER BY level, mid;
+level id mid name mname
+1 0 NULL Name NULL
+2 1 2147483647 Name1 NULL
+2 2 2147483647 Name2 NULL
+3 11 2147483647 Name11 NULL
+3 12 2147483647 Name12 NULL
+Warnings:
+Warning 1264 Out of range value for column 'mid' at row 2
+Warning 1264 Out of range value for column 'mid' at row 3
+Warning 1264 Out of range value for column 'mid' at row 4
+Warning 1264 Out of range value for column 'mid' at row 5
+create table t2 as WITH RECURSIVE
+cteReports (level, id, mid, name) AS
+(
+SELECT 1, id, mid, name FROM t1 WHERE mid IS NULL
+UNION ALL
+SELECT r.level + 1, e.id, e.mid + 1000000000000, e.name FROM t1 e
+INNER JOIN cteReports r ON e.mid = r.id
+)
+SELECT
+level, id, mid, name,
+(SELECT name FROM t1 WHERE id= cteReports.mid) AS mname
+FROM cteReports ORDER BY level, mid;;
+Warnings:
+Warning 1264 Out of range value for column 'mid' at row 2
+Warning 1264 Out of range value for column 'mid' at row 3
+Warning 1264 Out of range value for column 'mid' at row 4
+Warning 1264 Out of range value for column 'mid' at row 5
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `level` int(1) DEFAULT NULL,
+ `id` int(11) DEFAULT NULL,
+ `mid` int(11) DEFAULT NULL,
+ `name` text DEFAULT NULL,
+ `mname` text DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+set @@sql_mode=default;
+drop table t1,t2;
+#
+# MDEV-29361: Embedded recursive / non-recursive CTE within
+# the scope of another embedded CTE with the same name
+#
+create table t1 (a int);
+insert into t1 values (4), (5);
+create table t2 (a int);
+insert into t2 values (6), (8);
+create table t3 (a int);
+insert into t3 values (1), (9);
+with recursive
+x as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1;
+a
+4
+5
+6
+7
+with recursive
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2;
+a
+6
+8
+10
+with
+cte as
+(
+with recursive
+x as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1
+where s1.a in (
+with recursive
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+a
+6
+with
+cte as
+(
+with recursive
+x(a) as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select s1.a from x as s1, x
+where s1.a = x.a and
+x.a in (
+with recursive
+x(a) as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+a
+6
+with
+cte as
+(
+with
+x as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1
+where s1.a in (
+with recursive
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+with
+cte as
+(
+with recursive
+x as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1
+where s1.a in (
+with
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+a
+6
+7
+with
+cte as
+(
+with
+x as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1
+where s1.a in (
+with
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+with
+cte as
+(
+with recursive
+y as
+(
+select a from t1 union select a+1 from y as r1 where a < 7
+)
+select * from y as s1
+where s1.a in (
+with
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+with
+cte as
+(
+with
+y(a) as
+(
+select a+5 from t1
+)
+select * from y as s1
+where s1.a in (
+with
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+with
+cte as
+(
+select (
+with
+x as
+(
+select a from x as r1
+)
+select * from x as s1
+where s1.a in (
+with recursive
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+) as r
+from t3
+)
+select * from cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+with
+cte as
+(
+select (
+with
+x as
+(
+select a from x as r1
+)
+select * from x as s1
+where s1.a < 5 and
+s1.a in (
+with
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+) as r
+from t3
+)
+select * from cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+with
+cte as
+(
+select (
+with recursive
+x(a) as
+(
+select a+3 from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1
+where s1.a < 8 and
+s1.a in (
+with recursive
+x(a) as
+(
+select a-2 from t2
+union
+select a+1 from x as r2 where a < 10
+)
+select a from x as s2
+)
+) as r
+from t3
+)
+select * from cte;
+r
+7
+7
+with
+cte as
+(
+select (
+with recursive
+x as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1
+where s1.a in (
+with recursive
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+) as r
+from t3
+)
+select * from cte;
+r
+6
+6
+create table x (a int);
+insert into x values (3), (7), (1), (5), (6);
+with
+cte as
+(
+select (
+with
+x as
+(
+select ( select a from x as r1 ) as a from t1
+)
+select * from x as s1
+where s1.a in (
+with recursive
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x s2
+)
+) as r
+from t3
+)
+select * from cte;
+ERROR 21000: Subquery returns more than 1 row
+with
+cte as
+(
+select (
+with
+x as
+(
+select ( select a from x ) as a from t1
+)
+select exists (
+with recursive
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x
+)
+) as r
+from t3
+)
+select * from cte;
+r
+1
+1
+with
+cte_e as
+(
+with
+cte as
+(
+select (
+with
+x as
+(
+select ( select a from x ) from t1
+)
+select exists (
+with recursive
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x
+)
+) as r
+from t3
+)
+select * from cte
+)
+select s1.*, s2.* from cte_e as s1, cte_e as s2;
+r r
+1 1
+1 1
+1 1
+1 1
+with
+x as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1;
+a
+4
+5
+2
+6
+7
+with
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2;
+a
+6
+8
+5
+9
+3
+7
+with recursive
+x as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1;
+a
+4
+5
+6
+7
+with recursive
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2;
+a
+6
+8
+10
+with
+cte as
+(
+with
+x as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1
+where s1.a in (
+with recursive
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+a
+6
+with
+cte as
+(
+with
+x as
+(
+select a from t1 union select a+1 from x as r1 where a < 7
+)
+select * from x as s1
+where s1.a in (
+with
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+a
+4
+6
+7
+with
+cte as
+(
+with recursive
+y as
+(
+select a from t1 union select a+1 from y as r1 where a < 7
+)
+select * from y as s1
+where s1.a in (
+with
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+a
+5
+6
+7
+with
+cte as
+(
+with
+y(a) as
+(
+select a+5 from t1
+)
+select * from y as s1
+where s1.a in (
+with
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+)
+select * from cte;
+a
+9
+with
+cte as
+(
+select (
+with
+x as
+(
+select a from x as r1
+)
+select * from x as s1
+where s1.a in (
+with
+recursive x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+) as r
+from t3
+)
+select * from cte;
+r
+6
+6
+with
+cte as
+(
+select (
+with
+x as
+(
+select a from x as r1
+)
+select * from x as s1
+where s1.a < 5 and
+s1.a in (
+with
+x as
+(
+select a from t2
+union
+select a+2 from x as r2 where a < 10
+)
+select a from x as s2
+)
+) as r
+from t3
+)
+select * from cte;
+r
+3
+3
+drop table t1,t2,t3,x;
+#
+# MDEV-30248: Embedded non-recursive CTE referring to base table 'x'
+# within a CTE with name 'x' used in a subquery from
+# select list of another CTE
+#
+CREATE TABLE x (a int) ENGINE=MyISAM;
+INSERT INTO x VALUES (3),(7),(1);
+CREATE TABLE t1 (b int) ENGINE=MYISAM;
+INSERT INTO t1 VALUES (1);
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH x AS (SELECT a FROM x AS t) SELECT 1 AS b)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT cte.c FROM cte;
+c
+1
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH x AS (SELECT a FROM x AS t) SELECT b FROM t1)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT cte.c FROM cte;
+c
+1
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH y AS (SELECT a FROM x AS t) SELECT b FROM t1)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT cte.c FROM cte;
+c
+1
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH y(b) AS (SELECT a FROM x AS t LIMIT 1) SELECT b FROM y)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT cte.c FROM cte;
+c
+3
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH x(b) AS (SELECT a FROM x AS t LIMIT 1) SELECT b FROM x)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT cte.c FROM cte;
+c
+3
+WITH x AS
+(
+SELECT
+(
+WITH x AS
+(WITH x AS (SELECT a FROM x AS t) SELECT 1 AS b)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT x.c from x;
+c
+1
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH x AS (SELECT a FROM x AS t) SELECT 2 AS b)
+SELECT r1.b FROM x AS r1, x AS r2 WHERE r1.b=r2.b
+) AS c
+)
+SELECT cte.c from cte;
+c
+2
+DROP TABLE x;
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH x AS (SELECT a FROM x AS t) SELECT 1 AS b)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT cte.c FROM cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH x AS (SELECT a FROM x AS t) SELECT b FROM t1)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT cte.c FROM cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH y AS (SELECT a FROM x AS t) SELECT b FROM t1)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT cte.c FROM cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH y(b) AS (SELECT a FROM x AS t LIMIT 1) SELECT b FROM y)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT cte.c FROM cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH x(b) AS (SELECT a FROM x AS t LIMIT 1) SELECT b FROM x)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT cte.c FROM cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+WITH x AS
+(
+SELECT
+(
+WITH x AS
+(WITH x AS (SELECT a FROM x AS t) SELECT 1 AS b)
+SELECT b FROM x AS r
+) AS c
+)
+SELECT x.c from x;
+ERROR 42S02: Table 'test.x' doesn't exist
+WITH cte AS
+(
+SELECT
+(
+WITH x AS
+(WITH x AS (SELECT a FROM x AS t) SELECT 2 AS b)
+SELECT r1.b FROM x AS r1, x AS r2 WHERE r1.b=r2.b
+) AS c
+)
+SELECT cte.c from cte;
+ERROR 42S02: Table 'test.x' doesn't exist
+DROP TABLE t1;
+#
+# End of 10.3 tests
+#
+#
+# MDEV-26108: Recursive CTE embedded into another CTE which is used twice
+#
+create table t1 (a int);
+insert into t1 values (5), (7);
+with cte_e as (
+with recursive cte_r as (
+select a from t1 union select a+1 as a from cte_r r where a < 10
+) select * from cte_r
+) select * from cte_e s1, cte_e s2 where s1.a=s2.a;
+a a
+5 5
+7 7
+6 6
+8 8
+9 9
+10 10
+drop table t1;
+#
+# MDEV-20010 Equal on two RANK window functions create wrong result
+#
+create table t1 (a int, b int) engine= innodb;
+insert into t1 values (4, -2), (3, -1);
+SELECT RANK() OVER (ORDER BY D.C) = RANK() OVER (ORDER BY B.a) FROM
+(SELECT 5 AS C FROM t1) as D, (SELECT t1.b AS A FROM t1) AS B;
+RANK() OVER (ORDER BY D.C) = RANK() OVER (ORDER BY B.a)
+1
+1
+0
+0
+select b, rank() over (order by c) , rank() over (order by dt1.b)
+from
+(select 5 as c from t1) as dt,
+(select b from t1) as dt1;
+b rank() over (order by c) rank() over (order by dt1.b)
+-2 1 1
+-2 1 1
+-1 1 3
+-1 1 3
+select b, rank() over (order by c) , rank() over (order by dt1.b),
+rank() over (order by c) = rank() over (order by dt1.b)
+from
+(select 5 as c from t1) as dt,
+(select b from t1) as dt1;
+b rank() over (order by c) rank() over (order by dt1.b) rank() over (order by c) = rank() over (order by dt1.b)
+-2 1 1 1
+-2 1 1 1
+-1 1 3 0
+-1 1 3 0
+alter table t1 engine=myisam;
+select b, rank() over (order by c) , rank() over (order by dt1.b)
+from
+(select 5 as c from t1) as dt,
+(select b from t1) as dt1;
+b rank() over (order by c) rank() over (order by dt1.b)
+-2 1 1
+-2 1 1
+-1 1 3
+-1 1 3
+create view v1 as select b,5 as c from t1;
+select b, rank() over (order by c) from v1 order by b;
+b rank() over (order by c)
+-2 1
+-1 1
+drop view v1;
+drop table t1;
+# End of 10.4 tests