234 lines
4.3 KiB
SQL
234 lines
4.3 KiB
SQL
# name: test/sql/cte/test_cte.test
|
|
# description: Test Common Table Expressions (CTE)
|
|
# group: [cte]
|
|
|
|
statement ok
|
|
PRAGMA enable_verification
|
|
|
|
statement ok
|
|
create table a(i integer);
|
|
|
|
statement ok
|
|
insert into a values (42);
|
|
|
|
query I
|
|
with cte1 as (Select i as j from a) select * from cte1;
|
|
----
|
|
42
|
|
|
|
query I
|
|
with cte1 as (Select i as j from a) select x from cte1 t1(x);
|
|
----
|
|
42
|
|
|
|
query I
|
|
with cte1(xxx) as (Select i as j from a) select xxx from cte1;
|
|
----
|
|
42
|
|
|
|
query I
|
|
with cte1(xxx) as (Select i as j from a) select x from cte1 t1(x);
|
|
----
|
|
42
|
|
|
|
query II
|
|
with cte1 as (Select i as j from a), cte2 as (select ref.j as k from cte1 as ref), cte3 as (select ref2.j+1 as i from cte1 as ref2) select * from cte2 , cte3;
|
|
----
|
|
42 43
|
|
|
|
query I
|
|
with cte1 as (select i as j from a), cte2 as (select ref.j as k from cte1 as ref), cte3 as (select ref2.j+1 as i from cte1 as ref2) select * from cte2 union all select * FROM cte3;
|
|
----
|
|
42
|
|
43
|
|
|
|
# duplicate CTE alias
|
|
statement error
|
|
with cte1 as (select 42), cte1 as (select 42) select * FROM cte1;
|
|
----
|
|
|
|
|
|
# multiple uses of same CTE
|
|
query II
|
|
with cte1 as (Select i as j from a) select * from cte1 cte11, cte1 cte12;
|
|
----
|
|
42 42
|
|
|
|
# refer to CTE in subquery
|
|
query I
|
|
with cte1 as (Select i as j from a) select * from cte1 where j = (select max(j) from cte1 as cte2);
|
|
----
|
|
42
|
|
|
|
# multi-column name alias
|
|
query II
|
|
with cte1(x, y) as (select 42 a, 84 b) select zzz, y from cte1 t1(zzz);
|
|
----
|
|
42 84
|
|
|
|
# use a CTE in a view definition
|
|
statement ok
|
|
create view va AS (with cte as (Select i as j from a) select * from cte);
|
|
|
|
query I
|
|
select * from va
|
|
----
|
|
42
|
|
|
|
# nested CTE views that re-use CTE aliases
|
|
query I
|
|
with cte AS (SELECT * FROM va) SELECT * FROM cte;
|
|
----
|
|
42
|
|
|
|
# multiple ctes in a view definition
|
|
statement ok
|
|
create view vb AS (with cte1 as (Select i as j from a), cte2 as (select ref.j+1 as k from cte1 as ref) select * from cte2);
|
|
|
|
query I
|
|
select * from vb
|
|
----
|
|
43
|
|
|
|
# cte in set operation node
|
|
query I
|
|
SELECT 1 UNION ALL (WITH cte AS (SELECT 42) SELECT * FROM cte);
|
|
----
|
|
1
|
|
42
|
|
|
|
# cte in nested set operation node
|
|
query I
|
|
SELECT 1 UNION ALL (WITH cte AS (SELECT 42) SELECT * FROM cte UNION ALL SELECT * FROM cte);
|
|
----
|
|
1
|
|
42
|
|
42
|
|
|
|
# cte in recursive cte
|
|
query I
|
|
WITH RECURSIVE cte(d) AS (
|
|
SELECT 1
|
|
UNION ALL
|
|
(WITH c(d) AS (SELECT * FROM cte)
|
|
SELECT d + 1
|
|
FROM c
|
|
WHERE FALSE
|
|
)
|
|
)
|
|
SELECT max(d) FROM cte;
|
|
----
|
|
1
|
|
|
|
# test CTE with nested aliases in where clause
|
|
query II
|
|
with cte (a) as (
|
|
select 1
|
|
)
|
|
select
|
|
a as alias1,
|
|
alias1 as alias2
|
|
from cte
|
|
where alias2 > 0;
|
|
----
|
|
1 1
|
|
|
|
# recursive CTE and a non-recursive CTE with except
|
|
query I
|
|
WITH RECURSIVE t AS (
|
|
SELECT 1 AS a
|
|
UNION ALL
|
|
SELECT a+1
|
|
FROM t
|
|
WHERE a < 10
|
|
), s AS (
|
|
(VALUES (5), (6), (7), (8), (9), (10), (11), (12), (13), (42))
|
|
EXCEPT
|
|
TABLE t
|
|
)
|
|
SELECT * FROM s AS _(x) ORDER BY x;
|
|
----
|
|
11
|
|
12
|
|
13
|
|
42
|
|
|
|
# recursive CTE with except in recursive part (but not as a recursive anchor)
|
|
query I
|
|
WITH RECURSIVE t AS (
|
|
select 1 as a
|
|
union all
|
|
(select a+1
|
|
from t
|
|
where a < 10
|
|
except
|
|
SELECT 4)
|
|
), s AS (
|
|
(values (5), (6), (7))
|
|
except
|
|
table t
|
|
)
|
|
SELECT * FROM s AS _(x) ORDER BY x;
|
|
----
|
|
5
|
|
6
|
|
7
|
|
|
|
query I
|
|
WITH RECURSIVE
|
|
t(b) AS MATERIALIZED (
|
|
(WITH helper(c) AS (
|
|
SELECT 5
|
|
), h1 AS
|
|
(SELECT * FROM helper h
|
|
UNION
|
|
SELECT 7 FROM helper h)
|
|
SELECT * FROM h1)
|
|
)
|
|
SELECT * FROM t ORDER BY b;
|
|
----
|
|
5
|
|
7
|
|
|
|
require no_alternative_verify
|
|
|
|
# FIXME: this one should work with ALTERNATIVE_VERIFY, but doesn't yet
|
|
# something wrong with binding a CTE inside a recursive CTE
|
|
query I
|
|
WITH RECURSIVE
|
|
t(b) AS MATERIALIZED (
|
|
(WITH helper(c) AS (
|
|
SELECT 5
|
|
)
|
|
SELECT * FROM helper h
|
|
UNION
|
|
SELECT 7
|
|
)
|
|
)
|
|
SELECT * FROM t ORDER BY b;
|
|
----
|
|
5
|
|
7
|
|
|
|
# reference to CTE before its actually defined, can't with ALTERNATIVE_VERIFY because everything gets materialized
|
|
statement error
|
|
with cte3 as (select ref2.j as i from cte1 as ref2), cte1 as (Select i as j from a), cte2 as (select ref.j+1 as k from cte1 as ref) select * from cte2 union all select * FROM cte3;
|
|
----
|
|
Catalog Error: Table with name cte1 does not exist!
|
|
|
|
statement error
|
|
WITH t(x) AS (SELECT x)
|
|
SELECT *
|
|
FROM range(10) AS _(x), LATERAL (SELECT * FROM t);
|
|
----
|
|
|
|
statement error
|
|
WITH cte AS (SELECT x)
|
|
SELECT b.x
|
|
FROM (SELECT 1) _(x), LATERAL (SELECT * FROM cte) b(x)
|
|
----
|
|
|
|
query III
|
|
WITH RECURSIVE rec(a, b, c) AS (select a,b,c from (values(1,2,3),(1,2,3)) s(a,b,c) union select 1,2,3) select * from rec;
|
|
----
|
|
1 2 3 |