2016-05-08 22:04:41 +02:00
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
2016-07-01 00:13:12 +02:00
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
2016-05-08 22:04:41 +02:00
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;
2016-07-01 00:13:12 +02:00
ERROR HY000: Unacceptable mutual recursion with anchored table 'a1'
2016-05-08 22:04:41 +02:00
drop table t1;
2016-05-24 20:29:52 +02:00
# 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 SUBQUERY 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
2016-07-27 07:58:33 +02:00
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
2016-05-24 20:29:52 +02:00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
2016-08-08 22:02:52 +02:00
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)
2016-05-24 20:29:52 +02:00
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(20) 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;
2016-05-08 22:04:41 +02:00
create table folks(id int, name char(32), dob date, father int, mother int);
insert into folks values
2016-05-19 22:17:19 +02:00
(100, 'Me', '2000-01-01', 20, 30),
2016-05-08 22:04:41 +02:00
(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),
2016-05-19 21:07:53 +02:00
(7, 'Grandma Sally', '1943-08-23', null, 6),
(8, 'Grandpa Ben', '1940-10-21', null, null),
2016-05-08 22:04:41 +02:00
(6, 'Grandgrandma Martha', '1923-05-17', null, null),
(67, 'Cousin Eddie', '1992-02-28', 25, 27),
(27, 'Auntie Melinda', '1971-03-29', null, null);
2016-08-30 07:45:17 +02:00
# simple recursion with one anchor and one recursive select
# the anchor is the first select in the specification
2016-05-08 22:04:41 +02:00
with recursive
ancestors
as
(
select *
from folks
2016-05-19 22:17:19 +02:00
where name = 'Me' and dob = '2000-01-01'
2016-05-08 22:04:41 +02:00
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
2016-05-19 22:17:19 +02:00
100 Me 2000-01-01 20 30
2016-05-08 22:04:41 +02:00
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
2016-05-19 21:07:53 +02:00
7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
2016-05-08 22:04:41 +02:00
6 Grandgrandma Martha 1923-05-17 NULL NULL
2016-08-30 07:45:17 +02:00
# simple recursion with one anchor and one recursive select
# the anchor is the last select in the specification
2016-05-08 22:04:41 +02:00
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
2016-05-19 22:17:19 +02:00
where name = 'Me' and dob = '2000-01-01'
2016-05-08 22:04:41 +02:00
)
select * from ancestors;
id name dob father mother
2016-05-19 22:17:19 +02:00
100 Me 2000-01-01 20 30
2016-05-08 22:04:41 +02:00
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
2016-05-19 21:07:53 +02:00
7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
2016-05-08 22:04:41 +02:00
6 Grandgrandma Martha 1923-05-17 NULL NULL
2016-08-30 07:45:17 +02:00
# simple recursion with one anchor and one recursive select
# the anchor is the first select in the specification
2016-05-08 22:04:41 +02:00
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
2016-05-19 21:07:53 +02:00
7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
2016-05-08 22:04:41 +02:00
6 Grandgrandma Martha 1923-05-17 NULL NULL
2016-08-30 07:58:01 +02:00
# 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
2016-08-30 07:45:17 +02:00
# two recursive definition, one uses another
2016-05-08 22:04:41 +02:00
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
2016-05-19 22:17:19 +02:00
where name='Me'
2016-05-08 22:04:41 +02:00
),
ancestors
as
(
select *
from folks
2016-05-19 22:17:19 +02:00
where name='Me'
2016-05-08 22:04:41 +02:00
union
select *
from ancestors
union
select *
from prev_gen
)
select ancestors.name, ancestors.dob from ancestors;
name dob
2016-05-19 22:17:19 +02:00
Me 2000-01-01
2016-05-08 22:04:41 +02:00
Dad 1970-02-02
Mom 1975-03-03
Grandpa Bill 1940-04-05
Grandma Ann 1941-10-15
Grandma Sally 1943-08-23
2016-05-19 21:07:53 +02:00
Grandpa Ben 1940-10-21
2016-05-08 22:04:41 +02:00
Grandgrandma Martha 1923-05-17
2016-08-30 07:45:17 +02:00
# 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
2016-05-08 22:04:41 +02:00
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
2016-05-19 22:17:19 +02:00
100 Me 2000-01-01 20 30
2016-05-08 22:04:41 +02:00
98 Sister Amy 2001-06-20 20 30
2016-08-30 07:45:17 +02:00
# simple recursion with one anchor and one recursive select
# the anchor is the first select in the specification
2016-05-08 22:04:41 +02:00
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
2016-05-19 21:07:53 +02:00
7 Grandma Sally 1943-08-23 NULL 6
2016-05-08 22:04:41 +02:00
30 Mom 1975-03-03 8 7
25 Uncle Jim 1968-11-18 8 7
2016-05-19 22:17:19 +02:00
100 Me 2000-01-01 20 30
2016-05-08 22:04:41 +02:00
98 Sister Amy 2001-06-20 20 30
67 Cousin Eddie 1992-02-28 25 27
2016-08-30 07:45:17 +02:00
# simple recursive table used three times in the main query
2016-05-08 22:04:41 +02:00
with recursive
ancestors
as
(
select *
from folks
2016-05-19 22:17:19 +02:00
where name = 'Me' and dob = '2000-01-01'
2016-05-08 22:04:41 +02:00
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
2016-05-19 21:07:53 +02:00
8 Grandpa Ben 1940-10-21 NULL NULL 7 Grandma Sally 1943-08-23 NULL 6
2016-08-30 07:45:17 +02:00
# simple recursive table used three times in the main query
2016-05-08 22:04:41 +02:00
with
ancestor_couples(husband, h_dob, wife, w_dob)
as
(
with recursive
ancestors
as
(
select *
from folks
2016-05-19 22:17:19 +02:00
where name = 'Me'
2016-05-08 22:04:41 +02:00
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
2016-05-19 21:07:53 +02:00
Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
2016-08-30 07:45:17 +02:00
# simple recursion with two selects in recursive part
2016-05-08 22:04:41 +02:00
with recursive
ancestors
as
(
select *
from folks
2016-05-19 22:17:19 +02:00
where name = 'Me'
2016-05-08 22:04:41 +02:00
union
select p.*
2016-05-14 22:33:50 +02:00
from folks as p, ancestors as fa
where p.id = fa.father
2016-05-08 22:04:41 +02:00
union
select p.*
2016-05-14 22:33:50 +02:00
from folks as p, ancestors as ma
where p.id = ma.mother
2016-05-08 22:04:41 +02:00
)
select * from ancestors;
id name dob father mother
2016-05-19 22:17:19 +02:00
100 Me 2000-01-01 20 30
2016-05-08 22:04:41 +02:00
20 Dad 1970-02-02 10 9
30 Mom 1975-03-03 8 7
10 Grandpa Bill 1940-04-05 NULL NULL
2016-05-19 21:07:53 +02:00
8 Grandpa Ben 1940-10-21 NULL NULL
2016-06-06 19:01:16 +02:00
9 Grandma Ann 1941-10-15 NULL NULL
2016-05-19 21:07:53 +02:00
7 Grandma Sally 1943-08-23 NULL 6
2016-05-08 22:04:41 +02:00
6 Grandgrandma Martha 1923-05-17 NULL NULL
2016-08-30 07:45:17 +02:00
# mutual recursion with renaming
2016-05-08 22:04:41 +02:00
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
2016-05-19 22:17:19 +02:00
where v.name = 'Me' and
2016-05-08 22:04:41 +02:00
(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
2016-05-19 21:07:53 +02:00
Grandpa Ben 1940-10-21 Grandma Sally 1943-08-23
2016-08-30 07:45:17 +02:00
# mutual recursion with union all
2016-06-06 19:01:16 +02:00
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
2016-08-30 07:45:17 +02:00
# 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
2016-06-06 19:01:16 +02:00
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
2016-08-30 07:45:17 +02:00
# mutual recursion with one select in the first definition
2016-06-06 19:01:16 +02:00
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
2016-08-30 07:45:17 +02:00
# join of a mutually recursive table with base tables
2016-06-06 19:01:16 +02:00
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
2016-08-30 07:45:17 +02:00
# join of two mutually recursive tables
2016-06-06 19:01:16 +02:00
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
2016-07-27 07:58:33 +02:00
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
2016-06-06 19:01:16 +02:00
3 SUBQUERY folks ALL NULL NULL NULL NULL 12 100.00 Using where
2016-08-08 22:02:52 +02:00
4 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
4 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
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)
2016-06-06 19:01:16 +02:00
NULL UNION RESULT <union3,4,5> ALL NULL NULL NULL NULL NULL NULL
2016-07-27 07:58:33 +02:00
2 UNCACHEABLE SUBQUERY <derived3> ALL NULL NULL NULL NULL 12 100.00 Using where
2016-06-06 19:01:16 +02:00
Warnings:
2016-07-27 07:58:33 +02:00
Note 1003 with recursive ancestor_couple_ids as (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 as (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 `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 `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 `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`))
2016-08-30 07:45:17 +02:00
# simple mutual recursion
2016-06-06 19:01:16 +02:00
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
2016-08-30 07:45:17 +02:00
# join of two mutually recursive tables
2016-06-06 19:01:16 +02:00
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
2016-08-30 07:45:17 +02:00
# execution of prepared query using a recursive table
2016-05-12 22:23:12 +02:00
prepare stmt1 from "
with recursive
ancestors
as
(
select *
from folks
2016-05-19 22:17:19 +02:00
where name = 'Me' and dob = '2000-01-01'
2016-05-12 22:23:12 +02:00
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
2016-05-19 22:17:19 +02:00
100 Me 2000-01-01 20 30
2016-05-12 22:23:12 +02:00
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
2016-05-19 21:07:53 +02:00
7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
2016-05-12 22:23:12 +02:00
6 Grandgrandma Martha 1923-05-17 NULL NULL
execute stmt1;
id name dob father mother
2016-05-19 22:17:19 +02:00
100 Me 2000-01-01 20 30
2016-05-12 22:23:12 +02:00
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
2016-05-19 21:07:53 +02:00
7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
2016-05-12 22:23:12 +02:00
6 Grandgrandma Martha 1923-05-17 NULL NULL
deallocate prepare stmt1;
2016-08-30 07:45:17 +02:00
# view using a recursive table
2016-05-12 22:23:12 +02:00
create view v1 as
with recursive
ancestors
as
(
select *
from folks
2016-05-19 22:17:19 +02:00
where name = 'Me' and dob = '2000-01-01'
2016-05-12 22:23:12 +02:00
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
2016-05-19 22:17:19 +02:00
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
2016-05-12 22:23:12 +02:00
select * from v1;
id name dob father mother
2016-05-19 22:17:19 +02:00
100 Me 2000-01-01 20 30
2016-05-12 22:23:12 +02:00
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
2016-05-19 21:07:53 +02:00
7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
2016-05-12 22:23:12 +02:00
6 Grandgrandma Martha 1923-05-17 NULL NULL
2016-05-14 22:33:50 +02:00
create view v2 as
with recursive
ancestors
as
(
select *
from folks
2016-05-19 22:17:19 +02:00
where name = 'Me'
2016-05-14 22:33:50 +02:00
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
2016-05-19 22:17:19 +02:00
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
2016-05-14 22:33:50 +02:00
select * from v2;
id name dob father mother
2016-05-19 22:17:19 +02:00
100 Me 2000-01-01 20 30
2016-05-14 22:33:50 +02:00
20 Dad 1970-02-02 10 9
30 Mom 1975-03-03 8 7
10 Grandpa Bill 1940-04-05 NULL NULL
2016-05-19 21:07:53 +02:00
8 Grandpa Ben 1940-10-21 NULL NULL
2016-06-06 19:01:16 +02:00
9 Grandma Ann 1941-10-15 NULL NULL
2016-05-19 21:07:53 +02:00
7 Grandma Sally 1943-08-23 NULL 6
2016-05-14 22:33:50 +02:00
6 Grandgrandma Martha 1923-05-17 NULL NULL
drop view v1,v2;
2016-05-12 22:23:12 +02:00
explain extended
with recursive
ancestors
as
(
select *
from folks
2016-05-19 22:17:19 +02:00
where name = 'Me' and dob = '2000-01-01'
2016-05-12 22:23:12 +02:00
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
2016-07-27 07:58:33 +02:00
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 12 100.00
2016-05-19 21:07:53 +02:00
2 SUBQUERY folks ALL NULL NULL NULL NULL 12 100.00 Using where
2016-08-08 22:02:52 +02:00
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)
2016-05-12 22:23:12 +02:00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
2016-05-19 22:17:19 +02:00
Note 1003 with recursive ancestors as (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 `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 `ancestors`.`id` AS `id`,`ancestors`.`name` AS `name`,`ancestors`.`dob` AS `dob`,`ancestors`.`father` AS `father`,`ancestors`.`mother` AS `mother` from `ancestors`
2016-08-30 07:45:17 +02:00
# recursive spec with two anchor selects and two recursive ones
2016-05-19 21:07:53 +02:00
with recursive
ancestor_ids (id)
as
(
2016-05-19 22:17:19 +02:00
select father from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
union
2016-05-19 22:17:19 +02:00
select mother from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
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
2016-07-27 07:58:33 +02:00
8 Grandpa Ben 1940-10-21 NULL NULL
2016-05-19 21:07:53 +02:00
6 Grandgrandma Martha 1923-05-17 NULL NULL
2016-08-30 07:45:17 +02:00
# recursive spec using union all
2016-05-19 21:07:53 +02:00
with recursive
ancestors
as
(
select *
from folks
2016-05-19 22:17:19 +02:00
where name = 'Me'
2016-05-19 21:07:53 +02:00
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
2016-05-19 22:17:19 +02:00
100 Me 2000-01-01 20 30
2016-05-19 21:07:53 +02:00
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
(
2016-05-19 22:17:19 +02:00
select father, 1 from folks where name = 'Me' and father is not null
2016-05-19 21:07:53 +02:00
union all
2016-05-19 22:17:19 +02:00
select mother, 1 from folks where name = 'Me' and mother is not null
2016-05-19 21:07:53 +02:00
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 standards_compliant_cte=0;
with recursive
ancestor_ids (id, generation)
as
(
2016-05-19 22:17:19 +02:00
select father from folks where name = 'Me' and father is not null
2016-05-19 21:07:53 +02:00
union all
2016-05-19 22:17:19 +02:00
select mother from folks where name = 'Me' and mother is not null
2016-05-19 21:07:53 +02:00
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
(
2016-05-19 22:17:19 +02:00
select father, 1 from folks where name = 'Me' and father is not null
2016-05-19 21:07:53 +02:00
union all
2016-05-19 22:17:19 +02:00
select mother, 1 from folks where name = 'Me' and mother is not null
2016-05-19 21:07:53 +02:00
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
2016-07-27 07:58:33 +02:00
2 Grandpa Ben
2016-05-19 21:07:53 +02:00
3 Grandgrandma Martha
set standards_compliant_cte=1;
with recursive
coupled_ancestor_ids (id)
as
(
2016-05-19 22:17:19 +02:00
select father from folks where name = 'Me' and father is not null
2016-05-19 21:07:53 +02:00
union
2016-05-19 22:17:19 +02:00
select mother from folks where name = 'Me' and mother is not null
2016-05-19 21:07:53 +02:00
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 standards_compliant_cte=0 for
with recursive
coupled_ancestor_ids (id)
as
(
2016-05-19 22:17:19 +02:00
select father from folks where name = 'Me' and father is not null
2016-05-19 21:07:53 +02:00
union
2016-05-19 22:17:19 +02:00
select mother from folks where name = 'Me' and mother is not null
2016-05-19 21:07:53 +02:00
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
2016-07-27 07:58:33 +02:00
8 Grandpa Ben 1940-10-21 NULL NULL
2016-05-19 21:07:53 +02:00
with recursive
ancestor_ids (id)
as
(
2016-05-19 22:17:19 +02:00
select father from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
union
2016-05-19 22:17:19 +02:00
select mother from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
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 standards_compliant_cte=0 for
with recursive
ancestor_ids (id)
as
(
2016-05-19 22:17:19 +02:00
select father from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
union
2016-05-19 22:17:19 +02:00
select mother from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
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
2016-07-27 07:58:33 +02:00
25 Uncle Jim 1968-11-18 8 7
2016-05-19 21:07:53 +02:00
7 Grandma Sally 1943-08-23 NULL 6
2016-07-27 07:58:33 +02:00
8 Grandpa Ben 1940-10-21 NULL NULL
2016-05-19 21:07:53 +02:00
6 Grandgrandma Martha 1923-05-17 NULL NULL
27 Auntie Melinda 1971-03-29 NULL NULL
with recursive
ancestor_ids (id, generation)
as
(
2016-05-19 22:17:19 +02:00
select father, 1 from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
union
2016-05-19 22:17:19 +02:00
select mother, 1 from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
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
2016-07-27 07:58:33 +02:00
2 Grandpa Ben
2016-05-19 21:07:53 +02:00
3 Grandgrandma Martha
with recursive
ancestor_ids (id, generation)
as
(
2016-05-19 22:17:19 +02:00
select father, 1 from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
union
2016-05-19 22:17:19 +02:00
select mother, 1 from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
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 standards_compliant_cte=0 for
with recursive
ancestor_ids (id, generation)
as
(
2016-05-19 22:17:19 +02:00
select father, 1 from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
union
2016-05-19 22:17:19 +02:00
select mother, 1 from folks where name = 'Me'
2016-05-19 21:07:53 +02:00
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
2016-08-11 00:51:40 +02:00
set statement max_recursive_iterations=1 for
2016-05-24 20:29:52 +02:00
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
2016-07-27 07:58:33 +02:00
2 Grandpa Ben
2016-08-30 07:45:17 +02:00
# query with recursive tables using key access
2016-07-27 07:58:33 +02:00
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 SUBQUERY folks ALL NULL NULL NULL NULL 12 Using where
2016-08-08 22:02:52 +02:00
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
2016-07-27 07:58:33 +02:00
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
2016-08-08 22:02:52 +02:00
#
# 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 SUBQUERY folks ALL NULL NULL NULL NULL 12 Using where
6 RECURSIVE UNION <derived3> ALL NULL NULL NULL NULL 12
5 RECURSIVE UNION <derived4> ALL NULL NULL NULL NULL 24
NULL UNION RESULT <union4,6,5> ALL NULL NULL NULL NULL NULL
3 SUBQUERY 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,
"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,
"table": {
"table_name": "folks",
"access_type": "ALL",
"rows": 12,
"filtered": 100,
"attached_condition": "(folks.`name` = 'Me2')"
}
}
},
{
"query_block": {
"select_id": 6,
"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,
"table": {
"table_name": "folks",
"access_type": "ALL",
"rows": 12,
"filtered": 100,
"attached_condition": "(folks.`name` = 'Me')"
}
}
},
{
"query_block": {
"select_id": 2,
"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": "256Kb",
"join_type": "BNL",
"attached_condition": "((prev_gen.father = folks.`id`) or (prev_gen.mother = folks.`id`))"
}
}
}
]
}
}
}
}
}
},
{
"query_block": {
"select_id": 5,
"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,
"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,
"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,
"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
}
}
}
]
}
}
}
}
}
}
2016-09-22 10:45:05 +02:00
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;
2016-09-25 05:29:56 +02:00
#
# 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;
2016-09-25 06:04:54 +02:00
#
# 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;
2016-05-08 22:04:41 +02:00
drop table folks;
2016-08-08 22:02:52 +02:00
#
# 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
2016-08-11 00:51:40 +02:00
with recursive t as (select a from t1 union select a+10 from t where a < 1000)
select * from t;
2016-08-08 22:02:52 +02:00
EXPLAIN
{
"query_block": {
"select_id": 1,
"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,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 10,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 3,
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 10,
"filtered": 100,
2016-08-11 00:51:40 +02:00
"attached_condition": "(t.a < 1000)"
2016-08-08 22:02:52 +02:00
}
}
}
]
}
}
}
}
}
}
drop table t1;
2016-09-06 08:07:31 +02:00
#
# 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
2016-09-09 22:25:02 +02:00
#
# 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;