mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
46a2e41398
Added the check whether there are set functions in the specifications of recursive CTE. Added the check whether there are recursive references in subqueries. Introduced boolean system variable 'standards_compliant_cte'. By default it's set to 'on'. When it's set to 'off' non-standard compliant CTE can be executed.
719 lines
20 KiB
Text
719 lines
20 KiB
Text
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
|
|
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: No anchors for recursive WITH element 'b1'
|
|
drop table t1;
|
|
create table folks(id int, name char(32), dob date, father int, mother int);
|
|
insert into folks values
|
|
(100, 'Vasya', '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
|
|
ancestors
|
|
as
|
|
(
|
|
select *
|
|
from folks
|
|
where name = 'Vasya' 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 Vasya 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
|
|
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 = 'Vasya' and dob = '2000-01-01'
|
|
)
|
|
select * from ancestors;
|
|
id name dob father mother
|
|
100 Vasya 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
|
|
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
|
|
with recursive
|
|
ancestors
|
|
as
|
|
(
|
|
select *
|
|
from folks
|
|
where name = 'Vasya' 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 Vasya 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
|
|
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='Vasya'
|
|
),
|
|
ancestors
|
|
as
|
|
(
|
|
select *
|
|
from folks
|
|
where name='Vasya'
|
|
union
|
|
select *
|
|
from ancestors
|
|
union
|
|
select *
|
|
from prev_gen
|
|
)
|
|
select ancestors.name, ancestors.dob from ancestors;
|
|
name dob
|
|
Vasya 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
|
|
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 Vasya 2000-01-01 20 30
|
|
98 Sister Amy 2001-06-20 20 30
|
|
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 Vasya 2000-01-01 20 30
|
|
98 Sister Amy 2001-06-20 20 30
|
|
67 Cousin Eddie 1992-02-28 25 27
|
|
with recursive
|
|
ancestors
|
|
as
|
|
(
|
|
select *
|
|
from folks
|
|
where name = 'Vasya' 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
|
|
with
|
|
ancestor_couples(husband, h_dob, wife, w_dob)
|
|
as
|
|
(
|
|
with recursive
|
|
ancestors
|
|
as
|
|
(
|
|
select *
|
|
from folks
|
|
where name = 'Vasya'
|
|
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
|
|
with recursive
|
|
ancestors
|
|
as
|
|
(
|
|
select *
|
|
from folks
|
|
where name = 'Vasya'
|
|
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 Vasya 2000-01-01 20 30
|
|
20 Dad 1970-02-02 10 9
|
|
30 Mom 1975-03-03 8 7
|
|
9 Grandma Ann 1941-10-15 NULL NULL
|
|
10 Grandpa Bill 1940-04-05 NULL NULL
|
|
8 Grandpa Ben 1940-10-21 NULL NULL
|
|
7 Grandma Sally 1943-08-23 NULL 6
|
|
6 Grandgrandma Martha 1923-05-17 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 = 'Vasya' 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
|
|
prepare stmt1 from "
|
|
with recursive
|
|
ancestors
|
|
as
|
|
(
|
|
select *
|
|
from folks
|
|
where name = 'Vasya' 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 Vasya 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 Vasya 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;
|
|
create view v1 as
|
|
with recursive
|
|
ancestors
|
|
as
|
|
(
|
|
select *
|
|
from folks
|
|
where name = 'Vasya' 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` = 'Vasya') 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 Vasya 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 = 'Vasya'
|
|
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` = 'Vasya') 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 Vasya 2000-01-01 20 30
|
|
20 Dad 1970-02-02 10 9
|
|
30 Mom 1975-03-03 8 7
|
|
9 Grandma Ann 1941-10-15 NULL NULL
|
|
10 Grandpa Bill 1940-04-05 NULL NULL
|
|
8 Grandpa Ben 1940-10-21 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 = 'Vasya' 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 156 100.00
|
|
2 SUBQUERY folks ALL NULL NULL NULL NULL 12 100.00 Using where
|
|
3 UNCACHEABLE UNION p ALL NULL NULL NULL NULL 12 100.00
|
|
3 UNCACHEABLE 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 `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` = 'Vasya') 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`
|
|
with recursive
|
|
ancestor_ids (id)
|
|
as
|
|
(
|
|
select father from folks where name = 'Vasya'
|
|
union
|
|
select mother from folks where name = 'Vasya'
|
|
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
|
|
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
|
|
ancestors
|
|
as
|
|
(
|
|
select *
|
|
from folks
|
|
where name = 'Vasya'
|
|
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 Vasya 2000-01-01 20 30
|
|
20 Dad 1970-02-02 10 9
|
|
30 Mom 1975-03-03 8 7
|
|
9 Grandma Ann 1941-10-15 NULL NULL
|
|
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 = 'Vasya' and father is not null
|
|
union all
|
|
select mother, 1 from folks where name = 'Vasya' 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 standards_compliant_cte=0;
|
|
set optimizer_switch='materialization=off,subquery_cache=off';
|
|
with recursive
|
|
ancestor_ids (id, generation)
|
|
as
|
|
(
|
|
select father from folks where name = 'Vasya' and father is not null
|
|
union all
|
|
select mother from folks where name = 'Vasya' 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 = 'Vasya' and father is not null
|
|
union all
|
|
select mother, 1 from folks where name = 'Vasya' 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 Grandpa Ben
|
|
2 Grandma Ann
|
|
2 Grandma Sally
|
|
3 Grandgrandma Martha
|
|
set optimizer_switch=default;
|
|
set standards_compliant_cte=1;
|
|
with recursive
|
|
coupled_ancestor_ids (id)
|
|
as
|
|
(
|
|
select father from folks where name = 'Vasya' and father is not null
|
|
union
|
|
select mother from folks where name = 'Vasya' 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 standards_compliant_cte=0 for
|
|
with recursive
|
|
coupled_ancestor_ids (id)
|
|
as
|
|
(
|
|
select father from folks where name = 'Vasya' and father is not null
|
|
union
|
|
select mother from folks where name = 'Vasya' 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
|
|
8 Grandpa Ben 1940-10-21 NULL NULL
|
|
9 Grandma Ann 1941-10-15 NULL NULL
|
|
7 Grandma Sally 1943-08-23 NULL 6
|
|
with recursive
|
|
ancestor_ids (id)
|
|
as
|
|
(
|
|
select father from folks where name = 'Vasya'
|
|
union
|
|
select mother from folks where name = 'Vasya'
|
|
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
|
|
(
|
|
select father from folks where name = 'Vasya'
|
|
union
|
|
select mother from folks where name = 'Vasya'
|
|
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
|
|
8 Grandpa Ben 1940-10-21 NULL NULL
|
|
25 Uncle Jim 1968-11-18 8 7
|
|
9 Grandma Ann 1941-10-15 NULL NULL
|
|
7 Grandma Sally 1943-08-23 NULL 6
|
|
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 = 'Vasya'
|
|
union
|
|
select mother, 1 from folks where name = 'Vasya'
|
|
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 Grandpa Ben
|
|
2 Grandma Ann
|
|
2 Grandma Sally
|
|
3 Grandgrandma Martha
|
|
with recursive
|
|
ancestor_ids (id, generation)
|
|
as
|
|
(
|
|
select father, 1 from folks where name = 'Vasya'
|
|
union
|
|
select mother, 1 from folks where name = 'Vasya'
|
|
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
|
|
(
|
|
select father, 1 from folks where name = 'Vasya'
|
|
union
|
|
select mother, 1 from folks where name = 'Vasya'
|
|
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
|
|
drop table folks;
|