should be it
This commit is contained in:
35
external/duckdb/test/sql/cte/cte_bc.test
vendored
Normal file
35
external/duckdb/test/sql/cte/cte_bc.test
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# name: test/sql/cte/cte_bc.test
|
||||
# description: Test BC of reading CTEs
|
||||
# group: [cte]
|
||||
|
||||
# The database is written with a vector size of 2048.
|
||||
require vector_size 2048
|
||||
|
||||
unzip data/storage/cte_v1.db.gz __TEST_DIR__/cte_v1.db
|
||||
|
||||
unzip data/storage/cte_v1_4.db.gz __TEST_DIR__/cte_v1_4.db
|
||||
|
||||
statement ok
|
||||
ATTACH '__TEST_DIR__/cte_v1.db' (READ_ONLY)
|
||||
|
||||
statement ok
|
||||
ATTACH '__TEST_DIR__/cte_v1_4.db' (READ_ONLY)
|
||||
|
||||
foreach cte_db cte_v1 cte_v1_4
|
||||
|
||||
query I
|
||||
FROM ${cte_db}.v1
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
FROM ${cte_db}.v2
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
FROM ${cte_db}.v3
|
||||
----
|
||||
42
|
||||
|
||||
endloop
|
||||
16
external/duckdb/test/sql/cte/cte_colname_issue_10074.test
vendored
Normal file
16
external/duckdb/test/sql/cte/cte_colname_issue_10074.test
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# name: test/sql/cte/cte_colname_issue_10074.test
|
||||
# description: Issue #10074 - CTE returns wrong column name
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
pragma enable_verification
|
||||
|
||||
statement ok
|
||||
create table t as with q(id,s) as (values(1,42)),
|
||||
a(s)as materialized(select 42)
|
||||
select id from q join a on q.s=a.s
|
||||
|
||||
query I
|
||||
select id from t
|
||||
----
|
||||
1
|
||||
34
external/duckdb/test/sql/cte/cte_describe.test
vendored
Normal file
34
external/duckdb/test/sql/cte/cte_describe.test
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# name: test/sql/cte/cte_describe.test
|
||||
# description: Test CTE describe
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
query I nosort describe
|
||||
DESCRIBE select 42 AS a
|
||||
|
||||
query I nosort describe
|
||||
with cte as (select 42 AS a) FROM (DESCRIBE TABLE cte)
|
||||
|
||||
query I nosort describe
|
||||
with cte as (select 42 AS a) FROM (DESCRIBE TABLE cte)
|
||||
|
||||
query I nosort summarize
|
||||
SUMMARIZE select 42 AS a
|
||||
|
||||
query I nosort summarize
|
||||
with cte as (select 42 AS a) FROM (SUMMARIZE TABLE cte)
|
||||
|
||||
query I nosort summarize
|
||||
with cte as (select 42 AS a) FROM (SUMMARIZE TABLE cte)
|
||||
|
||||
statement error
|
||||
with cte as (select 42 AS a) (DESCRIBE TABLE cte)
|
||||
----
|
||||
Parser Error: exprLocation NOT IMPLEMENTED
|
||||
|
||||
statement error
|
||||
(DESCRIBE TABLE cte) ORDER BY 1
|
||||
----
|
||||
Parser Error: exprLocation NOT IMPLEMENTED
|
||||
21
external/duckdb/test/sql/cte/cte_issue_17311.test
vendored
Normal file
21
external/duckdb/test/sql/cte/cte_issue_17311.test
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# name: test/sql/cte/cte_issue_17311.test
|
||||
# description: Test for CTE issue #17311
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE RECURSIVE VIEW nums (n) AS
|
||||
VALUES (1)
|
||||
UNION ALL
|
||||
SELECT n+1 FROM nums WHERE n < 5;
|
||||
|
||||
query I
|
||||
FROM nums
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
18
external/duckdb/test/sql/cte/cte_schema.test
vendored
Normal file
18
external/duckdb/test/sql/cte/cte_schema.test
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# name: test/sql/cte/cte_schema.test
|
||||
# description: Test conflict between CTE and table in different schema
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
create schema s1;
|
||||
|
||||
statement ok
|
||||
create table s1.tbl(a varchar);
|
||||
|
||||
statement ok
|
||||
insert into s1.tbl values ('hello');
|
||||
|
||||
query II
|
||||
with tbl as (select 'world' b)
|
||||
select * from s1.tbl, tbl;
|
||||
----
|
||||
hello world
|
||||
19
external/duckdb/test/sql/cte/cte_with_replacement_scan.test
vendored
Normal file
19
external/duckdb/test/sql/cte/cte_with_replacement_scan.test
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# name: test/sql/cte/cte_with_replacement_scan.test
|
||||
# description: Test CTE with same name as file
|
||||
# group: [cte]
|
||||
|
||||
require parquet
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
copy (select 42 as answer) to '__TEST_DIR__/df.parquet';
|
||||
|
||||
query I
|
||||
WITH '__TEST_DIR__/df.parquet' AS (
|
||||
SELECT answer FROM '__TEST_DIR__/df.parquet'
|
||||
)
|
||||
SELECT * FROM '__TEST_DIR__/df.parquet';
|
||||
----
|
||||
42
|
||||
65
external/duckdb/test/sql/cte/game_of_life.test_slow
vendored
Normal file
65
external/duckdb/test/sql/cte/game_of_life.test_slow
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
# name: test/sql/cte/game_of_life.test_slow
|
||||
# description: Run conways game of life as a CTE (https://gist.github.com/janickr/58fab629ee3ea7e5638a)
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
create table series as select * from generate_series(-1,1) x(n);
|
||||
|
||||
# conway
|
||||
query III
|
||||
with recursive generation1(x,y) as ( --the initial board setup
|
||||
select 2, 3
|
||||
union
|
||||
select 3, 3
|
||||
union
|
||||
select 4, 3
|
||||
),
|
||||
game(n, x, y) as (
|
||||
select 1 AS n, x, y from generation1 -- generation 1 is initial board setup
|
||||
union all
|
||||
select n+1, new_x, new_y from -- generation n+1
|
||||
(
|
||||
select n, x+offset_x new_x, y+offset_y new_y, max(self) over (partition by n+1, x+offset_x, y+offset_y) cell_was_already_alive
|
||||
from game, (
|
||||
select x.n offset_x, y.n offset_y, case when x.n = 0 and y.n = 0 then 1 else 0 end self
|
||||
from series x(n), series y(n) --join 2 row generators to get 9 pairs
|
||||
) offsets_to_neighbours_and_self(offset_x, offset_y, self)
|
||||
where n < 100
|
||||
) all_impacts
|
||||
group by n+1, new_x, new_y, cell_was_already_alive -- from all impacts back to cells
|
||||
having (cell_was_already_alive=1 and count(*) < 5 and count(*) > 2) or count(*) = 3 --decide if cell is alive
|
||||
)
|
||||
select * from game where n=4 order by n, x, y; --select generation 4
|
||||
----
|
||||
4 3 2
|
||||
4 3 3
|
||||
4 3 4
|
||||
|
||||
query III
|
||||
with recursive generation1(x,y) as ( --the initial board setup
|
||||
select 2, 3
|
||||
union
|
||||
select 3, 3
|
||||
union
|
||||
select 4, 3
|
||||
),
|
||||
game(n, x, y) as (
|
||||
select 1 AS n, x, y from generation1 -- generation 1 is initial board setup
|
||||
union all
|
||||
select n+1, new_x, new_y from -- generation n+1
|
||||
(
|
||||
select n, x+offset_x new_x, y+offset_y new_y, max(self) over (partition by n+1, x+offset_x, y+offset_y) cell_was_already_alive
|
||||
from game, (
|
||||
select x.n offset_x, y.n offset_y, case when x.n = 0 and y.n = 0 then 1 else 0 end self
|
||||
from generate_series(-1,1) x(n), generate_series(-1,1) y(n) --join 2 row generators to get 9 pairs
|
||||
) offsets_to_neighbours_and_self(offset_x, offset_y, self)
|
||||
where n < 100
|
||||
) all_impacts
|
||||
group by n+1, new_x, new_y, cell_was_already_alive -- from all impacts back to cells
|
||||
having (cell_was_already_alive=1 and count(*) < 5 and count(*) > 2) or count(*) = 3 --decide if cell is alive
|
||||
)
|
||||
select * from game where n=4 order by n, x, y; --select generation 4
|
||||
----
|
||||
4 3 2
|
||||
4 3 3
|
||||
4 3 4
|
||||
18
external/duckdb/test/sql/cte/incorrect_recursive_cte.test
vendored
Normal file
18
external/duckdb/test/sql/cte/incorrect_recursive_cte.test
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# name: test/sql/cte/incorrect_recursive_cte.test
|
||||
# description: Incorrect recursive ctes
|
||||
# group: [cte]
|
||||
|
||||
# recursive CTE without UNION is just a normal CTE
|
||||
query I
|
||||
WITH RECURSIVE cte AS (SELECT 42) SELECT * FROM cte;
|
||||
----
|
||||
42
|
||||
|
||||
# we only support recursive ctes with union or union all
|
||||
statement error
|
||||
with recursive t as (select 1 as x intersect select x+1 from t where x < 3) select * from t order by x
|
||||
----
|
||||
|
||||
statement error
|
||||
with recursive t as (select 1 as x except select x+1 from t where x < 3) select * from t order by x
|
||||
----
|
||||
17
external/duckdb/test/sql/cte/insert_cte_bug_3417.test
vendored
Normal file
17
external/duckdb/test/sql/cte/insert_cte_bug_3417.test
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# name: test/sql/cte/insert_cte_bug_3417.test
|
||||
# description: Test for a crash reported in issue #3417
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE table1 (id INTEGER, a INTEGER);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE table2 (table1_id INTEGER);
|
||||
|
||||
statement error
|
||||
INSERT INTO table2 WITH cte AS (INSERT INTO table1 SELECT 1, 2 RETURNING id) SELECT id FROM cte;
|
||||
----
|
||||
<REGEX>:.*Parser Error.*A CTE needs a SELECT.*
|
||||
12
external/duckdb/test/sql/cte/lazy_cte_bind.test
vendored
Normal file
12
external/duckdb/test/sql/cte/lazy_cte_bind.test
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# name: test/sql/cte/lazy_cte_bind.test
|
||||
# description: Test that CTE binding is lazy
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
query I
|
||||
with cte as (select * from read_parquet('does/not/exist/file.parquet'))
|
||||
select 42
|
||||
----
|
||||
42
|
||||
39
external/duckdb/test/sql/cte/materialized/annotated_and_auto_materialized.test
vendored
Normal file
39
external/duckdb/test/sql/cte/materialized/annotated_and_auto_materialized.test
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
# name: test/sql/cte/materialized/annotated_and_auto_materialized.test
|
||||
# description: Issue 13850 - Binder error when manually materializing a CTE
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
create table batch (
|
||||
entity text,
|
||||
start_ts timestamp,
|
||||
duration interval
|
||||
);
|
||||
|
||||
statement ok
|
||||
create table active_events (
|
||||
entity text,
|
||||
start_ts timestamp,
|
||||
end_ts timestamp
|
||||
);
|
||||
|
||||
statement ok
|
||||
explain create table new_active_events as
|
||||
with
|
||||
new_events as materialized ( -- Does not make much sense in this example, but my original query was a union of a bunch of things
|
||||
select * from batch
|
||||
), combined_deduplicated_events as (
|
||||
select
|
||||
entity,
|
||||
min(start_ts) as start_ts,
|
||||
max(end_ts) as end_ts
|
||||
from
|
||||
active_events
|
||||
group by
|
||||
entity
|
||||
), all_events as (
|
||||
select * from combined_deduplicated_events
|
||||
)
|
||||
select
|
||||
*
|
||||
from
|
||||
new_events;
|
||||
407
external/duckdb/test/sql/cte/materialized/automatic_cte_materialization.test_slow
vendored
Normal file
407
external/duckdb/test/sql/cte/materialized/automatic_cte_materialization.test_slow
vendored
Normal file
@@ -0,0 +1,407 @@
|
||||
# name: test/sql/cte/materialized/automatic_cte_materialization.test_slow
|
||||
# description: Test that CTEs are automatically materialized
|
||||
# group: [materialized]
|
||||
|
||||
require tpch
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
PRAGMA explain_output='OPTIMIZED_ONLY'
|
||||
|
||||
statement ok
|
||||
SET disabled_optimizers TO 'common_subplan'
|
||||
|
||||
statement ok
|
||||
CALL dbgen(sf=0.01);
|
||||
|
||||
# TPC-H Q15
|
||||
query II
|
||||
EXPLAIN WITH revenue AS (
|
||||
SELECT
|
||||
l_suppkey AS supplier_no,
|
||||
sum(l_extendedprice * (1 - l_discount)) AS total_revenue
|
||||
FROM
|
||||
lineitem
|
||||
WHERE
|
||||
l_shipdate >= CAST('1996-01-01' AS date)
|
||||
AND l_shipdate < CAST('1996-04-01' AS date)
|
||||
GROUP BY
|
||||
supplier_no
|
||||
)
|
||||
SELECT
|
||||
s_suppkey,
|
||||
s_name,
|
||||
s_address,
|
||||
s_phone,
|
||||
total_revenue
|
||||
FROM
|
||||
supplier,
|
||||
revenue
|
||||
WHERE
|
||||
s_suppkey = supplier_no
|
||||
AND total_revenue = (
|
||||
SELECT
|
||||
max(total_revenue)
|
||||
FROM revenue)
|
||||
ORDER BY
|
||||
s_suppkey;
|
||||
----
|
||||
logical_opt <REGEX>:.*CTE_SCAN.*
|
||||
|
||||
query II
|
||||
EXPLAIN WITH revenue AS NOT MATERIALIZED (
|
||||
SELECT
|
||||
l_suppkey AS supplier_no,
|
||||
sum(l_extendedprice * (1 - l_discount)) AS total_revenue
|
||||
FROM
|
||||
lineitem
|
||||
WHERE
|
||||
l_shipdate >= CAST('1996-01-01' AS date)
|
||||
AND l_shipdate < CAST('1996-04-01' AS date)
|
||||
GROUP BY
|
||||
supplier_no
|
||||
)
|
||||
SELECT
|
||||
s_suppkey,
|
||||
s_name,
|
||||
s_address,
|
||||
s_phone,
|
||||
total_revenue
|
||||
FROM
|
||||
supplier,
|
||||
revenue
|
||||
WHERE
|
||||
s_suppkey = supplier_no
|
||||
AND total_revenue = (
|
||||
SELECT
|
||||
max(total_revenue)
|
||||
FROM revenue)
|
||||
ORDER BY
|
||||
s_suppkey;
|
||||
----
|
||||
logical_opt <!REGEX>:.*CTE_SCAN.*
|
||||
|
||||
# duplicate table name
|
||||
statement ok
|
||||
DROP TABLE customer
|
||||
|
||||
require tpcds
|
||||
|
||||
statement ok
|
||||
call dsdgen(sf=0.01)
|
||||
|
||||
# TPC-DS Q23
|
||||
query II
|
||||
EXPLAIN WITH frequent_ss_items AS
|
||||
(SELECT itemdesc,
|
||||
i_item_sk item_sk,
|
||||
d_date solddate,
|
||||
count(*) cnt
|
||||
FROM store_sales,
|
||||
date_dim,
|
||||
(SELECT SUBSTRING(i_item_desc, 1, 30) itemdesc,
|
||||
*
|
||||
FROM item) sq1
|
||||
WHERE ss_sold_date_sk = d_date_sk
|
||||
AND ss_item_sk = i_item_sk
|
||||
AND d_year IN (2000,
|
||||
2000+1,
|
||||
2000+2,
|
||||
2000+3)
|
||||
GROUP BY itemdesc,
|
||||
i_item_sk,
|
||||
d_date
|
||||
HAVING count(*) >4),
|
||||
max_store_sales AS
|
||||
(SELECT max(csales) tpcds_cmax
|
||||
FROM
|
||||
(SELECT c_customer_sk,
|
||||
sum(ss_quantity*ss_sales_price) csales
|
||||
FROM store_sales,
|
||||
customer,
|
||||
date_dim
|
||||
WHERE ss_customer_sk = c_customer_sk
|
||||
AND ss_sold_date_sk = d_date_sk
|
||||
AND d_year IN (2000,
|
||||
2000+1,
|
||||
2000+2,
|
||||
2000+3)
|
||||
GROUP BY c_customer_sk) sq2),
|
||||
best_ss_customer AS
|
||||
(SELECT c_customer_sk,
|
||||
sum(ss_quantity*ss_sales_price) ssales
|
||||
FROM store_sales,
|
||||
customer,
|
||||
max_store_sales
|
||||
WHERE ss_customer_sk = c_customer_sk
|
||||
GROUP BY c_customer_sk
|
||||
HAVING sum(ss_quantity*ss_sales_price) > (50/100.0) * max(tpcds_cmax))
|
||||
SELECT c_last_name,
|
||||
c_first_name,
|
||||
sales
|
||||
FROM
|
||||
(SELECT c_last_name,
|
||||
c_first_name,
|
||||
sum(cs_quantity*cs_list_price) sales
|
||||
FROM catalog_sales,
|
||||
customer,
|
||||
date_dim,
|
||||
frequent_ss_items,
|
||||
best_ss_customer
|
||||
WHERE d_year = 2000
|
||||
AND d_moy = 2
|
||||
AND cs_sold_date_sk = d_date_sk
|
||||
AND cs_item_sk = item_sk
|
||||
AND cs_bill_customer_sk = best_ss_customer.c_customer_sk
|
||||
AND cs_bill_customer_sk = customer.c_customer_sk
|
||||
GROUP BY c_last_name,
|
||||
c_first_name
|
||||
UNION ALL SELECT c_last_name,
|
||||
c_first_name,
|
||||
sum(ws_quantity*ws_list_price) sales
|
||||
FROM web_sales,
|
||||
customer,
|
||||
date_dim,
|
||||
frequent_ss_items,
|
||||
best_ss_customer
|
||||
WHERE d_year = 2000
|
||||
AND d_moy = 2
|
||||
AND ws_sold_date_sk = d_date_sk
|
||||
AND ws_item_sk = item_sk
|
||||
AND ws_bill_customer_sk = best_ss_customer.c_customer_sk
|
||||
AND ws_bill_customer_sk = customer.c_customer_sk
|
||||
GROUP BY c_last_name,
|
||||
c_first_name) sq3
|
||||
ORDER BY c_last_name NULLS FIRST,
|
||||
c_first_name NULLS FIRST,
|
||||
sales NULLS FIRST
|
||||
LIMIT 100;
|
||||
----
|
||||
logical_opt <REGEX>:.*CTE_SCAN.*
|
||||
|
||||
query II
|
||||
EXPLAIN WITH frequent_ss_items AS NOT MATERIALIZED
|
||||
(SELECT itemdesc,
|
||||
i_item_sk item_sk,
|
||||
d_date solddate,
|
||||
count(*) cnt
|
||||
FROM store_sales,
|
||||
date_dim,
|
||||
(SELECT SUBSTRING(i_item_desc, 1, 30) itemdesc,
|
||||
*
|
||||
FROM item) sq1
|
||||
WHERE ss_sold_date_sk = d_date_sk
|
||||
AND ss_item_sk = i_item_sk
|
||||
AND d_year IN (2000,
|
||||
2000+1,
|
||||
2000+2,
|
||||
2000+3)
|
||||
GROUP BY itemdesc,
|
||||
i_item_sk,
|
||||
d_date
|
||||
HAVING count(*) >4),
|
||||
max_store_sales AS NOT MATERIALIZED
|
||||
(SELECT max(csales) tpcds_cmax
|
||||
FROM
|
||||
(SELECT c_customer_sk,
|
||||
sum(ss_quantity*ss_sales_price) csales
|
||||
FROM store_sales,
|
||||
customer,
|
||||
date_dim
|
||||
WHERE ss_customer_sk = c_customer_sk
|
||||
AND ss_sold_date_sk = d_date_sk
|
||||
AND d_year IN (2000,
|
||||
2000+1,
|
||||
2000+2,
|
||||
2000+3)
|
||||
GROUP BY c_customer_sk) sq2),
|
||||
best_ss_customer AS NOT MATERIALIZED
|
||||
(SELECT c_customer_sk,
|
||||
sum(ss_quantity*ss_sales_price) ssales
|
||||
FROM store_sales,
|
||||
customer,
|
||||
max_store_sales
|
||||
WHERE ss_customer_sk = c_customer_sk
|
||||
GROUP BY c_customer_sk
|
||||
HAVING sum(ss_quantity*ss_sales_price) > (50/100.0) * max(tpcds_cmax))
|
||||
SELECT c_last_name,
|
||||
c_first_name,
|
||||
sales
|
||||
FROM
|
||||
(SELECT c_last_name,
|
||||
c_first_name,
|
||||
sum(cs_quantity*cs_list_price) sales
|
||||
FROM catalog_sales,
|
||||
customer,
|
||||
date_dim,
|
||||
frequent_ss_items,
|
||||
best_ss_customer
|
||||
WHERE d_year = 2000
|
||||
AND d_moy = 2
|
||||
AND cs_sold_date_sk = d_date_sk
|
||||
AND cs_item_sk = item_sk
|
||||
AND cs_bill_customer_sk = best_ss_customer.c_customer_sk
|
||||
AND cs_bill_customer_sk = customer.c_customer_sk
|
||||
GROUP BY c_last_name,
|
||||
c_first_name
|
||||
UNION ALL SELECT c_last_name,
|
||||
c_first_name,
|
||||
sum(ws_quantity*ws_list_price) sales
|
||||
FROM web_sales,
|
||||
customer,
|
||||
date_dim,
|
||||
frequent_ss_items,
|
||||
best_ss_customer
|
||||
WHERE d_year = 2000
|
||||
AND d_moy = 2
|
||||
AND ws_sold_date_sk = d_date_sk
|
||||
AND ws_item_sk = item_sk
|
||||
AND ws_bill_customer_sk = best_ss_customer.c_customer_sk
|
||||
AND ws_bill_customer_sk = customer.c_customer_sk
|
||||
GROUP BY c_last_name,
|
||||
c_first_name) sq3
|
||||
ORDER BY c_last_name NULLS FIRST,
|
||||
c_first_name NULLS FIRST,
|
||||
sales NULLS FIRST
|
||||
LIMIT 100;
|
||||
----
|
||||
logical_opt <!REGEX>:.*CTE_SCAN.*
|
||||
|
||||
# TPC-DS Q57
|
||||
query II
|
||||
EXPLAIN WITH v1 AS
|
||||
(SELECT i_category,
|
||||
i_brand,
|
||||
cc_name,
|
||||
d_year,
|
||||
d_moy,
|
||||
sum(cs_sales_price) sum_sales,
|
||||
avg(sum(cs_sales_price)) OVER (PARTITION BY i_category,
|
||||
i_brand,
|
||||
cc_name,
|
||||
d_year) avg_monthly_sales,
|
||||
rank() OVER (PARTITION BY i_category,
|
||||
i_brand,
|
||||
cc_name
|
||||
ORDER BY d_year,
|
||||
d_moy) rn
|
||||
FROM item,
|
||||
catalog_sales,
|
||||
date_dim,
|
||||
call_center
|
||||
WHERE cs_item_sk = i_item_sk
|
||||
AND cs_sold_date_sk = d_date_sk
|
||||
AND cc_call_center_sk= cs_call_center_sk
|
||||
AND (d_year = 1999
|
||||
OR (d_year = 1999-1
|
||||
AND d_moy =12)
|
||||
OR (d_year = 1999+1
|
||||
AND d_moy =1))
|
||||
GROUP BY i_category,
|
||||
i_brand,
|
||||
cc_name,
|
||||
d_year,
|
||||
d_moy),
|
||||
v2 AS
|
||||
(SELECT v1.i_category,
|
||||
v1.i_brand,
|
||||
v1.cc_name,
|
||||
v1.d_year,
|
||||
v1.d_moy,
|
||||
v1.avg_monthly_sales,
|
||||
v1.sum_sales,
|
||||
v1_lag.sum_sales psum,
|
||||
v1_lead.sum_sales nsum
|
||||
FROM v1,
|
||||
v1 v1_lag,
|
||||
v1 v1_lead
|
||||
WHERE v1.i_category = v1_lag.i_category
|
||||
AND v1.i_category = v1_lead.i_category
|
||||
AND v1.i_brand = v1_lag.i_brand
|
||||
AND v1.i_brand = v1_lead.i_brand
|
||||
AND v1. cc_name = v1_lag. cc_name
|
||||
AND v1. cc_name = v1_lead. cc_name
|
||||
AND v1.rn = v1_lag.rn + 1
|
||||
AND v1.rn = v1_lead.rn - 1)
|
||||
SELECT *
|
||||
FROM v2
|
||||
WHERE d_year = 1999
|
||||
AND avg_monthly_sales > 0
|
||||
AND CASE
|
||||
WHEN avg_monthly_sales > 0 THEN abs(sum_sales - avg_monthly_sales) / avg_monthly_sales
|
||||
ELSE NULL
|
||||
END > 0.1
|
||||
ORDER BY sum_sales - avg_monthly_sales NULLS FIRST, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
LIMIT 100;
|
||||
----
|
||||
logical_opt <REGEX>:.*CTE_SCAN.*
|
||||
|
||||
query II
|
||||
EXPLAIN WITH v1 AS NOT MATERIALIZED
|
||||
(SELECT i_category,
|
||||
i_brand,
|
||||
cc_name,
|
||||
d_year,
|
||||
d_moy,
|
||||
sum(cs_sales_price) sum_sales,
|
||||
avg(sum(cs_sales_price)) OVER (PARTITION BY i_category,
|
||||
i_brand,
|
||||
cc_name,
|
||||
d_year) avg_monthly_sales,
|
||||
rank() OVER (PARTITION BY i_category,
|
||||
i_brand,
|
||||
cc_name
|
||||
ORDER BY d_year,
|
||||
d_moy) rn
|
||||
FROM item,
|
||||
catalog_sales,
|
||||
date_dim,
|
||||
call_center
|
||||
WHERE cs_item_sk = i_item_sk
|
||||
AND cs_sold_date_sk = d_date_sk
|
||||
AND cc_call_center_sk= cs_call_center_sk
|
||||
AND (d_year = 1999
|
||||
OR (d_year = 1999-1
|
||||
AND d_moy =12)
|
||||
OR (d_year = 1999+1
|
||||
AND d_moy =1))
|
||||
GROUP BY i_category,
|
||||
i_brand,
|
||||
cc_name,
|
||||
d_year,
|
||||
d_moy),
|
||||
v2 AS
|
||||
(SELECT v1.i_category,
|
||||
v1.i_brand,
|
||||
v1.cc_name,
|
||||
v1.d_year,
|
||||
v1.d_moy,
|
||||
v1.avg_monthly_sales,
|
||||
v1.sum_sales,
|
||||
v1_lag.sum_sales psum,
|
||||
v1_lead.sum_sales nsum
|
||||
FROM v1,
|
||||
v1 v1_lag,
|
||||
v1 v1_lead
|
||||
WHERE v1.i_category = v1_lag.i_category
|
||||
AND v1.i_category = v1_lead.i_category
|
||||
AND v1.i_brand = v1_lag.i_brand
|
||||
AND v1.i_brand = v1_lead.i_brand
|
||||
AND v1. cc_name = v1_lag. cc_name
|
||||
AND v1. cc_name = v1_lead. cc_name
|
||||
AND v1.rn = v1_lag.rn + 1
|
||||
AND v1.rn = v1_lead.rn - 1)
|
||||
SELECT *
|
||||
FROM v2
|
||||
WHERE d_year = 1999
|
||||
AND avg_monthly_sales > 0
|
||||
AND CASE
|
||||
WHEN avg_monthly_sales > 0 THEN abs(sum_sales - avg_monthly_sales) / avg_monthly_sales
|
||||
ELSE NULL
|
||||
END > 0.1
|
||||
ORDER BY sum_sales - avg_monthly_sales NULLS FIRST, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
LIMIT 100;
|
||||
----
|
||||
logical_opt <!REGEX>:.*CTE_SCAN.*
|
||||
23
external/duckdb/test/sql/cte/materialized/cte_filter_pusher.test
vendored
Normal file
23
external/duckdb/test/sql/cte/materialized/cte_filter_pusher.test
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# name: test/sql/cte/materialized/cte_filter_pusher.test
|
||||
# description: Test that the cte_filter_pusher optimizer works
|
||||
# group: [materialized]
|
||||
|
||||
query I
|
||||
WITH
|
||||
a(x) AS MATERIALIZED (
|
||||
SELECT *
|
||||
FROM generate_series(1, 10)
|
||||
),
|
||||
b(x) AS MATERIALIZED (
|
||||
SELECT *
|
||||
FROM a
|
||||
WHERE x < 8
|
||||
)
|
||||
SELECT *
|
||||
FROM b
|
||||
WHERE x % 3 = 1
|
||||
ORDER BY x;
|
||||
----
|
||||
1
|
||||
4
|
||||
7
|
||||
111
external/duckdb/test/sql/cte/materialized/dml_materialized_cte.test
vendored
Normal file
111
external/duckdb/test/sql/cte/materialized/dml_materialized_cte.test
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
# name: test/sql/cte/materialized/dml_materialized_cte.test
|
||||
# description: Test DML statements with materialized Common Table Expressions (CTE)
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
require no_alternative_verify
|
||||
|
||||
statement ok
|
||||
create table a(i integer);
|
||||
|
||||
statement ok
|
||||
insert into a values (42);
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (VALUES (42))
|
||||
INSERT INTO a (SELECT * FROM t);
|
||||
----
|
||||
1
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (VALUES (42))
|
||||
DELETE FROM a WHERE a.i IN (SELECT * FROM t);
|
||||
----
|
||||
2
|
||||
|
||||
statement ok
|
||||
insert into a values (42);
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (VALUES (42))
|
||||
UPDATE a SET i = 0 WHERE a.i IN (SELECT * FROM t);
|
||||
----
|
||||
1
|
||||
|
||||
query I
|
||||
FROM a
|
||||
----
|
||||
0
|
||||
|
||||
statement ok
|
||||
insert into a values (2);
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (SELECT 1),
|
||||
u(x) AS MATERIALIZED (SELECT 2 UNION ALL SELECT * FROM t)
|
||||
DELETE FROM a WHERE a.i IN (SELECT * FROM u);
|
||||
----
|
||||
1
|
||||
|
||||
statement ok
|
||||
insert into a values (2);
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (SELECT 1),
|
||||
u(x) AS MATERIALIZED (SELECT 2 UNION ALL SELECT * FROM t)
|
||||
UPDATE a SET i = 99 WHERE a.i IN (SELECT * FROM u);
|
||||
----
|
||||
1
|
||||
|
||||
query I
|
||||
FROM a ORDER BY 1
|
||||
----
|
||||
0
|
||||
99
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (SELECT 1),
|
||||
u(x) AS MATERIALIZED (SELECT 2 UNION ALL SELECT * FROM t)
|
||||
INSERT INTO a (SELECT * FROM u);
|
||||
----
|
||||
2
|
||||
|
||||
query I
|
||||
FROM a ORDER BY 1
|
||||
----
|
||||
0
|
||||
1
|
||||
2
|
||||
99
|
||||
|
||||
statement ok
|
||||
insert into a values (42);
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (SELECT 1)
|
||||
DELETE FROM a WHERE i IN (WITH s(x) AS MATERIALIZED (SELECT x + 41 FROM t) SELECT * FROM t);
|
||||
----
|
||||
1
|
||||
|
||||
query I
|
||||
FROM a ORDER BY 1
|
||||
----
|
||||
0
|
||||
2
|
||||
42
|
||||
99
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (SELECT 1)
|
||||
DELETE FROM a WHERE i IN (WITH s(x) AS MATERIALIZED (SELECT x + 41 FROM t) SELECT * FROM s);
|
||||
----
|
||||
1
|
||||
|
||||
query I
|
||||
FROM a ORDER BY 1
|
||||
----
|
||||
0
|
||||
2
|
||||
99
|
||||
65
external/duckdb/test/sql/cte/materialized/game_of_life_materialized.test_slow
vendored
Normal file
65
external/duckdb/test/sql/cte/materialized/game_of_life_materialized.test_slow
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
# name: test/sql/cte/materialized/game_of_life_materialized.test_slow
|
||||
# description: Run conways game of life as a CTE (https://gist.github.com/janickr/58fab629ee3ea7e5638a)
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
create table series as select * from generate_series(-1,1) x(n);
|
||||
|
||||
# conway
|
||||
query III
|
||||
with recursive generation1(x,y) as materialized ( --the initial board setup
|
||||
select 2, 3
|
||||
union
|
||||
select 3, 3
|
||||
union
|
||||
select 4, 3
|
||||
),
|
||||
game(n, x, y) as materialized (
|
||||
select 1 AS n, x, y from generation1 -- generation 1 is initial board setup
|
||||
union all
|
||||
select n+1, new_x, new_y from -- generation n+1
|
||||
(
|
||||
select n, x+offset_x new_x, y+offset_y new_y, max(self) over (partition by n+1, x+offset_x, y+offset_y) cell_was_already_alive
|
||||
from game, (
|
||||
select x.n offset_x, y.n offset_y, case when x.n = 0 and y.n = 0 then 1 else 0 end self
|
||||
from series x(n), series y(n) --join 2 row generators to get 9 pairs
|
||||
) offsets_to_neighbours_and_self(offset_x, offset_y, self)
|
||||
where n < 100
|
||||
) all_impacts
|
||||
group by n+1, new_x, new_y, cell_was_already_alive -- from all impacts back to cells
|
||||
having (cell_was_already_alive=1 and count(*) < 5 and count(*) > 2) or count(*) = 3 --decide if cell is alive
|
||||
)
|
||||
select * from game where n=4 order by n, x, y; --select generation 4
|
||||
----
|
||||
4 3 2
|
||||
4 3 3
|
||||
4 3 4
|
||||
|
||||
query III
|
||||
with recursive generation1(x,y) as materialized ( --the initial board setup
|
||||
select 2, 3
|
||||
union
|
||||
select 3, 3
|
||||
union
|
||||
select 4, 3
|
||||
),
|
||||
game(n, x, y) as materialized (
|
||||
select 1 AS n, x, y from generation1 -- generation 1 is initial board setup
|
||||
union all
|
||||
select n+1, new_x, new_y from -- generation n+1
|
||||
(
|
||||
select n, x+offset_x new_x, y+offset_y new_y, max(self) over (partition by n+1, x+offset_x, y+offset_y) cell_was_already_alive
|
||||
from game, (
|
||||
select x.n offset_x, y.n offset_y, case when x.n = 0 and y.n = 0 then 1 else 0 end self
|
||||
from generate_series(-1,1) x(n), generate_series(-1,1) y(n) --join 2 row generators to get 9 pairs
|
||||
) offsets_to_neighbours_and_self(offset_x, offset_y, self)
|
||||
where n < 100
|
||||
) all_impacts
|
||||
group by n+1, new_x, new_y, cell_was_already_alive -- from all impacts back to cells
|
||||
having (cell_was_already_alive=1 and count(*) < 5 and count(*) > 2) or count(*) = 3 --decide if cell is alive
|
||||
)
|
||||
select * from game where n=4 order by n, x, y; --select generation 4
|
||||
----
|
||||
4 3 2
|
||||
4 3 3
|
||||
4 3 4
|
||||
18
external/duckdb/test/sql/cte/materialized/incorrect_recursive_cte_materialized.test
vendored
Normal file
18
external/duckdb/test/sql/cte/materialized/incorrect_recursive_cte_materialized.test
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# name: test/sql/cte/materialized/incorrect_recursive_cte_materialized.test
|
||||
# description: Incorrect recursive ctes
|
||||
# group: [materialized]
|
||||
|
||||
# recursive CTE without UNION is just a normal CTE
|
||||
query I
|
||||
WITH RECURSIVE cte AS MATERIALIZED (SELECT 42) SELECT * FROM cte;
|
||||
----
|
||||
42
|
||||
|
||||
# we only support recursive ctes with union or union all
|
||||
statement error
|
||||
with recursive t as MATERIALIZED (select 1 as x intersect select x+1 from t where x < 3) select * from t order by x
|
||||
----
|
||||
|
||||
statement error
|
||||
with recursive t as MATERIALIZED (select 1 as x except select x+1 from t where x < 3) select * from t order by x
|
||||
----
|
||||
31
external/duckdb/test/sql/cte/materialized/internal_3004.test
vendored
Normal file
31
external/duckdb/test/sql/cte/materialized/internal_3004.test
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# name: test/sql/cte/materialized/internal_3004.test
|
||||
# description: INTERNAL Error: Attempted to access index 1 within vector of size 1 -> harlequin internal code, CTE related
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
with
|
||||
system_types as (
|
||||
select distinct
|
||||
type_name as label,
|
||||
'type' as type_label,
|
||||
1000 as priority,
|
||||
null as context
|
||||
from duckdb_types()
|
||||
where database_name = 'system'
|
||||
),
|
||||
custom_types as (
|
||||
select distinct
|
||||
type_name as label,
|
||||
'type' as type_label,
|
||||
1000 as priority,
|
||||
schema_name as context
|
||||
from duckdb_types()
|
||||
where
|
||||
database_name not in ('system', 'temp')
|
||||
and type_name not in (select label from system_types)
|
||||
)
|
||||
select *
|
||||
from system_types
|
||||
union all
|
||||
select *
|
||||
from custom_types
|
||||
37
external/duckdb/test/sql/cte/materialized/materialized_cte_modifiers.test
vendored
Normal file
37
external/duckdb/test/sql/cte/materialized/materialized_cte_modifiers.test
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# name: test/sql/cte/materialized/materialized_cte_modifiers.test
|
||||
# description: TopN should still work with materialized CTE (internal issue 2569)
|
||||
# group: [materialized]
|
||||
|
||||
require tpcds
|
||||
|
||||
statement ok
|
||||
call dsdgen(sf=0)
|
||||
|
||||
# q01
|
||||
query II
|
||||
explain
|
||||
WITH customer_total_return AS
|
||||
(SELECT sr_customer_sk AS ctr_customer_sk,
|
||||
sr_store_sk AS ctr_store_sk,
|
||||
sum(sr_return_amt) AS ctr_total_return
|
||||
FROM store_returns,
|
||||
date_dim
|
||||
WHERE sr_returned_date_sk = d_date_sk
|
||||
AND d_year = 2000
|
||||
GROUP BY sr_customer_sk,
|
||||
sr_store_sk)
|
||||
SELECT c_customer_id
|
||||
FROM customer_total_return ctr1,
|
||||
store,
|
||||
customer
|
||||
WHERE ctr1.ctr_total_return >
|
||||
(SELECT avg(ctr_total_return)*1.2
|
||||
FROM customer_total_return ctr2
|
||||
WHERE ctr1.ctr_store_sk = ctr2.ctr_store_sk)
|
||||
AND s_store_sk = ctr1.ctr_store_sk
|
||||
AND s_state = 'TN'
|
||||
AND ctr1.ctr_customer_sk = c_customer_sk
|
||||
ORDER BY c_customer_id
|
||||
LIMIT 100;
|
||||
----
|
||||
physical_plan <REGEX>:.*TOP_N.*
|
||||
51
external/duckdb/test/sql/cte/materialized/materialized_cte_prepared.test
vendored
Normal file
51
external/duckdb/test/sql/cte/materialized/materialized_cte_prepared.test
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# name: test/sql/cte/materialized/materialized_cte_prepared.test
|
||||
# description: Test DML statements with materialized Common Table Expressions (CTE)
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
require no_alternative_verify
|
||||
|
||||
statement ok
|
||||
create table a(i integer);
|
||||
|
||||
statement ok
|
||||
insert into a values (1), (2), (3), (NULL), (42), (84);
|
||||
|
||||
# prepare in materialized cte
|
||||
statement ok
|
||||
PREPARE v1 AS WITH t(x) AS MATERIALIZED (VALUES ($1))
|
||||
DELETE FROM a WHERE i IN (FROM t);
|
||||
|
||||
query I
|
||||
EXECUTE v1(42)
|
||||
----
|
||||
1
|
||||
|
||||
query I
|
||||
FROM a ORDER BY 1
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
84
|
||||
NULL
|
||||
|
||||
# prepare in both materialized cte and delete
|
||||
statement ok
|
||||
PREPARE v2 AS WITH t(x) AS MATERIALIZED (VALUES ($1))
|
||||
DELETE FROM a WHERE (i + $2) IN (FROM t);
|
||||
|
||||
query I
|
||||
EXECUTE v2(5, 2)
|
||||
----
|
||||
1
|
||||
|
||||
query I
|
||||
FROM a ORDER BY 1
|
||||
----
|
||||
1
|
||||
2
|
||||
84
|
||||
NULL
|
||||
76
external/duckdb/test/sql/cte/materialized/recursive_array_slice_materialized.test
vendored
Normal file
76
external/duckdb/test/sql/cte/materialized/recursive_array_slice_materialized.test
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# name: test/sql/cte/materialized/recursive_array_slice_materialized.test
|
||||
# description: Issue #3005: array_slice prevents row values to be used more than once
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE p(loc int8);
|
||||
|
||||
statement ok
|
||||
INSERT INTO p VALUES (1);
|
||||
|
||||
query II
|
||||
WITH RECURSIVE t(y, arr) AS MATERIALIZED
|
||||
(
|
||||
SELECT 1, array[1,2,3,4,5,6]
|
||||
UNION ALL
|
||||
SELECT y+1, arr[:loc]
|
||||
FROM t, p
|
||||
WHERE y < 10
|
||||
) SELECT * FROM t;
|
||||
----
|
||||
1 [1, 2, 3, 4, 5, 6]
|
||||
2 [1]
|
||||
3 [1]
|
||||
4 [1]
|
||||
5 [1]
|
||||
6 [1]
|
||||
7 [1]
|
||||
8 [1]
|
||||
9 [1]
|
||||
10 [1]
|
||||
|
||||
query II
|
||||
WITH RECURSIVE t(y, arr) AS MATERIALIZED
|
||||
(
|
||||
SELECT 1, array[1,2,3,4,5,6]
|
||||
UNION ALL
|
||||
SELECT y+1, arr
|
||||
FROM t, p
|
||||
WHERE y < 10
|
||||
AND y = loc
|
||||
) SELECT * FROM t;
|
||||
----
|
||||
1 [1, 2, 3, 4, 5, 6]
|
||||
2 [1, 2, 3, 4, 5, 6]
|
||||
|
||||
query II
|
||||
WITH RECURSIVE t(y, arr) AS MATERIALIZED
|
||||
(
|
||||
SELECT 1, array[1,2,3,4,5,6]
|
||||
UNION ALL
|
||||
SELECT y+1, arr[:loc]
|
||||
FROM t, p
|
||||
WHERE y < 10
|
||||
AND y = loc
|
||||
) SELECT * FROM t;
|
||||
----
|
||||
1 [1, 2, 3, 4, 5, 6]
|
||||
2 [1]
|
||||
|
||||
query I
|
||||
WITH RECURSIVE t(arr) AS MATERIALIZED
|
||||
(
|
||||
SELECT array[1,2,3,4,5,6]
|
||||
UNION ALL
|
||||
SELECT arr[arr[1]+1:6]
|
||||
FROM t
|
||||
WHERE arr[1] < 6
|
||||
) SELECT * FROM t;
|
||||
----
|
||||
[1, 2, 3, 4, 5, 6]
|
||||
[2, 3, 4, 5, 6]
|
||||
[4, 5, 6]
|
||||
[]
|
||||
133
external/duckdb/test/sql/cte/materialized/recursive_cte_complex_pipelines.test
vendored
Normal file
133
external/duckdb/test/sql/cte/materialized/recursive_cte_complex_pipelines.test
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
# name: test/sql/cte/materialized/recursive_cte_complex_pipelines.test
|
||||
# description: Recursive CTEs with complex pipelines
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# recursive CTE with various cross products
|
||||
query I
|
||||
WITH RECURSIVE t AS MATERIALIZED
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT t1.x + t2.x + t3.x AS x
|
||||
FROM t t1, t t2, t t3
|
||||
WHERE t1.x < 100
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1;
|
||||
----
|
||||
1
|
||||
3
|
||||
9
|
||||
27
|
||||
81
|
||||
243
|
||||
|
||||
# what if we have different types?
|
||||
query I
|
||||
WITH RECURSIVE t AS MATERIALIZED
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT (t1.x + t2.x + t3.x)::HUGEINT AS x
|
||||
FROM t t1, t t2, t t3
|
||||
WHERE t1.x < 100
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1;
|
||||
----
|
||||
1
|
||||
3
|
||||
9
|
||||
27
|
||||
81
|
||||
243
|
||||
|
||||
statement ok
|
||||
CREATE TABLE a AS SELECT * FROM range(100) t1(i)
|
||||
|
||||
# recursive CTE with aggregates
|
||||
query I
|
||||
WITH RECURSIVE t AS MATERIALIZED
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT SUM(x) AS x
|
||||
FROM t, a
|
||||
WHERE x < 1000000
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
100
|
||||
10000
|
||||
1000000
|
||||
NULL
|
||||
|
||||
# the same but with a hash join
|
||||
query I
|
||||
WITH RECURSIVE t AS MATERIALIZED
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT SUM(x) AS x
|
||||
FROM t, a
|
||||
WHERE x < 1000000 AND t.x=a.i
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
|
||||
# nested aggregates
|
||||
query I
|
||||
WITH RECURSIVE t AS MATERIALIZED
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT SUM(x)
|
||||
FROM
|
||||
(SELECT SUM(x) FROM t) t1(x), a
|
||||
WHERE x < 1000
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
100
|
||||
10000
|
||||
NULL
|
||||
|
||||
# non-correlated subqueries
|
||||
query I
|
||||
WITH RECURSIVE t AS MATERIALIZED
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT (SELECT x + 1 FROM t) AS x
|
||||
FROM t
|
||||
WHERE x < 5
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
|
||||
# correlated subqueries
|
||||
query I
|
||||
WITH RECURSIVE t AS MATERIALIZED
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT (SELECT t.x+t2.x FROM t t2 LIMIT 1) AS x
|
||||
FROM t
|
||||
WHERE x < 10
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
2
|
||||
4
|
||||
8
|
||||
16
|
||||
@@ -0,0 +1,33 @@
|
||||
# name: test/sql/cte/materialized/recursive_cte_correlated_subquery_materialized.test_slow
|
||||
# description: Issue #2713: reports struct_extract error when run a sql
|
||||
# group: [materialized]
|
||||
|
||||
query I
|
||||
WITH RECURSIVE
|
||||
input(sud) AS MATERIALIZED (
|
||||
VALUES('53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79')
|
||||
),
|
||||
digits(z, lp) AS MATERIALIZED (
|
||||
SELECT CAST(lp+1 AS TEXT), lp::int+1 FROM generate_series(0,8,1) t(lp)
|
||||
),
|
||||
x(s, ind) AS MATERIALIZED (
|
||||
SELECT sud, instr(sud, '.') FROM input
|
||||
UNION ALL
|
||||
SELECT
|
||||
substr(s, 1, ind::int-1) || z || substr(s, ind::int+1),
|
||||
instr(substr(s, 1, ind::int-1) || z || substr(s, ind::int+1), '.' )
|
||||
FROM x, digits AS z
|
||||
WHERE ind::int>0
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM digits AS lp
|
||||
WHERE z.z = substr(s, ((ind::int-1)//9)*9 + lp, 1)
|
||||
OR z.z = substr(s, ((ind::int-1)%9) + (lp-1)*9 + 1, 1)
|
||||
OR z.z = substr(s, (((ind::int-1)//3) % 3) * 3
|
||||
+ ((ind::int-1)//27) * 27 + lp
|
||||
+ ((lp-1) // 3) * 6, 1)
|
||||
)
|
||||
)
|
||||
SELECT s FROM x WHERE ind::int=0;
|
||||
----
|
||||
534678912672195348198342567859761423426853791713924856961537284287419635345286179
|
||||
32
external/duckdb/test/sql/cte/materialized/recursive_cte_error_materialized.test
vendored
Normal file
32
external/duckdb/test/sql/cte/materialized/recursive_cte_error_materialized.test
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# name: test/sql/cte/materialized/recursive_cte_error_materialized.test
|
||||
# description: Recursive CTEs with an error thrown in the pipelines
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tag(id int, name string, subclassof int);
|
||||
|
||||
statement ok
|
||||
INSERT INTO tag VALUES
|
||||
(7, 'Music', 9),
|
||||
(8, 'Movies', 9),
|
||||
(9, 'Art', NULL)
|
||||
;
|
||||
|
||||
statement error
|
||||
WITH RECURSIVE tag_hierarchy(id, source, path, target) AS materialized (
|
||||
SELECT id, name, name AS path, NULL AS target -- this should be '' for correct behaviour
|
||||
FROM tag
|
||||
WHERE subclassof IS NULL
|
||||
UNION ALL
|
||||
SELECT tag.id, tag.name, tag_hierarchy.path || ' <- ' || tag.name, tag.name AS target
|
||||
FROM tag, tag_hierarchy
|
||||
WHERE tag.subclassof = tag_hierarchy.id
|
||||
)
|
||||
SELECT source, path, target
|
||||
FROM tag_hierarchy
|
||||
;
|
||||
----
|
||||
<REGEX>:.*Conversion Error: Could not convert string.*
|
||||
120
external/duckdb/test/sql/cte/materialized/recursive_hang_2745_materialized.test
vendored
Normal file
120
external/duckdb/test/sql/cte/materialized/recursive_hang_2745_materialized.test
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
# name: test/sql/cte/materialized/recursive_hang_2745_materialized.test
|
||||
# description: Issue #2745: sql with RECURSIVE keyword but does not RECURSIVE hang
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
query III
|
||||
with RECURSIVE parents_tab (id , value , parent )
|
||||
as MATERIALIZED (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents_tab2(id , value , parent )
|
||||
as MATERIALIZED (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents as MATERIALIZED (
|
||||
select * from parents_tab
|
||||
union all
|
||||
select id, value+2, parent from parents_tab2
|
||||
)
|
||||
select * from parents ORDER BY id, value, parent;
|
||||
----
|
||||
1 1 2
|
||||
1 3 2
|
||||
2 2 4
|
||||
2 4 4
|
||||
3 1 4
|
||||
3 3 4
|
||||
4 2 -1
|
||||
4 4 -1
|
||||
5 1 2
|
||||
5 3 2
|
||||
6 2 7
|
||||
6 4 7
|
||||
7 1 -1
|
||||
7 3 -1
|
||||
|
||||
query III
|
||||
with RECURSIVE parents_tab (id , value , parent )
|
||||
as MATERIALIZED (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents_tab2(id , value , parent )
|
||||
as MATERIALIZED (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
)
|
||||
select * from parents_tab
|
||||
union all
|
||||
select id, value+2, parent from parents_tab2 ORDER BY id, value, parent;
|
||||
----
|
||||
1 1 2
|
||||
1 3 2
|
||||
2 2 4
|
||||
2 4 4
|
||||
3 1 4
|
||||
3 3 4
|
||||
4 2 -1
|
||||
4 4 -1
|
||||
5 1 2
|
||||
5 3 2
|
||||
6 2 7
|
||||
6 4 7
|
||||
7 1 -1
|
||||
7 3 -1
|
||||
|
||||
query III
|
||||
with parents_tab (id , value , parent )
|
||||
as MATERIALIZED (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents_tab2(id , value , parent )
|
||||
as MATERIALIZED (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents as MATERIALIZED (
|
||||
select * from parents_tab
|
||||
union all
|
||||
select id, value+2, parent from parents_tab2
|
||||
)
|
||||
select * from parents ORDER BY id, value, parent;
|
||||
----
|
||||
1 1 2
|
||||
1 3 2
|
||||
2 2 4
|
||||
2 4 4
|
||||
3 1 4
|
||||
3 3 4
|
||||
4 2 -1
|
||||
4 4 -1
|
||||
5 1 2
|
||||
5 3 2
|
||||
6 2 7
|
||||
6 4 7
|
||||
7 1 -1
|
||||
7 3 -1
|
||||
|
||||
statement ok
|
||||
create view vparents as
|
||||
with RECURSIVE parents_tab (id , value , parent )
|
||||
as MATERIALIZED (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents_tab2 (id , value , parent )
|
||||
as MATERIALIZED (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
)
|
||||
select * from parents_tab
|
||||
union all
|
||||
select id, value+2, parent from parents_tab2;
|
||||
|
||||
query III
|
||||
select * from vparents ORDER BY id, value, parent;
|
||||
----
|
||||
1 1 2
|
||||
1 3 2
|
||||
2 2 4
|
||||
2 4 4
|
||||
3 1 4
|
||||
3 3 4
|
||||
4 2 -1
|
||||
4 4 -1
|
||||
5 1 2
|
||||
5 3 2
|
||||
6 2 7
|
||||
6 4 7
|
||||
7 1 -1
|
||||
7 3 -1
|
||||
11
external/duckdb/test/sql/cte/materialized/test_bug_922_materialized.test
vendored
Normal file
11
external/duckdb/test/sql/cte/materialized/test_bug_922_materialized.test
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# name: test/sql/cte/materialized/test_bug_922_materialized.test
|
||||
# description: Test for a crash reported in issue #922
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
query I
|
||||
WITH my_list(value) AS MATERIALIZED (VALUES (1), (2), (3))
|
||||
SELECT * FROM my_list LIMIT 0 OFFSET 1
|
||||
----
|
||||
265
external/duckdb/test/sql/cte/materialized/test_correlated_recursive_cte_materialized.test
vendored
Normal file
265
external/duckdb/test/sql/cte/materialized/test_correlated_recursive_cte_materialized.test
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
# name: test/sql/cte/materialized/test_correlated_recursive_cte_materialized.test
|
||||
# description: Test Materialized Correlated Recursive Common Table Expressions (CTE)
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# Correlation in the initialization query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS MATERIALIZED (
|
||||
SELECT _.x
|
||||
UNION ALL
|
||||
SELECT y + 1
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 2
|
||||
2 3
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Correlation in the recursive query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS MATERIALIZED (
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT y + _.x
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 1
|
||||
2 3
|
||||
3 1
|
||||
3 4
|
||||
4 1
|
||||
4 5
|
||||
|
||||
# Correlation in the initialization and recursive query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS MATERIALIZED (
|
||||
SELECT _.x
|
||||
UNION ALL
|
||||
SELECT y + _.x
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 2
|
||||
2 4
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Correlation with multiple recursive anchors
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS MATERIALIZED (
|
||||
SELECT _.x
|
||||
UNION ALL
|
||||
SELECT t1.y + t2.y + _.x
|
||||
FROM t AS t1, t AS t2
|
||||
WHERE t1.y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 3
|
||||
2 2
|
||||
2 6
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Test correlation in SELECT clause
|
||||
query III rowsort
|
||||
SELECT x, y, (WITH RECURSIVE t(z) AS MATERIALIZED (
|
||||
SELECT x + y
|
||||
UNION ALL
|
||||
SELECT z + 1
|
||||
FROM t
|
||||
WHERE z < 3
|
||||
) SELECT sum(z) FROM t) AS z
|
||||
FROM generate_series(1,2) AS _(x), generate_series(1,2) AS __(y) order by all;
|
||||
----
|
||||
1 1 5
|
||||
1 2 3
|
||||
2 1 3
|
||||
2 2 4
|
||||
|
||||
|
||||
# Complex nested recursive query
|
||||
query III rowsort
|
||||
SELECT x, y, (WITH RECURSIVE t(z) AS MATERIALIZED (
|
||||
SELECT x + y
|
||||
UNION ALL
|
||||
SELECT z + 1
|
||||
FROM (WITH RECURSIVE g(a) AS MATERIALIZED (
|
||||
SELECT t.z
|
||||
FROM t
|
||||
UNION ALL
|
||||
SELECT g.a + (x + y) / 2
|
||||
FROM g
|
||||
WHERE g.a < 3)
|
||||
SELECT * FROM g) AS t(z)
|
||||
WHERE z < 5
|
||||
) SELECT sum(z) FROM t) AS z
|
||||
FROM generate_series(1,2) AS _(x), generate_series(1,2) AS __(y) order by all;
|
||||
----
|
||||
1 1 23
|
||||
1 2 12
|
||||
2 1 12
|
||||
2 2 9
|
||||
|
||||
# UNION semantics
|
||||
|
||||
# Correlation in the initialization query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS MATERIALIZED (
|
||||
SELECT _.x
|
||||
UNION
|
||||
SELECT y + 1
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 2
|
||||
2 3
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Correlation in the recursive query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS MATERIALIZED (
|
||||
SELECT 1
|
||||
UNION
|
||||
SELECT y + _.x
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 1
|
||||
2 3
|
||||
3 1
|
||||
3 4
|
||||
4 1
|
||||
4 5
|
||||
|
||||
# Correlation in the initialization and recursive query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS MATERIALIZED (
|
||||
SELECT _.x
|
||||
UNION
|
||||
SELECT y + _.x
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 2
|
||||
2 4
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Correlation with multiple recursive anchors
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS MATERIALIZED (
|
||||
SELECT _.x
|
||||
UNION
|
||||
SELECT t1.y + t2.y + _.x
|
||||
FROM t AS t1, t AS t2
|
||||
WHERE t1.y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 3
|
||||
2 2
|
||||
2 6
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Test correlation in SELECT clause
|
||||
query III rowsort
|
||||
SELECT x, y, (WITH RECURSIVE t(z) AS MATERIALIZED (
|
||||
SELECT x + y
|
||||
UNION
|
||||
SELECT z + 1
|
||||
FROM t
|
||||
WHERE z < 3
|
||||
) SELECT sum(z) FROM t) AS z
|
||||
FROM generate_series(1,2) AS _(x), generate_series(1,2) AS __(y) order by all;
|
||||
----
|
||||
1 1 5
|
||||
1 2 3
|
||||
2 1 3
|
||||
2 2 4
|
||||
|
||||
# Complex nested recursive query
|
||||
query III rowsort
|
||||
SELECT x, y, (WITH RECURSIVE t(z) AS MATERIALIZED (
|
||||
SELECT x + y
|
||||
UNION
|
||||
SELECT z + 1
|
||||
FROM (WITH RECURSIVE g(a) AS MATERIALIZED (
|
||||
SELECT t.z
|
||||
FROM t
|
||||
UNION
|
||||
SELECT g.a + (x + y) / 2
|
||||
FROM g
|
||||
WHERE g.a < 3)
|
||||
SELECT * FROM g) AS t(z)
|
||||
WHERE z < 5
|
||||
) SELECT sum(z) FROM t) AS z
|
||||
FROM generate_series(1,2) AS _(x), generate_series(1,2) AS __(y) order by all;
|
||||
----
|
||||
1 1 14
|
||||
1 2 12
|
||||
2 1 12
|
||||
2 2 9
|
||||
70
external/duckdb/test/sql/cte/materialized/test_cte_in_cte_materialized.test
vendored
Normal file
70
external/duckdb/test/sql/cte/materialized/test_cte_in_cte_materialized.test
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
# name: test/sql/cte/materialized/test_cte_in_cte_materialized.test
|
||||
# description: Test Nested Common Table Expressions (CTE)
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
create table a(i integer);
|
||||
|
||||
statement ok
|
||||
insert into a values (42);
|
||||
|
||||
query I
|
||||
with cte1 as MATERIALIZED (Select i as j from a) select * from cte1;
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
with cte1 as MATERIALIZED (with b as MATERIALIZED (Select i as j from a) Select j from b) select x from cte1 t1(x);
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
with cte1(xxx) as MATERIALIZED (with ncte(yyy) as MATERIALIZED (Select i as j from a) Select yyy from ncte) select xxx from cte1;
|
||||
----
|
||||
42
|
||||
|
||||
query II
|
||||
with cte1 as MATERIALIZED (with b as MATERIALIZED (Select i as j from a) select j from b), cte2 as MATERIALIZED (with c as MATERIALIZED (select ref.j+1 as k from cte1 as ref) select k from c) select * from cte1 , cte2;
|
||||
----
|
||||
42 43
|
||||
|
||||
# duplicate CTE alias
|
||||
statement error
|
||||
with cte1 as MATERIALIZED (select 42), cte1 as MATERIALIZED (select 42) select * FROM cte1;
|
||||
----
|
||||
<REGEX>:.*Parser Error: Duplicate CTE name.*
|
||||
|
||||
# refer to CTE in subquery tableref
|
||||
query I
|
||||
with cte1 as MATERIALIZED (Select i as j from a) select * from (with cte2 as MATERIALIZED (select max(j) as j from cte1) select * from cte2) f
|
||||
----
|
||||
42
|
||||
|
||||
# refer to CTE in subquery expression
|
||||
query I
|
||||
with cte1 as MATERIALIZED (Select i as j from a) select * from cte1 where j = (with cte2 as MATERIALIZED (select max(j) as j from cte1) select j from cte2);
|
||||
----
|
||||
42
|
||||
|
||||
require no_alternative_verify
|
||||
|
||||
# same name, both get materialized with ALTERNATIVE_VERIFY, so we need 'no_alternative_verify'
|
||||
query I
|
||||
with cte as materialized (Select i as j from a) select * from cte where j = (with cte as (select max(j) as j from cte) select j from cte);
|
||||
----
|
||||
42
|
||||
|
||||
# refer to same-named CTE in a subquery expression
|
||||
query I
|
||||
with cte as MATERIALIZED (Select i as j from a) select * from cte where j = (with cte as MATERIALIZED (select max(j) as j from cte) select j from cte);
|
||||
----
|
||||
42
|
||||
|
||||
# self-refer to non-existent cte
|
||||
statement error
|
||||
with cte as MATERIALIZED (select * from cte) select * from cte
|
||||
----
|
||||
<REGEX>:.*Binder Error.*Circular reference to CTE.*
|
||||
154
external/duckdb/test/sql/cte/materialized/test_cte_materialized.test
vendored
Normal file
154
external/duckdb/test/sql/cte/materialized/test_cte_materialized.test
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
# name: test/sql/cte/materialized/test_cte_materialized.test
|
||||
# description: Test Common Table Expressions (CTE)
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
create table a(i integer);
|
||||
|
||||
statement ok
|
||||
insert into a values (42);
|
||||
|
||||
query I
|
||||
with cte1 as MATERIALIZED (Select i as j from a) select * from cte1;
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
with cte1 as MATERIALIZED (Select i as j from a) select x from cte1 t1(x);
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
with cte1(xxx) as MATERIALIZED (Select i as j from a) select xxx from cte1;
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
with cte1(xxx) as MATERIALIZED (Select i as j from a) select x from cte1 t1(x);
|
||||
----
|
||||
42
|
||||
|
||||
query II
|
||||
with cte1 as MATERIALIZED (Select i as j from a), cte2 as MATERIALIZED (select ref.j as k from cte1 as ref), cte3 as MATERIALIZED (select ref2.j+1 as i from cte1 as ref2) select * from cte2 , cte3;
|
||||
----
|
||||
42 43
|
||||
|
||||
query I
|
||||
with cte1 as MATERIALIZED (select i as j from a), cte2 as MATERIALIZED (select ref.j as k from cte1 as ref), cte3 as MATERIALIZED (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 MATERIALIZED (select 42), cte1 as MATERIALIZED (select 42) select * FROM cte1;
|
||||
----
|
||||
|
||||
# reference to CTE before its actually defined
|
||||
statement error
|
||||
with cte3 as MATERIALIZED (select ref2.j as i from cte1 as ref2), cte1 as MATERIALIZED (Select i as j from a), cte2 as MATERIALIZED (select ref.j+1 as k from cte1 as ref) select * from cte2 union all select * FROM cte3;
|
||||
----
|
||||
|
||||
# multiple uses of same CTE
|
||||
query II
|
||||
with cte1 as MATERIALIZED (Select i as j from a) select * from cte1 cte11, cte1 cte12;
|
||||
----
|
||||
42 42
|
||||
|
||||
# refer to CTE in subquery
|
||||
query I
|
||||
with cte1 as MATERIALIZED (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 MATERIALIZED (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 MATERIALIZED (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 MATERIALIZED (SELECT * FROM va) SELECT * FROM cte;
|
||||
----
|
||||
42
|
||||
|
||||
# multiple ctes in a view definition
|
||||
statement ok
|
||||
create view vb AS (with cte1 as MATERIALIZED (Select i as j from a), cte2 as MATERIALIZED (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 MATERIALIZED (SELECT 42) SELECT * FROM cte);
|
||||
----
|
||||
1
|
||||
42
|
||||
|
||||
# cte in recursive cte
|
||||
query I
|
||||
WITH RECURSIVE cte(d) AS MATERIALIZED (
|
||||
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 MATERIALIZED (
|
||||
select 1
|
||||
)
|
||||
select
|
||||
a as alias1,
|
||||
alias1 as alias2
|
||||
from cte
|
||||
where alias2 > 0;
|
||||
----
|
||||
1 1
|
||||
|
||||
# test materialized CTE in recursive CTE
|
||||
query II
|
||||
WITH RECURSIVE t(x,v) AS (
|
||||
SELECT 1, ARRAY[] :: int[]
|
||||
UNION ALL
|
||||
(WITH u(x) AS MATERIALIZED (SELECT 1)
|
||||
SELECT f.x, (SELECT array_agg(x) FROM u)
|
||||
FROM t, LATERAL (SELECT t.x + 1) AS f(x)
|
||||
WHERE t.x < 5
|
||||
)
|
||||
) SELECT * FROM t ORDER BY x;
|
||||
----
|
||||
1 []
|
||||
2 [1]
|
||||
3 [1]
|
||||
4 [1]
|
||||
5 [1]
|
||||
|
||||
query I
|
||||
SELECT * FROM (WITH t(x) AS MATERIALIZED (SELECT * FROM generate_series(1,10) LIMIT 75%) SELECT * FROM t LIMIT 80%) AS _(x) ORDER BY x LIMIT 50%;
|
||||
----
|
||||
1
|
||||
2
|
||||
17
external/duckdb/test/sql/cte/materialized/test_cte_overflow_materialized.test
vendored
Normal file
17
external/duckdb/test/sql/cte/materialized/test_cte_overflow_materialized.test
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# name: test/sql/cte/materialized/test_cte_overflow_materialized.test
|
||||
# description: Ensure no stack overflow for CTE names that match existing tables
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
create table a (id integer)
|
||||
|
||||
statement ok
|
||||
insert into a values (1729)
|
||||
|
||||
statement ok
|
||||
create view va as (with v as MATERIALIZED (select * from a) select * from v)
|
||||
|
||||
query I
|
||||
with a as MATERIALIZED (select * from va) select * from a
|
||||
----
|
||||
1729
|
||||
28
external/duckdb/test/sql/cte/materialized/test_issue_10260.test
vendored
Normal file
28
external/duckdb/test/sql/cte/materialized/test_issue_10260.test
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# name: test/sql/cte/materialized/test_issue_10260.test
|
||||
# description: Issue #10260: MATERIALIZED causes Binder Error: table has duplicate column name
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE T0(C1 INT);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE T1(C1 INT);
|
||||
|
||||
statement ok
|
||||
INSERT INTO T0(C1) VALUES (1);
|
||||
|
||||
statement ok
|
||||
INSERT INTO T1(C1) VALUES (1);
|
||||
|
||||
query I
|
||||
WITH CTE AS MATERIALIZED (
|
||||
SELECT A1, * FROM T0
|
||||
LEFT JOIN (
|
||||
SELECT C1 AS A1 FROM T1
|
||||
) ON T0.C1 = A1
|
||||
) SELECT A1 FROM CTE;
|
||||
----
|
||||
1
|
||||
86
external/duckdb/test/sql/cte/materialized/test_materialized_cte.test
vendored
Normal file
86
external/duckdb/test/sql/cte/materialized/test_materialized_cte.test
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
# name: test/sql/cte/materialized/test_materialized_cte.test
|
||||
# description: Test Materialized Common Table Expressions (CTE)
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (SELECT 1) SELECT * FROM t;
|
||||
----
|
||||
1
|
||||
|
||||
query II
|
||||
WITH t(x) AS MATERIALIZED (SELECT t FROM generate_series(1,3) AS _(t)) SELECT t1.x,1 as y FROM t AS t1 ORDER BY x;
|
||||
----
|
||||
1 1
|
||||
2 1
|
||||
3 1
|
||||
|
||||
query II
|
||||
WITH t(x) AS MATERIALIZED (SELECT t FROM generate_series(1,3) AS _(t)) SELECT t1.x, t1.x FROM t AS t1 ORDER BY x;
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
|
||||
query II
|
||||
WITH t(x) AS MATERIALIZED (SELECT t FROM generate_series(1,3) AS _(t)) SELECT t1.x, t2.x FROM t AS t1, t AS t2 ORDER BY t1.x, t2.x;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 1
|
||||
2 2
|
||||
2 3
|
||||
3 1
|
||||
3 2
|
||||
3 3
|
||||
|
||||
query II
|
||||
WITH t(x) AS MATERIALIZED (SELECT 1),
|
||||
u(x) AS MATERIALIZED (SELECT 2)
|
||||
SELECT *
|
||||
FROM u FULL OUTER JOIN t ON TRUE;
|
||||
----
|
||||
2 1
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (SELECT x FROM generate_series(1,10) AS _(x) limit 4) SELECT DISTINCT x FROM t order by x desc;
|
||||
----
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (SELECT x FROM generate_series(1,10) AS _(x) limit 4) SELECT DISTINCT x FROM t order by x desc LIMIT 2;
|
||||
----
|
||||
4
|
||||
3
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (
|
||||
WITH u(x) AS MATERIALIZED (
|
||||
SELECT 42
|
||||
) SELECT * FROM u
|
||||
) SELECT * FROM t;
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
WITH t(x) AS MATERIALIZED (SELECT 1),
|
||||
u(x) AS MATERIALIZED (SELECT x+1 FROM t)
|
||||
TABLE u UNION ALL TABLE t;
|
||||
----
|
||||
2
|
||||
1
|
||||
|
||||
statement error
|
||||
WITH t0(x) AS MATERIALIZED (
|
||||
SELECT x FROM t1
|
||||
), t1(x) AS MATERIALIZED (
|
||||
SELECT 1
|
||||
)
|
||||
SELECT * FROM t0;
|
||||
----
|
||||
59
external/duckdb/test/sql/cte/materialized/test_nested_recursive_cte_materialized.test
vendored
Normal file
59
external/duckdb/test/sql/cte/materialized/test_nested_recursive_cte_materialized.test
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
# name: test/sql/cte/materialized/test_nested_recursive_cte_materialized.test
|
||||
# description: Test Nested Recursive Common Table Expressions (CTE)
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
query I
|
||||
WITH RECURSIVE t(x) AS MATERIALIZED
|
||||
(
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT x+1
|
||||
FROM t
|
||||
WHERE x < 4
|
||||
),
|
||||
u(x) AS MATERIALIZED
|
||||
(
|
||||
SELECT *
|
||||
FROM t
|
||||
UNION ALL
|
||||
SELECT u.x * 2 + t.x
|
||||
FROM u, t
|
||||
WHERE u.x < 32
|
||||
)
|
||||
SELECT *
|
||||
FROM u
|
||||
ORDER BY x
|
||||
LIMIT 5;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
3
|
||||
4
|
||||
|
||||
query III
|
||||
WITH RECURSIVE collatz(x, t, steps) AS MATERIALIZED
|
||||
(
|
||||
SELECT x, x, 0
|
||||
FROM (WITH RECURSIVE n(t) AS (SELECT 1 UNION ALL SELECT t+1 FROM n WHERE t < 10) SELECT * FROM n) AS _(x)
|
||||
UNION ALL
|
||||
(SELECT x, CASE WHEN t%2 = 1 THEN t * 3 + p ELSE t / 2 END, steps + p
|
||||
FROM collatz, (WITH RECURSIVE n(t) AS (SELECT 1 UNION ALL SELECT t+1 FROM n WHERE t < 1) SELECT * FROM n) AS _(p)
|
||||
WHERE t <> 1)
|
||||
)
|
||||
SELECT * FROM collatz WHERE t = 1
|
||||
ORDER BY x;
|
||||
----
|
||||
1 1 0
|
||||
2 1 1
|
||||
3 1 7
|
||||
4 1 2
|
||||
5 1 5
|
||||
6 1 8
|
||||
7 1 16
|
||||
8 1 3
|
||||
9 1 19
|
||||
10 1 6
|
||||
30
external/duckdb/test/sql/cte/materialized/test_outer_joins_recursive_cte_materialized.test
vendored
Normal file
30
external/duckdb/test/sql/cte/materialized/test_outer_joins_recursive_cte_materialized.test
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# name: test/sql/cte/materialized/test_outer_joins_recursive_cte_materialized.test
|
||||
# description: Test Recursive Common Table Expressions (CTE) with outer joins
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE v(x INT);
|
||||
|
||||
statement ok
|
||||
INSERT INTO v
|
||||
VALUES
|
||||
(1),(2),(3);
|
||||
|
||||
query II
|
||||
WITH RECURSIVE t(x) AS MATERIALIZED
|
||||
(
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT x + 1
|
||||
FROM (SELECT t.x+1 FROM v AS _(p) FULL OUTER JOIN t ON t.x = p) AS _(x)
|
||||
WHERE x < 10
|
||||
) SELECT * FROM v AS _(p) RIGHT OUTER JOIN t ON t.x = p ORDER BY p, x NULLS LAST;
|
||||
----
|
||||
1 1
|
||||
3 3
|
||||
NULL 5
|
||||
NULL 7
|
||||
NULL 9
|
||||
141
external/duckdb/test/sql/cte/materialized/test_recursive_cte_tutorial_materialized.test
vendored
Normal file
141
external/duckdb/test/sql/cte/materialized/test_recursive_cte_tutorial_materialized.test
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
# name: test/sql/cte/materialized/test_recursive_cte_tutorial_materialized.test
|
||||
# description: Test Recursive CTEs from the CyberTec tutorial: https://www.cybertec-postgresql.com/en/recursive-queries-postgresql/
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE emp (empno INTEGER PRIMARY KEY,
|
||||
ename VARCHAR,
|
||||
job VARCHAR,
|
||||
mgr INTEGER,
|
||||
hiredate DATE,
|
||||
sal DOUBLE,
|
||||
comm DOUBLE,
|
||||
deptno INTEGER);
|
||||
|
||||
statement ok
|
||||
INSERT INTO emp VALUES (7839, 'KING', 'PRESIDENT', NULL, DATE '1981-11-17', 5000.00, NULL, 10);
|
||||
INSERT INTO emp VALUES (7698, 'BLAKE', 'MANAGER', 7839, DATE '1981-05-01', 2850.00, NULL, 30);
|
||||
INSERT INTO emp VALUES (7782, 'CLARK', 'MANAGER', 7839, DATE '1981-06-09', 2450.00, NULL, 10);
|
||||
INSERT INTO emp VALUES (7566, 'JONES', 'MANAGER', 7839, DATE '1981-04-02', 2975.00, NULL, 20);
|
||||
INSERT INTO emp VALUES (7902, 'FORD', 'ANALYST', 7566, DATE '1981-12-03', 3000.00, NULL, 20);
|
||||
INSERT INTO emp VALUES (7369, 'SMITH', 'CLERK', 7902, DATE '1980-12-17', 800.00, NULL, 20);
|
||||
INSERT INTO emp VALUES (7499, 'ALLEN', 'SALESMAN', 7698, DATE '1981-02-20', 1600.00, 300.00, 30);
|
||||
INSERT INTO emp VALUES (7521, 'WARD', 'SALESMAN', 7698, DATE '1981-02-22', 1250.00, 500.00, 30);
|
||||
INSERT INTO emp VALUES (7654, 'MARTIN', 'SALESMAN', 7698, DATE '1981-09-28', 1250.00, 1400.00, 30);
|
||||
INSERT INTO emp VALUES (7844, 'TURNER', 'SALESMAN', 7698, DATE '1981-09-08', 1500.00, 0.00, 30);
|
||||
INSERT INTO emp VALUES (7900, 'JAMES', 'CLERK', 7698, DATE '1981-12-03', 950.00, NULL, 30);
|
||||
INSERT INTO emp VALUES (7934, 'MILLER', 'CLERK', 7782, DATE '1982-01-23', 1300.00, NULL, 10);
|
||||
|
||||
query II
|
||||
WITH RECURSIVE ctename AS MATERIALIZED (
|
||||
SELECT empno, ename
|
||||
FROM emp
|
||||
WHERE empno = 7566
|
||||
UNION ALL
|
||||
SELECT emp.empno, emp.ename
|
||||
FROM emp
|
||||
JOIN ctename ON emp.mgr = ctename.empno
|
||||
)
|
||||
SELECT * FROM ctename;
|
||||
----
|
||||
7566 JONES
|
||||
7902 FORD
|
||||
7369 SMITH
|
||||
|
||||
query III
|
||||
WITH RECURSIVE ctename AS MATERIALIZED (
|
||||
SELECT empno, ename,
|
||||
0 AS level
|
||||
FROM emp
|
||||
WHERE empno = 7566
|
||||
UNION ALL
|
||||
SELECT emp.empno, emp.ename,
|
||||
ctename.level + 1
|
||||
FROM emp
|
||||
JOIN ctename ON emp.mgr = ctename.empno
|
||||
)
|
||||
SELECT * FROM ctename;
|
||||
----
|
||||
7566 JONES 0
|
||||
7902 FORD 1
|
||||
7369 SMITH 2
|
||||
|
||||
query III
|
||||
WITH RECURSIVE ctename AS MATERIALIZED (
|
||||
SELECT empno, ename,
|
||||
ename AS path
|
||||
FROM emp
|
||||
WHERE empno = 7566
|
||||
UNION ALL
|
||||
SELECT emp.empno, emp.ename,
|
||||
ctename.path || ' -> ' || emp.ename
|
||||
FROM emp
|
||||
JOIN ctename ON emp.mgr = ctename.empno
|
||||
)
|
||||
SELECT * FROM ctename;
|
||||
----
|
||||
7566 JONES JONES
|
||||
7902 FORD JONES -> FORD
|
||||
7369 SMITH JONES -> FORD -> SMITH
|
||||
|
||||
statement ok
|
||||
CREATE VIEW ctenames AS (
|
||||
WITH RECURSIVE ctename AS MATERIALIZED (
|
||||
SELECT empno, ename,
|
||||
ename AS path
|
||||
FROM emp
|
||||
WHERE empno = 7566
|
||||
UNION ALL
|
||||
SELECT emp.empno, emp.ename,
|
||||
ctename.path || ' -> ' || emp.ename
|
||||
FROM emp
|
||||
JOIN ctename ON emp.mgr = ctename.empno
|
||||
)
|
||||
SELECT * FROM ctename
|
||||
);
|
||||
|
||||
query III
|
||||
SELECT * FROM ctenames;
|
||||
----
|
||||
7566 JONES JONES
|
||||
7902 FORD JONES -> FORD
|
||||
7369 SMITH JONES -> FORD -> SMITH
|
||||
|
||||
query II
|
||||
WITH RECURSIVE fib AS MATERIALIZED (
|
||||
SELECT 1 AS n,
|
||||
1::bigint AS "fibₙ",
|
||||
1::bigint AS "fibₙ₊₁"
|
||||
UNION ALL
|
||||
SELECT n+1,
|
||||
"fibₙ₊₁",
|
||||
"fibₙ" + "fibₙ₊₁"
|
||||
FROM fib
|
||||
WHERE n <= 20
|
||||
)
|
||||
SELECT n, "fibₙ" FROM fib
|
||||
LIMIT 20;
|
||||
----
|
||||
1 1
|
||||
2 1
|
||||
3 2
|
||||
4 3
|
||||
5 5
|
||||
6 8
|
||||
7 13
|
||||
8 21
|
||||
9 34
|
||||
10 55
|
||||
11 89
|
||||
12 144
|
||||
13 233
|
||||
14 377
|
||||
15 610
|
||||
16 987
|
||||
17 1597
|
||||
18 2584
|
||||
19 4181
|
||||
20 6765
|
||||
118
external/duckdb/test/sql/cte/materialized/test_recursive_cte_union_all_materialized.test
vendored
Normal file
118
external/duckdb/test/sql/cte/materialized/test_recursive_cte_union_all_materialized.test
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
# name: test/sql/cte/materialized/test_recursive_cte_union_all_materialized.test
|
||||
# description: Test Recursive Common Table Expressions UNION ALL (CTE)
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# simple recursive CTE
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union all select x+1 from t where x < 3) select * from t
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# simple recursive CTE with an alias
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union all select x+1 from t as m where m.x < 3) select * from t
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# recursive CTE with multiple references and aliases
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union all select m.x+f.x from t as m, t as f where m.x < 3) select * from t
|
||||
----
|
||||
1
|
||||
2
|
||||
4
|
||||
|
||||
# strings and multiple columns
|
||||
query IT
|
||||
with recursive t as MATERIALIZED (select 1 as x, 'hello' as y union all select x+1, y || '-' || 'hello' from t where x < 3) select * from t;
|
||||
----
|
||||
1 hello
|
||||
2 hello-hello
|
||||
3 hello-hello-hello
|
||||
|
||||
# referencing same CTE multiple times
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union all select x+1 from t where x < 3) select min(a1.x) from t a1, t a2;
|
||||
----
|
||||
1
|
||||
|
||||
# nested uncorrelated subquery
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union all select x+(SELECT 1) from t where x < 3) select * from t;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# use with recursive in table creation
|
||||
statement ok
|
||||
create table integers as with recursive t as MATERIALIZED (select 1 as x union all select x+1 from t where x < 3) select * from t;
|
||||
|
||||
# more complex uncorrelated subquery
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select (select min(x) from integers) as x union all select x+1 from t where x < 3) select * from t;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# aggregate function
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union all select sum(x+1) AS x from t where x < 3 group by x) select * from t
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# recursive CTE with table-producing function
|
||||
query I
|
||||
WITH RECURSIVE t AS MATERIALIZED (
|
||||
SELECT 1 AS i
|
||||
UNION ALL
|
||||
SELECT j
|
||||
FROM t, generate_series(0, 10, 1) series(j)
|
||||
WHERE j=i+1
|
||||
)
|
||||
SELECT * FROM t;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
|
||||
# order by is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as MATERIALIZED (select 1 as x union all select x+1 from t where x < 3 order by x) select * from t
|
||||
----
|
||||
<REGEX>:.*Parser Error.*recursive query is not allowed.*
|
||||
|
||||
# limit is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as MATERIALIZED (select 1 as x union all select x+1 from t where x < 3 LIMIT 1) select * from t
|
||||
----
|
||||
<REGEX>:.*Parser Error.*recursive query is not allowed.*
|
||||
|
||||
# offset is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as MATERIALIZED (select 1 as x union all select x+1 from t where x < 3 OFFSET 1) select * from t
|
||||
----
|
||||
<REGEX>:.*Parser Error.*recursive query is not allowed.*
|
||||
|
||||
# offset is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as MATERIALIZED (select 1 as x union all select x+1 from t where x < 3 LIMIT 1 OFFSET 1) select * from t
|
||||
----
|
||||
<REGEX>:.*Parser Error.*recursive query is not allowed.*
|
||||
140
external/duckdb/test/sql/cte/materialized/test_recursive_cte_union_materialized.test
vendored
Normal file
140
external/duckdb/test/sql/cte/materialized/test_recursive_cte_union_materialized.test
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
# name: test/sql/cte/materialized/test_recursive_cte_union_materialized.test
|
||||
# description: Test Recursive Common Table Expressions UNION (CTE)
|
||||
# group: [materialized]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# simple recursive CTE
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union select x+1 from t where x < 3) select * from t order by x
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
query I
|
||||
with recursive t(x) as MATERIALIZED (select 1 union select x+1 from t where x < 3) select * from t order by x
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# test some aliases
|
||||
query I
|
||||
with recursive t(x) as MATERIALIZED (select 1 union select x+1 from t where x < 3) select zz from t t1(zz) order by zz
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
query I
|
||||
with recursive t(x) as MATERIALIZED (select 1 union select zzz+1 from t t1(zzz) where zzz < 3) select zz from t t1(zz) order by zz
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# UNION semantics prevents infinite loop here
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union select x from t) select * from t
|
||||
----
|
||||
1
|
||||
|
||||
# simple recursive CTE with an alias
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union select x+1 from t as m where m.x < 3) select * from t order by x
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# recursive CTE with multiple references and aliases
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union select m.x+f.x from t as m, t as f where m.x < 3) select * from t order by x
|
||||
----
|
||||
1
|
||||
2
|
||||
4
|
||||
|
||||
# strings and multiple columns
|
||||
query IT
|
||||
with recursive t as MATERIALIZED (select 1 as x, 'hello' as y union select x+1, y || '-' || 'hello' from t where x < 3) select * from t order by x;
|
||||
----
|
||||
1 hello
|
||||
2 hello-hello
|
||||
3 hello-hello-hello
|
||||
|
||||
# referencing same CTE multiple times
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union select x+1 from t where x < 3) select min(a1.x) from t a1, t a2;
|
||||
----
|
||||
1
|
||||
|
||||
# nested uncorrelated subquery
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union select x+(SELECT 1) from t where x < 3) select * from t order by x;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# correlated subquery
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union select x+(SELECT 1+t.x) from t where x < 5) select * from t order by x;
|
||||
----
|
||||
1
|
||||
3
|
||||
7
|
||||
|
||||
# use with recursive in table creation
|
||||
statement ok
|
||||
create table integers as with recursive t as MATERIALIZED (select 1 as x union select x+1 from t where x < 3) select * from t;
|
||||
|
||||
# more complex uncorrelated subquery
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select (select min(x) from integers) as x union select x+1 from t where x < 3) select * from t order by x;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# aggregate functions
|
||||
query I
|
||||
with recursive t as MATERIALIZED (select 1 as x union select sum(x+1) from t where x < 3) select * from t order by 1 nulls last
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
NULL
|
||||
|
||||
# order by is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as MATERIALIZED (select 1 as x union select sum(x+1) from t where x < 3 order by x) select * from t
|
||||
----
|
||||
|
||||
# limit is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as MATERIALIZED (select 1 as x union select sum(x+1) from t where x < 3 LIMIT 1) select * from t
|
||||
----
|
||||
|
||||
# offset is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as MATERIALIZED (select 1 as x union select sum(x+1) from t where x < 3 OFFSET 1) select * from t
|
||||
----
|
||||
|
||||
# offset is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as MATERIALIZED (select 1 as x union select sum(x+1) from t where x < 3 LIMIT 1 OFFSET 1) select * from t
|
||||
----
|
||||
|
||||
# create a view from a recursive cte
|
||||
statement ok
|
||||
create view vr as (with recursive t(x) as MATERIALIZED (select 1 union select x+1 from t where x < 3) select * from t order by x)
|
||||
|
||||
query I
|
||||
select * from vr
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
76
external/duckdb/test/sql/cte/recursive_array_slice.test
vendored
Normal file
76
external/duckdb/test/sql/cte/recursive_array_slice.test
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# name: test/sql/cte/recursive_array_slice.test
|
||||
# description: Issue #3005: array_slice prevents row values to be used more than once
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE p(loc int8);
|
||||
|
||||
statement ok
|
||||
INSERT INTO p VALUES (1);
|
||||
|
||||
query II
|
||||
WITH RECURSIVE t(y, arr) AS
|
||||
(
|
||||
SELECT 1, array[1,2,3,4,5,6]
|
||||
UNION ALL
|
||||
SELECT y+1, arr[:loc]
|
||||
FROM t, p
|
||||
WHERE y < 10
|
||||
) SELECT * FROM t;
|
||||
----
|
||||
1 [1, 2, 3, 4, 5, 6]
|
||||
2 [1]
|
||||
3 [1]
|
||||
4 [1]
|
||||
5 [1]
|
||||
6 [1]
|
||||
7 [1]
|
||||
8 [1]
|
||||
9 [1]
|
||||
10 [1]
|
||||
|
||||
query II
|
||||
WITH RECURSIVE t(y, arr) AS
|
||||
(
|
||||
SELECT 1, array[1,2,3,4,5,6]
|
||||
UNION ALL
|
||||
SELECT y+1, arr
|
||||
FROM t, p
|
||||
WHERE y < 10
|
||||
AND y = loc
|
||||
) SELECT * FROM t;
|
||||
----
|
||||
1 [1, 2, 3, 4, 5, 6]
|
||||
2 [1, 2, 3, 4, 5, 6]
|
||||
|
||||
query II
|
||||
WITH RECURSIVE t(y, arr) AS
|
||||
(
|
||||
SELECT 1, array[1,2,3,4,5,6]
|
||||
UNION ALL
|
||||
SELECT y+1, arr[:loc]
|
||||
FROM t, p
|
||||
WHERE y < 10
|
||||
AND y = loc
|
||||
) SELECT * FROM t;
|
||||
----
|
||||
1 [1, 2, 3, 4, 5, 6]
|
||||
2 [1]
|
||||
|
||||
query I
|
||||
WITH RECURSIVE t(arr) AS
|
||||
(
|
||||
SELECT array[1,2,3,4,5,6]
|
||||
UNION ALL
|
||||
SELECT arr[arr[1]+1:6]
|
||||
FROM t
|
||||
WHERE arr[1] < 6
|
||||
) SELECT * FROM t;
|
||||
----
|
||||
[1, 2, 3, 4, 5, 6]
|
||||
[2, 3, 4, 5, 6]
|
||||
[4, 5, 6]
|
||||
[]
|
||||
133
external/duckdb/test/sql/cte/recursive_cte_complex_pipelines.test
vendored
Normal file
133
external/duckdb/test/sql/cte/recursive_cte_complex_pipelines.test
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
# name: test/sql/cte/recursive_cte_complex_pipelines.test
|
||||
# description: Recursive CTEs with complex pipelines
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# recursive CTE with various cross products
|
||||
query I
|
||||
WITH RECURSIVE t AS
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT t1.x + t2.x + t3.x AS x
|
||||
FROM t t1, t t2, t t3
|
||||
WHERE t1.x < 100
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1;
|
||||
----
|
||||
1
|
||||
3
|
||||
9
|
||||
27
|
||||
81
|
||||
243
|
||||
|
||||
# what if we have different types?
|
||||
query I
|
||||
WITH RECURSIVE t AS
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT (t1.x + t2.x + t3.x)::HUGEINT AS x
|
||||
FROM t t1, t t2, t t3
|
||||
WHERE t1.x < 100
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1;
|
||||
----
|
||||
1
|
||||
3
|
||||
9
|
||||
27
|
||||
81
|
||||
243
|
||||
|
||||
statement ok
|
||||
CREATE TABLE a AS SELECT * FROM range(100) t1(i)
|
||||
|
||||
# recursive CTE with aggregates
|
||||
query I
|
||||
WITH RECURSIVE t AS
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT SUM(x) AS x
|
||||
FROM t, a
|
||||
WHERE x < 1000000
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
100
|
||||
10000
|
||||
1000000
|
||||
NULL
|
||||
|
||||
# the same but with a hash join
|
||||
query I
|
||||
WITH RECURSIVE t AS
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT SUM(x) AS x
|
||||
FROM t, a
|
||||
WHERE x < 1000000 AND t.x=a.i
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
|
||||
# nested aggregates
|
||||
query I
|
||||
WITH RECURSIVE t AS
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT SUM(x)
|
||||
FROM
|
||||
(SELECT SUM(x) FROM t) t1(x), a
|
||||
WHERE x < 1000
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
100
|
||||
10000
|
||||
NULL
|
||||
|
||||
# non-correlated subqueries
|
||||
query I
|
||||
WITH RECURSIVE t AS
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT (SELECT x + 1 FROM t) AS x
|
||||
FROM t
|
||||
WHERE x < 5
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
|
||||
# correlated subqueries
|
||||
query I
|
||||
WITH RECURSIVE t AS
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT (SELECT t.x+t2.x FROM t t2 LIMIT 1) AS x
|
||||
FROM t
|
||||
WHERE x < 10
|
||||
)
|
||||
SELECT * FROM t ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
2
|
||||
4
|
||||
8
|
||||
16
|
||||
33
external/duckdb/test/sql/cte/recursive_cte_correlated_subquery.test_slow
vendored
Normal file
33
external/duckdb/test/sql/cte/recursive_cte_correlated_subquery.test_slow
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# name: test/sql/cte/recursive_cte_correlated_subquery.test_slow
|
||||
# description: Issue #2713: reports struct_extract error when run a sql
|
||||
# group: [cte]
|
||||
|
||||
query I
|
||||
WITH RECURSIVE
|
||||
input(sud) AS (
|
||||
VALUES('53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79')
|
||||
),
|
||||
digits(z, lp) AS (
|
||||
SELECT CAST(lp+1 AS TEXT), lp::int+1 FROM generate_series(0,8,1) t(lp)
|
||||
),
|
||||
x(s, ind) AS (
|
||||
SELECT sud, instr(sud, '.') FROM input
|
||||
UNION ALL
|
||||
SELECT
|
||||
substr(s, 1, ind::int-1) || z || substr(s, ind::int+1),
|
||||
instr(substr(s, 1, ind::int-1) || z || substr(s, ind::int+1), '.' )
|
||||
FROM x, digits AS z
|
||||
WHERE ind::int>0
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM digits AS lp
|
||||
WHERE z.z = substr(s, ((ind::int-1)//9)*9 + lp, 1)
|
||||
OR z.z = substr(s, ((ind::int-1)%9) + (lp-1)*9 + 1, 1)
|
||||
OR z.z = substr(s, (((ind::int-1)//3) % 3) * 3
|
||||
+ ((ind::int-1)//27) * 27 + lp
|
||||
+ ((lp-1) // 3) * 6, 1)
|
||||
)
|
||||
)
|
||||
SELECT s FROM x WHERE ind::int=0;
|
||||
----
|
||||
534678912672195348198342567859761423426853791713924856961537284287419635345286179
|
||||
32
external/duckdb/test/sql/cte/recursive_cte_error.test
vendored
Normal file
32
external/duckdb/test/sql/cte/recursive_cte_error.test
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# name: test/sql/cte/recursive_cte_error.test
|
||||
# description: Recursive CTEs with an error thrown in the pipelines
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tag(id int, name string, subclassof int);
|
||||
|
||||
statement ok
|
||||
INSERT INTO tag VALUES
|
||||
(7, 'Music', 9),
|
||||
(8, 'Movies', 9),
|
||||
(9, 'Art', NULL)
|
||||
;
|
||||
|
||||
statement error
|
||||
WITH RECURSIVE tag_hierarchy(id, source, path, target) AS (
|
||||
SELECT id, name, name AS path, NULL AS target -- this should be '' for correct behaviour
|
||||
FROM tag
|
||||
WHERE subclassof IS NULL
|
||||
UNION ALL
|
||||
SELECT tag.id, tag.name, tag_hierarchy.path || ' <- ' || tag.name, tag.name AS target
|
||||
FROM tag, tag_hierarchy
|
||||
WHERE tag.subclassof = tag_hierarchy.id
|
||||
)
|
||||
SELECT source, path, target
|
||||
FROM tag_hierarchy
|
||||
;
|
||||
----
|
||||
<REGEX>:.*Conversion Error: Could not convert string.*
|
||||
409
external/duckdb/test/sql/cte/recursive_cte_key_variant.test
vendored
Normal file
409
external/duckdb/test/sql/cte/recursive_cte_key_variant.test
vendored
Normal file
@@ -0,0 +1,409 @@
|
||||
# name: test/sql/cte/recursive_cte_key_variant.test
|
||||
# description: Recursive CTEs with an error thrown in the pipelines
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification;
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tbl(a int);
|
||||
|
||||
query I
|
||||
WITH RECURSIVE tbl(a) USING KEY (a) AS (SELECT 1 UNION SELECT a.a+1 FROM tbl AS a, (SELECT * FROM recurring.tbl AS d WHERE d.a = 1) AS b WHERE a.a < 2) SELECT * FROM tbl;
|
||||
----
|
||||
1
|
||||
2
|
||||
|
||||
# reference only the recurring table
|
||||
query II
|
||||
WITH RECURSIVE tbl2(a, b) USING KEY (a) AS (SELECT 5, 1 UNION SELECT a, b + 1 FROM recurring.tbl2 WHERE b < a) SELECT * FROM tbl2;
|
||||
----
|
||||
5 5
|
||||
|
||||
statement error
|
||||
WITH RECURSIVE tbl(a) USING KEY (b) AS (SELECT 1 UNION SELECT a.a+1 FROM tbl AS a, (SELECT * FROM recurring.tbl AS d WHERE d.a = 1) AS b WHERE a.a < 2) SELECT * FROM tbl;
|
||||
----
|
||||
Binder Error: Referenced column "b" not found in FROM clause!
|
||||
|
||||
statement error
|
||||
WITH RECURSIVE tbl(a) USING KEY (a) AS (SELECT 1 UNION ALL SELECT a+1 FROM tbl) SELECT * FROM tbl;
|
||||
----
|
||||
Binder Error: UNION ALL cannot be used with USING KEY in recursive CTE.
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl2(a,b) USING KEY (a) AS (SELECT 1, NULL UNION SELECT a.a+1, a.b FROM tbl2 AS a, (SELECT * FROM recurring.tbl2) AS b WHERE a.a < 2) SELECT * FROM tbl2;
|
||||
----
|
||||
1 NULL
|
||||
2 NULL
|
||||
|
||||
query III
|
||||
WITH RECURSIVE tbl(a,b,c) USING KEY (a) AS (SELECT * FROM (VALUES (1, 2, 3), (2,2,5)) UNION SELECT a+1, b+1, c FROM tbl WHERE b < 4) SELECT * FROM tbl;
|
||||
----
|
||||
1 2 3
|
||||
2 3 3
|
||||
3 4 3
|
||||
4 4 5
|
||||
|
||||
query III
|
||||
WITH RECURSIVE tbl(a,b,c) USING KEY (b) AS (SELECT * FROM (VALUES (1, 2, 3), (2,3,2)) UNION SELECT a, b+1, c FROM tbl WHERE b < 4) SELECT * FROM tbl;
|
||||
----
|
||||
1 2 3
|
||||
1 3 3
|
||||
1 4 3
|
||||
|
||||
query III
|
||||
WITH RECURSIVE tbl(a,b,c) USING KEY (a) AS (SELECT * FROM (VALUES (1, 2, 3), (2,3,2)) UNION SELECT a, b+1, c FROM tbl WHERE b < 4) SELECT * FROM tbl;
|
||||
----
|
||||
1 4 3
|
||||
2 4 2
|
||||
|
||||
query III
|
||||
WITH RECURSIVE tbl(a,b,c) USING KEY (b,c) AS (SELECT * FROM (VALUES (1, 2, 3), (2,3,3)) UNION SELECT a, b+1, c FROM tbl WHERE b < 4) SELECT * FROM tbl;
|
||||
----
|
||||
1 2 3
|
||||
1 3 3
|
||||
1 4 3
|
||||
|
||||
query III
|
||||
WITH RECURSIVE tbl(a,b,c) USING KEY (a,b,c) AS (SELECT * FROM (VALUES (1, 2, 3), (2,3,3)) UNION SELECT a, b+1, c FROM tbl WHERE b < 4) SELECT * FROM tbl;
|
||||
----
|
||||
1 2 3
|
||||
2 3 3
|
||||
1 3 3
|
||||
2 4 3
|
||||
1 4 3
|
||||
|
||||
query III
|
||||
WITH RECURSIVE tbl(a,b,c) USING KEY (a) AS (SELECT * FROM (VALUES (1, 2, 3), (1,3,3)) UNION SELECT a, b+1, c FROM tbl WHERE b < 4) SELECT * FROM tbl;
|
||||
----
|
||||
1 4 3
|
||||
|
||||
query III
|
||||
WITH RECURSIVE tbl(a,b,c) USING KEY (a,b,c) AS (SELECT * FROM (VALUES (1, 2, 3), (1,3,3)) UNION SELECT a, b+1, c FROM tbl WHERE b < 4) SELECT * FROM tbl;
|
||||
----
|
||||
1 2 3
|
||||
1 3 3
|
||||
1 4 3
|
||||
|
||||
# Reference the recurring table more than once
|
||||
query III
|
||||
WITH RECURSIVE tbl(a,b,c) USING KEY (a) AS (
|
||||
SELECT 1, NULL, NULL
|
||||
UNION
|
||||
(SELECT DISTINCT ON (tbl.a) tbl.a+1, rec1.a, rec2.b
|
||||
FROM tbl, recurring.tbl AS rec1, recurring.tbl AS rec2
|
||||
WHERE tbl.a < 5
|
||||
ORDER BY tbl.a ASC, rec1.a DESC NULLS LAST, rec2.b DESC NULLS LAST
|
||||
)
|
||||
) SELECT * FROM tbl;
|
||||
----
|
||||
1 NULL NULL
|
||||
2 1 NULL
|
||||
3 2 1
|
||||
4 3 2
|
||||
5 4 3
|
||||
|
||||
############################################
|
||||
# reference recurring table in wrong places
|
||||
############################################
|
||||
|
||||
statement error
|
||||
SELECT * FROM recurring.tbl;
|
||||
----
|
||||
Catalog Error: Table with name tbl does not exist!
|
||||
|
||||
# no using key
|
||||
statement error
|
||||
WITH RECURSIVE tbl2(a) AS (SELECT 1 UNION SELECT a.a + 1 FROM tbl2 AS a, recurring.tbl2 AS b WHERE a.a < 2) SELECT * FROM tbl2;
|
||||
----
|
||||
does not exist
|
||||
|
||||
statement error
|
||||
WITH RECURSIVE tbl2(a,b) AS (SELECT 1, NULL UNION SELECT a.a+1, a.b FROM tbl2 AS a, (SELECT * FROM recurring.tbl2) AS b WHERE a.a < 2) SELECT * FROM tbl2;
|
||||
----
|
||||
does not exist
|
||||
|
||||
# second cte references recurring table of first cte while first cte does not
|
||||
statement error
|
||||
WITH RECURSIVE tbl(a, b) USING KEY (a) AS (SELECT 5, 1 UNION SELECT a, b + 1 FROM tbl WHERE b < a),
|
||||
tbl1(a,b) AS (SELECT * FROM recurring.tbl) SELECT * FROM tbl1;
|
||||
----
|
||||
does not exist
|
||||
|
||||
# second cte references recurring table of first like the first cte
|
||||
statement error
|
||||
WITH RECURSIVE tbl(a, b) USING KEY (a) AS (SELECT * FROM ((VALUES (5, 1), (6,1)) UNION SELECT a, b + 1 FROM recurring.tbl WHERE b < a) WHERE a = 5),
|
||||
tbl1(a,b) AS (SELECT * FROM recurring.tbl) SELECT * FROM tbl1;
|
||||
----
|
||||
does not exist
|
||||
|
||||
statement error
|
||||
WITH RECURSIVE tbl2(a) AS (SELECT 1 UNION SELECT a.a+1 FROM tbl2 AS a, (SELECT * FROM recurring.tbl2) AS b WHERE a.a < 2) SELECT * FROM tbl2;
|
||||
----
|
||||
does not exist
|
||||
|
||||
statement error
|
||||
WITH RECURSIVE tbl(a, b) USING KEY (a) AS (SELECT 5, 1 UNION SELECT a, b + 1 FROM tbl WHERE b < a),tbl1(a,b) AS (SELECT * FROM recurring.tbl) SELECT * FROM tbl1;
|
||||
----
|
||||
does not exist
|
||||
|
||||
statement error
|
||||
WITH RECURSIVE tbl(a, b) USING KEY (a) AS MATERIALIZED (SELECT 5, 1 UNION SELECT a, b + 1 FROM tbl WHERE b < a),tbl1(a,b) AS (SELECT * FROM recurring.tbl) SELECT * FROM tbl1;
|
||||
----
|
||||
does not exist
|
||||
|
||||
#######################
|
||||
# Connected components
|
||||
#######################
|
||||
statement ok
|
||||
CREATE OR REPLACE TABLE nodes (node int);
|
||||
|
||||
statement ok
|
||||
INSERT INTO nodes VALUES (0), (1), (2), (3), (4), (5), (6);
|
||||
|
||||
statement ok
|
||||
CREATE OR REPLACE TABLE edges (here int, there int);
|
||||
|
||||
statement ok
|
||||
INSERT INTO edges VALUES (0,4), (4,0),
|
||||
(0,3), (3,0),
|
||||
(1,4), (4,1),
|
||||
(3,4), (4,3),
|
||||
(2,5), (5,2);
|
||||
|
||||
|
||||
|
||||
query II
|
||||
WITH RECURSIVE cc(node, comp) USING KEY (node) AS (
|
||||
SELECT n.node, n.node AS comp
|
||||
FROM nodes AS n
|
||||
UNION
|
||||
(SELECT DISTINCT ON (u.node) u.node, v.comp
|
||||
FROM recurring.cc AS u, cc AS v, edges AS e
|
||||
WHERE (e.here, e.there) = (u.node, v.node)
|
||||
AND v.comp < u.comp
|
||||
ORDER BY u.node asc, v.comp asc)
|
||||
)
|
||||
TABLE cc ORDER BY node;
|
||||
----
|
||||
0 0
|
||||
1 0
|
||||
2 2
|
||||
3 0
|
||||
4 0
|
||||
5 2
|
||||
6 6
|
||||
|
||||
#######################
|
||||
# bellman-ford
|
||||
#######################
|
||||
statement ok
|
||||
CREATE OR REPLACE TABLE edges (here char(2), -- source node
|
||||
there char(2), -- target node
|
||||
length int, -- edge weight
|
||||
PRIMARY KEY (here, there));
|
||||
|
||||
statement ok
|
||||
INSERT INTO edges(here, there, length) VALUES
|
||||
('v0', 'v1', 9),
|
||||
('v0', 'v2', 3),
|
||||
('v1', 'v2', 6),
|
||||
('v1', 'v4', 2),
|
||||
('v2', 'v1', 2),
|
||||
('v2', 'v3', 1),
|
||||
('v3', 'v2', 2),
|
||||
('v3', 'v4', 2);
|
||||
|
||||
statement ok
|
||||
DROP TABLE nodes;
|
||||
|
||||
statement ok
|
||||
CREATE OR REPLACE VIEW nodes(node) AS
|
||||
SELECT e.here
|
||||
FROM edges AS e
|
||||
UNION
|
||||
SELECT e.there
|
||||
FROM edges AS e;
|
||||
|
||||
query II
|
||||
WITH RECURSIVE bellman(knode, distance) USING KEY (knode) AS (
|
||||
-- distance is 0 from source, ∞ from any other node
|
||||
SELECT n.node AS knode,
|
||||
CASE WHEN n.node = 'v0' THEN 0 ELSE 50000000 END AS distance
|
||||
FROM nodes AS n
|
||||
UNION
|
||||
(SELECT DISTINCT ON (knode) rec.knode AS knode, n.distance + e.length AS distance
|
||||
FROM bellman AS n, edges AS e, recurring.bellman AS rec
|
||||
WHERE (e.here, e.there) = (n.knode, rec.knode)
|
||||
AND rec.distance > n.distance + e.length
|
||||
ORDER BY distance)
|
||||
)
|
||||
SELECT n.knode || CASE WHEN n.knode = 'v0' THEN ' (source)' ELSE '' END AS node,
|
||||
n.distance
|
||||
FROM bellman AS n
|
||||
ORDER BY n.knode;
|
||||
----
|
||||
v0 (source) 0
|
||||
v1 5
|
||||
v2 3
|
||||
v3 4
|
||||
v4 6
|
||||
|
||||
|
||||
# more rows than STANDARD_CHUNK_SIZE
|
||||
query I
|
||||
WITH RECURSIVE tbl(n) USING KEY (n) AS (SELECT 1 UNION SELECT n+1 FROM tbl WHERE n < 3000) SELECT SUM(n) FROM tbl
|
||||
----
|
||||
4501500
|
||||
|
||||
# You can use recursive CTE with and without a key in a query.
|
||||
query II
|
||||
WITH RECURSIVE tbl (a, b) USING KEY (a) AS (SELECT 1 , 1 UNION SELECT a, b+1 FROM tbl WHERE b < 3), tbl2(a,b) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl2 WHERE b < 3) SELECT * FROM tbl;
|
||||
----
|
||||
1 3
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl (a, b) USING KEY (a) AS (SELECT 1 , 1 UNION SELECT a, b+1 FROM tbl WHERE b < 3), tbl2(a,b) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl2 WHERE b < 3) SELECT * FROM tbl2;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl2(a,b) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl2 WHERE b < 3), tbl (a, b) USING KEY (a) AS (SELECT 1 , 1 UNION SELECT a, b+1 FROM tbl WHERE b < 3) SELECT * FROM tbl2;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl2(a,b) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl2 WHERE b < 3), tbl (a, b) USING KEY (a) AS (SELECT 1 , 1 UNION SELECT a, b+1 FROM tbl WHERE b < 3) SELECT * FROM tbl;
|
||||
----
|
||||
1 3
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl(a, b) AS (
|
||||
SELECT 1, 1
|
||||
UNION
|
||||
(WITH RECURSIVE tbl2(a, b) USING KEY (b) AS (
|
||||
SELECT a, b+1 FROM tbl WHERE b < 5
|
||||
UNION
|
||||
SELECT a + 1, b
|
||||
FROM tbl2
|
||||
WHERE a < 5) SELECT * FROM tbl2))
|
||||
SELECT * FROM tbl
|
||||
----
|
||||
1 1
|
||||
5 2
|
||||
5 3
|
||||
5 4
|
||||
5 5
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl(a, b) USING KEY (b) AS (
|
||||
SELECT 1, 1
|
||||
UNION
|
||||
(WITH RECURSIVE tbl2(a, b) AS (
|
||||
SELECT a, b+1 FROM tbl WHERE b < 5
|
||||
UNION
|
||||
SELECT a + 1, b
|
||||
FROM tbl2
|
||||
WHERE a < 5) SELECT * FROM tbl2 ORDER BY a))
|
||||
SELECT * FROM tbl
|
||||
----
|
||||
1 1
|
||||
5 2
|
||||
5 3
|
||||
5 4
|
||||
5 5
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl(a, b) USING KEY (b) AS (
|
||||
SELECT 1, 1
|
||||
UNION
|
||||
(SELECT * FROM (WITH RECURSIVE tbl2(a, b) AS (
|
||||
SELECT a, b+1 FROM tbl WHERE b < 5
|
||||
UNION
|
||||
SELECT a + 1, b
|
||||
FROM tbl2
|
||||
WHERE a < 5) SELECT * FROM tbl2 ORDER BY a, b)))
|
||||
SELECT * FROM tbl
|
||||
----
|
||||
1 1
|
||||
5 2
|
||||
5 3
|
||||
5 4
|
||||
5 5
|
||||
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl(a,b) USING KEY (a) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl WHERE b < 5),
|
||||
tbl2(a,b) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl2 WHERE b < 5)
|
||||
SELECT *
|
||||
FROM tbl2
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
1 4
|
||||
1 5
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl(a,b) USING KEY (a) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl WHERE b < 5),
|
||||
tbl2(a,b) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl2 WHERE b < 5)
|
||||
SELECT *
|
||||
FROM tbl
|
||||
----
|
||||
1 5
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl(a,b) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl WHERE b < 5),
|
||||
tbl2(a,b) USING KEY (a) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl2 WHERE b < 5)
|
||||
SELECT *
|
||||
FROM tbl2
|
||||
----
|
||||
1 5
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl(a,b) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl WHERE b < 5),
|
||||
tbl2(a,b) USING KEY (a) AS (SELECT 1, 1 UNION SELECT a, b+1 FROM tbl2 WHERE b < 5)
|
||||
SELECT *
|
||||
FROM tbl
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
1 4
|
||||
1 5
|
||||
|
||||
query III
|
||||
WITH RECURSIVE tbl(a, b, c) USING KEY (a) AS ((SELECT [], 1, 3 UNION SELECT [1], 2, 4) UNION SELECT a || [b], b + 1, c FROM tbl WHERE b < 5) SELECT * FROM tbl ORDER BY len(a)
|
||||
----
|
||||
[] 1 3
|
||||
[1] 2 3
|
||||
[1, 2] 3 3
|
||||
[1, 2, 3] 4 3
|
||||
[1, 2, 3, 4] 5 3
|
||||
|
||||
query II
|
||||
WITH RECURSIVE tbl(a, b) USING KEY (a) AS (SELECT 'string', 1 UNION SELECT a, b + 1 FROM tbl WHERE b < 5) SELECT * FROM tbl
|
||||
----
|
||||
string 5
|
||||
|
||||
query III
|
||||
select *
|
||||
from range(1, 4) as _(l),
|
||||
lateral (
|
||||
with recursive cte(a, b) using key (a) as (
|
||||
select 1, 0
|
||||
union
|
||||
select a, b + 1
|
||||
from recurring.cte
|
||||
where b < l
|
||||
)
|
||||
table cte
|
||||
) ORDER BY l
|
||||
----
|
||||
1 1 1
|
||||
2 1 2
|
||||
3 1 3
|
||||
120
external/duckdb/test/sql/cte/recursive_hang_2745.test
vendored
Normal file
120
external/duckdb/test/sql/cte/recursive_hang_2745.test
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
# name: test/sql/cte/recursive_hang_2745.test
|
||||
# description: Issue #2745: sql with RECURSIVE keyword but does not RECURSIVE hang
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
query III
|
||||
with RECURSIVE parents_tab (id , value , parent )
|
||||
as (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents_tab2(id , value , parent )
|
||||
as (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents as (
|
||||
select * from parents_tab
|
||||
union all
|
||||
select id, value+2, parent from parents_tab2
|
||||
)
|
||||
select * from parents order by id, value, parent;
|
||||
----
|
||||
1 1 2
|
||||
1 3 2
|
||||
2 2 4
|
||||
2 4 4
|
||||
3 1 4
|
||||
3 3 4
|
||||
4 2 -1
|
||||
4 4 -1
|
||||
5 1 2
|
||||
5 3 2
|
||||
6 2 7
|
||||
6 4 7
|
||||
7 1 -1
|
||||
7 3 -1
|
||||
|
||||
query III
|
||||
with RECURSIVE parents_tab (id , value , parent )
|
||||
as (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents_tab2(id , value , parent )
|
||||
as (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
)
|
||||
select * from parents_tab
|
||||
union all
|
||||
select id, value+2, parent from parents_tab2 ORDER BY id, value, parent;
|
||||
----
|
||||
1 1 2
|
||||
1 3 2
|
||||
2 2 4
|
||||
2 4 4
|
||||
3 1 4
|
||||
3 3 4
|
||||
4 2 -1
|
||||
4 4 -1
|
||||
5 1 2
|
||||
5 3 2
|
||||
6 2 7
|
||||
6 4 7
|
||||
7 1 -1
|
||||
7 3 -1
|
||||
|
||||
query III
|
||||
with parents_tab (id , value , parent )
|
||||
as (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents_tab2(id , value , parent )
|
||||
as (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents as (
|
||||
select * from parents_tab
|
||||
union all
|
||||
select id, value+2, parent from parents_tab2
|
||||
)
|
||||
select * from parents ORDER BY id, value, parent;
|
||||
----
|
||||
1 1 2
|
||||
1 3 2
|
||||
2 2 4
|
||||
2 4 4
|
||||
3 1 4
|
||||
3 3 4
|
||||
4 2 -1
|
||||
4 4 -1
|
||||
5 1 2
|
||||
5 3 2
|
||||
6 2 7
|
||||
6 4 7
|
||||
7 1 -1
|
||||
7 3 -1
|
||||
|
||||
statement ok
|
||||
create view vparents as
|
||||
with RECURSIVE parents_tab (id , value , parent )
|
||||
as (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
),
|
||||
parents_tab2(id , value , parent )
|
||||
as (values (1, 1, 2), (2, 2, 4), (3, 1, 4), (4, 2, -1), (5, 1, 2), (6, 2, 7), (7, 1, -1)
|
||||
)
|
||||
select * from parents_tab
|
||||
union all
|
||||
select id, value+2, parent from parents_tab2;
|
||||
|
||||
query III rowsort
|
||||
select * from vparents;
|
||||
----
|
||||
1 1 2
|
||||
1 3 2
|
||||
2 2 4
|
||||
2 4 4
|
||||
3 1 4
|
||||
3 3 4
|
||||
4 2 -1
|
||||
4 4 -1
|
||||
5 1 2
|
||||
5 3 2
|
||||
6 2 7
|
||||
6 4 7
|
||||
7 1 -1
|
||||
7 3 -1
|
||||
11
external/duckdb/test/sql/cte/test_bug_922.test
vendored
Normal file
11
external/duckdb/test/sql/cte/test_bug_922.test
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# name: test/sql/cte/test_bug_922.test
|
||||
# description: Test for a crash reported in issue #922
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
query I
|
||||
WITH my_list(value) AS (VALUES (1), (2), (3))
|
||||
SELECT * FROM my_list LIMIT 0 OFFSET 1
|
||||
----
|
||||
432
external/duckdb/test/sql/cte/test_correlated_recursive_cte.test_slow
vendored
Normal file
432
external/duckdb/test/sql/cte/test_correlated_recursive_cte.test_slow
vendored
Normal file
@@ -0,0 +1,432 @@
|
||||
# name: test/sql/cte/test_correlated_recursive_cte.test_slow
|
||||
# description: Test Correlated Recursive Common Table Expressions (CTE)
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# Correlation in the initialization query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS (
|
||||
SELECT _.x
|
||||
UNION ALL
|
||||
SELECT y + 1
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 2
|
||||
2 3
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Correlation in the recursive query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS (
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT y + _.x
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 1
|
||||
2 3
|
||||
3 1
|
||||
3 4
|
||||
4 1
|
||||
4 5
|
||||
|
||||
# Correlation in the initialization and recursive query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS (
|
||||
SELECT _.x
|
||||
UNION ALL
|
||||
SELECT y + _.x
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 2
|
||||
2 4
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Correlation with multiple recursive anchors
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS (
|
||||
SELECT _.x
|
||||
UNION ALL
|
||||
SELECT t1.y + t2.y + _.x
|
||||
FROM t AS t1, t AS t2
|
||||
WHERE t1.y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 3
|
||||
2 2
|
||||
2 6
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Test correlation in SELECT clause
|
||||
query III rowsort
|
||||
SELECT x, y, (WITH RECURSIVE t(z) AS (
|
||||
SELECT x + y
|
||||
UNION ALL
|
||||
SELECT z + 1
|
||||
FROM t
|
||||
WHERE z < 3
|
||||
) SELECT sum(z) FROM t) AS z
|
||||
FROM generate_series(1,2) AS _(x), generate_series(1,2) AS __(y) order by all;
|
||||
----
|
||||
1 1 5
|
||||
1 2 3
|
||||
2 1 3
|
||||
2 2 4
|
||||
|
||||
|
||||
# Complex nested recursive query
|
||||
query III rowsort
|
||||
SELECT x, y, (WITH RECURSIVE t(z) AS (
|
||||
SELECT x + y
|
||||
UNION ALL
|
||||
SELECT z + 1
|
||||
FROM (WITH RECURSIVE g(a) AS (
|
||||
SELECT t.z
|
||||
FROM t
|
||||
UNION ALL
|
||||
SELECT g.a + (x + y) / 2
|
||||
FROM g
|
||||
WHERE g.a < 3)
|
||||
SELECT * FROM g) AS t(z)
|
||||
WHERE z < 5
|
||||
) SELECT sum(z) FROM t) AS z
|
||||
FROM generate_series(1,2) AS _(x), generate_series(1,2) AS __(y) order by all;
|
||||
----
|
||||
1 1 23
|
||||
1 2 12
|
||||
2 1 12
|
||||
2 2 9
|
||||
|
||||
statement ok
|
||||
CREATE TABLE a AS SELECT * FROM range(100) t1(i);
|
||||
|
||||
query I
|
||||
SELECT t2.*
|
||||
FROM (VALUES (1000000)) t(_corr), LATERAL (
|
||||
WITH RECURSIVE t AS
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT SUM(x) AS x
|
||||
FROM t, a
|
||||
WHERE x < _corr
|
||||
)
|
||||
SELECT * FROM t) t2
|
||||
ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
100
|
||||
10000
|
||||
1000000
|
||||
NULL
|
||||
|
||||
query I
|
||||
SELECT t2.*
|
||||
FROM (VALUES (10)) t(_corr), LATERAL (
|
||||
WITH RECURSIVE t AS
|
||||
(
|
||||
SELECT 1 AS x
|
||||
UNION
|
||||
SELECT (SELECT t.x+t2.x FROM t t2 LIMIT 1) AS x
|
||||
FROM t
|
||||
WHERE x < _corr
|
||||
)
|
||||
SELECT * FROM t) t2
|
||||
ORDER BY 1 NULLS LAST;
|
||||
----
|
||||
1
|
||||
2
|
||||
4
|
||||
8
|
||||
16
|
||||
|
||||
query III
|
||||
SELECT t2.*
|
||||
FROM (VALUES (1)) t(_corr), LATERAL (
|
||||
WITH RECURSIVE collatz(x, t, steps) AS
|
||||
(
|
||||
SELECT x, x, 0
|
||||
FROM (WITH RECURSIVE n(t) AS (SELECT _corr UNION ALL SELECT t+_corr FROM n WHERE t < 10) SELECT * FROM n) AS _(x)
|
||||
UNION ALL
|
||||
(SELECT x, CASE WHEN t%2 = _corr THEN t * 3 + p ELSE t / 2 END, steps + p
|
||||
FROM collatz, (WITH RECURSIVE n(t) AS (SELECT _corr UNION ALL SELECT t+_corr FROM n WHERE t < _corr) SELECT * FROM n) AS _(p)
|
||||
WHERE t <> _corr)
|
||||
)
|
||||
SELECT * FROM collatz WHERE t = _corr
|
||||
) t2
|
||||
ORDER BY x;
|
||||
----
|
||||
1 1 0
|
||||
2 1 1
|
||||
3 1 7
|
||||
4 1 2
|
||||
5 1 5
|
||||
6 1 8
|
||||
7 1 16
|
||||
8 1 3
|
||||
9 1 19
|
||||
10 1 6
|
||||
|
||||
# UNION semantics
|
||||
|
||||
# Correlation in the initialization query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS (
|
||||
SELECT _.x
|
||||
UNION
|
||||
SELECT y + 1
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 2
|
||||
2 3
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Correlation in the recursive query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS (
|
||||
SELECT 1
|
||||
UNION
|
||||
SELECT y + _.x
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 1
|
||||
2 3
|
||||
3 1
|
||||
3 4
|
||||
4 1
|
||||
4 5
|
||||
|
||||
# Correlation in the initialization and recursive query
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS (
|
||||
SELECT _.x
|
||||
UNION
|
||||
SELECT y + _.x
|
||||
FROM t
|
||||
WHERE y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 2
|
||||
1 3
|
||||
2 2
|
||||
2 4
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Correlation with multiple recursive anchors
|
||||
query II
|
||||
SELECT x, y
|
||||
FROM generate_series(1,4) AS _(x), LATERAL
|
||||
(WITH RECURSIVE t(y) AS (
|
||||
SELECT _.x
|
||||
UNION
|
||||
SELECT t1.y + t2.y + _.x
|
||||
FROM t AS t1, t AS t2
|
||||
WHERE t1.y < 3
|
||||
)
|
||||
SELECT * FROM t) AS t
|
||||
ORDER BY x, y;
|
||||
----
|
||||
1 1
|
||||
1 3
|
||||
2 2
|
||||
2 6
|
||||
3 3
|
||||
4 4
|
||||
|
||||
# Test correlation in SELECT clause
|
||||
query III rowsort
|
||||
SELECT x, y, (WITH RECURSIVE t(z) AS (
|
||||
SELECT x + y
|
||||
UNION
|
||||
SELECT z + 1
|
||||
FROM t
|
||||
WHERE z < 3
|
||||
) SELECT sum(z) FROM t) AS z
|
||||
FROM generate_series(1,2) AS _(x), generate_series(1,2) AS __(y) order by all;
|
||||
----
|
||||
1 1 5
|
||||
1 2 3
|
||||
2 1 3
|
||||
2 2 4
|
||||
|
||||
# Complex nested recursive query
|
||||
query III rowsort
|
||||
SELECT x, y, (WITH RECURSIVE t(z) AS (
|
||||
SELECT x + y
|
||||
UNION
|
||||
SELECT z + 1
|
||||
FROM (WITH RECURSIVE g(a) AS (
|
||||
SELECT t.z
|
||||
FROM t
|
||||
UNION
|
||||
SELECT g.a + (x + y) / 2
|
||||
FROM g
|
||||
WHERE g.a < 3)
|
||||
SELECT * FROM g) AS t(z)
|
||||
WHERE z < 5
|
||||
) SELECT sum(z) FROM t) AS z
|
||||
FROM generate_series(1,2) AS _(x), generate_series(1,2) AS __(y) order by all;
|
||||
----
|
||||
1 1 14
|
||||
1 2 12
|
||||
2 1 12
|
||||
2 2 9
|
||||
|
||||
# Deep subquery nesting
|
||||
query III
|
||||
SELECT *
|
||||
FROM generate_series(1,3) AS "input"("n"),
|
||||
LATERAL
|
||||
(WITH RECURSIVE "subquery1"("x") AS (
|
||||
(SELECT "n", true AS "exists")
|
||||
UNION ALL
|
||||
(WITH "subquery" AS (SELECT * FROM "subquery1")
|
||||
SELECT "x" - 1, (SELECT NOT EXISTS (SELECT 1 FROM "subquery" AS "input"("a") WHERE "a" > _."x"))
|
||||
FROM "subquery" AS _("x") WHERE "x" > 0)
|
||||
) table "subquery1")
|
||||
ORDER BY "n", "x";
|
||||
----
|
||||
1 0 true
|
||||
1 1 true
|
||||
2 0 true
|
||||
2 1 true
|
||||
2 2 true
|
||||
3 0 true
|
||||
3 1 true
|
||||
3 2 true
|
||||
3 3 true
|
||||
|
||||
query III
|
||||
SELECT *
|
||||
FROM generate_series(1,3) AS "input"("n"),
|
||||
LATERAL
|
||||
(WITH RECURSIVE "subquery"("x") AS (
|
||||
(SELECT "n", true AS "exists")
|
||||
UNION ALL
|
||||
SELECT "x" - 1, y
|
||||
FROM "subquery" AS _("x"), LATERAL (SELECT NOT EXISTS (SELECT 1 FROM "subquery" AS "input"("a") WHERE "a" > _."x")) AS __(y)
|
||||
WHERE "x" > 0
|
||||
) table "subquery")
|
||||
ORDER BY "n", "x"
|
||||
;
|
||||
----
|
||||
1 0 true
|
||||
1 1 true
|
||||
2 0 true
|
||||
2 1 true
|
||||
2 2 true
|
||||
3 0 true
|
||||
3 1 true
|
||||
3 2 true
|
||||
3 3 true
|
||||
|
||||
query III
|
||||
SELECT *
|
||||
FROM generate_series(1,3) AS "input"("n"),
|
||||
LATERAL
|
||||
(WITH RECURSIVE "subquery"("x") AS (
|
||||
(SELECT "n", true AS "exists")
|
||||
UNION ALL
|
||||
SELECT "x" - 1, y
|
||||
FROM "subquery" AS _("x"), LATERAL (SELECT (SELECT (SELECT NOT EXISTS (SELECT 1 FROM "subquery" AS "input"("a") WHERE "a" > _."x")))) AS __(y)
|
||||
WHERE "x" > 0
|
||||
) table "subquery")
|
||||
ORDER BY "n", "x"
|
||||
;
|
||||
----
|
||||
1 0 true
|
||||
1 1 true
|
||||
2 0 true
|
||||
2 1 true
|
||||
2 2 true
|
||||
3 0 true
|
||||
3 1 true
|
||||
3 2 true
|
||||
3 3 true
|
||||
|
||||
query III
|
||||
SELECT *
|
||||
FROM generate_series(1,3) AS "input"("n"),
|
||||
LATERAL
|
||||
(WITH RECURSIVE "subquery"("x", "exists") AS (
|
||||
(SELECT "n", true AS "exists")
|
||||
UNION ALL
|
||||
SELECT "a" - 1, (SELECT NOT bool_or("input"."x1" > _."a") FROM "subquery" AS "input"("x1"))
|
||||
FROM "subquery" AS _("a")
|
||||
WHERE "a" > 0
|
||||
)
|
||||
table "subquery")
|
||||
ORDER BY "n", "x"
|
||||
;
|
||||
----
|
||||
1 0 true
|
||||
1 1 true
|
||||
2 0 true
|
||||
2 1 true
|
||||
2 2 true
|
||||
3 0 true
|
||||
3 1 true
|
||||
3 2 true
|
||||
3 3 true
|
||||
234
external/duckdb/test/sql/cte/test_cte.test
vendored
Normal file
234
external/duckdb/test/sql/cte/test_cte.test
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
# 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
|
||||
64
external/duckdb/test/sql/cte/test_cte_in_cte.test
vendored
Normal file
64
external/duckdb/test/sql/cte/test_cte_in_cte.test
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
# name: test/sql/cte/test_cte_in_cte.test
|
||||
# description: Test Nested 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 (with b as (Select i as j from a) Select j from b) select x from cte1 t1(x);
|
||||
----
|
||||
42
|
||||
|
||||
query I
|
||||
with cte1(xxx) as (with ncte(yyy) as (Select i as j from a) Select yyy from ncte) select xxx from cte1;
|
||||
----
|
||||
42
|
||||
|
||||
query II
|
||||
with cte1 as (with b as (Select i as j from a) select j from b), cte2 as (with c as (select ref.j+1 as k from cte1 as ref) select k from c) select * from cte1 , cte2;
|
||||
----
|
||||
42 43
|
||||
|
||||
# duplicate CTE alias
|
||||
statement error
|
||||
with cte1 as (select 42), cte1 as (select 42) select * FROM cte1;
|
||||
----
|
||||
<REGEX>:.*Parser Error: Duplicate CTE name.*
|
||||
|
||||
# refer to CTE in subquery tableref
|
||||
query I
|
||||
with cte1 as (Select i as j from a) select * from (with cte2 as (select max(j) as j from cte1) select * from cte2) f
|
||||
----
|
||||
42
|
||||
|
||||
# refer to CTE in subquery expression
|
||||
query I
|
||||
with cte1 as (Select i as j from a) select * from cte1 where j = (with cte2 as (select max(j) as j from cte1) select j from cte2);
|
||||
----
|
||||
42
|
||||
|
||||
require no_alternative_verify
|
||||
|
||||
# refer to same-named CTE in a subquery expression
|
||||
query I
|
||||
with cte as (Select i as j from a) select * from cte where j = (with cte as (select max(j) as j from cte) select j from cte);
|
||||
----
|
||||
42
|
||||
|
||||
# self-refer to non-existent cte
|
||||
statement error
|
||||
with cte as (select * from cte) select * from cte
|
||||
----
|
||||
<REGEX>:.*Binder Error.*Circular reference to CTE.*
|
||||
17
external/duckdb/test/sql/cte/test_cte_overflow.test
vendored
Normal file
17
external/duckdb/test/sql/cte/test_cte_overflow.test
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# name: test/sql/cte/test_cte_overflow.test
|
||||
# description: Ensure no stack overflow for CTE names that match existing tables
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
create table a (id integer)
|
||||
|
||||
statement ok
|
||||
insert into a values (1729)
|
||||
|
||||
statement ok
|
||||
create view va as (with v as (select * from a) select * from v)
|
||||
|
||||
query I
|
||||
with a as (select * from va) select * from a
|
||||
----
|
||||
1729
|
||||
230
external/duckdb/test/sql/cte/test_fib_complex.test_slow
vendored
Normal file
230
external/duckdb/test/sql/cte/test_fib_complex.test_slow
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
# name: test/sql/cte/test_fib_complex.test_slow
|
||||
# description: Very complex recursive CTE with several corner cases
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification;
|
||||
|
||||
query IIIIIIIII
|
||||
SELECT "input".*,
|
||||
"result".*
|
||||
FROM (SELECT i FROM generate_series(2,3) AS _(i)) AS "input"("n"),
|
||||
LATERAL (WITH RECURSIVE
|
||||
"loop"(".iteration", ".mark", ".thread.this", ".label.this", ".thread.parent", ".label.parent", "fib.n", "fib.result.0") AS (
|
||||
(SELECT CAST((0) AS INT) AS ".iteration",
|
||||
CAST((0) AS INT) AS ".mark",
|
||||
CAST((0) AS INT) AS ".thread.this",
|
||||
'fib' AS ".label.this",
|
||||
CAST((NULL) AS INT) AS ".thread.parent",
|
||||
CAST((NULL) AS TEXT) AS ".label.parent",
|
||||
CAST(("input"."n") AS int) AS "fib.n",
|
||||
CAST((NULL) AS int) AS "fib.result.0"
|
||||
)
|
||||
UNION ALL
|
||||
(WITH
|
||||
"fib.assignment.1"(".iteration", ".mark", ".thread.this", ".label.parent", "k", "n") AS (
|
||||
SELECT "input".".iteration",
|
||||
"input".".mark",
|
||||
"input".".thread.this",
|
||||
"input".".label.parent",
|
||||
CAST(("input"."fib.n" <= 1) AS bool) AS "k",
|
||||
"input"."fib.n"
|
||||
FROM "loop" AS "input"
|
||||
WHERE "input".".label.this" IS NOT DISTINCT FROM 'fib'
|
||||
),
|
||||
"fib.call.1.prepare"(".iteration", ".mark", ".thread.this", ".label.this", ".thread.parent", ".label.parent", "argument.0") AS (
|
||||
SELECT "input".".iteration",
|
||||
"input".".mark",
|
||||
(SELECT COALESCE(MAX("loop".".thread.this"), 0)
|
||||
FROM "loop"
|
||||
WHERE ("loop".".label.parent" IS NOT DISTINCT FROM "input".".label.parent" OR
|
||||
"loop".".label.this" IS NOT DISTINCT FROM 'fib.call.1')) + ROW_NUMBER() OVER (ORDER BY "fork"."n" DESC) AS ".thread.this",
|
||||
'fib.call.1' AS ".label.this",
|
||||
"input".".thread.this" AS ".thread.parent",
|
||||
"input".".label.parent",
|
||||
CAST(("fork"."n") AS int) AS "argument.0"
|
||||
FROM "loop" AS "input",
|
||||
LATERAL (SELECT "input"."fib.n" - i FROM generate_series(1,2) AS _(i)) AS "fork"("n")
|
||||
WHERE "input".".label.this" IS NOT DISTINCT FROM 'fib.mark.1'
|
||||
),
|
||||
"fib.wait.1.decide"(".iteration", ".mark", ".thread.this", ".label.parent", ".done", "n") AS (
|
||||
SELECT "input".".iteration",
|
||||
MIN("input".".mark") OVER (
|
||||
PARTITION BY "input".".iteration",
|
||||
"input".".thread.this"
|
||||
ROWS BETWEEN UNBOUNDED PRECEDING
|
||||
AND UNBOUNDED FOLLOWING
|
||||
) AS ".mark",
|
||||
"input".".thread.this",
|
||||
"input".".label.parent",
|
||||
NOT EXISTS(SELECT 1 AS "dummy"
|
||||
FROM "loop"
|
||||
WHERE "loop".".mark" > "input".".mark"
|
||||
AND ("loop".".thread.this" IS NOT DISTINCT FROM "input".".thread.this" OR
|
||||
"loop".".thread.parent" IS NOT DISTINCT FROM "input".".thread.this"))
|
||||
AS ".done",
|
||||
"input"."n"
|
||||
FROM ((SELECT "input".".iteration",
|
||||
"input".".mark" - 1 AS ".mark",
|
||||
"input".".thread.parent",
|
||||
"input".".label.parent",
|
||||
"return"."fib.result.0"
|
||||
FROM "loop" AS "input", "loop" AS "return"
|
||||
WHERE "input".".label.this" IS NOT DISTINCT FROM 'fib.call.1'
|
||||
AND "return".".label.this" IS NULL
|
||||
AND "return".".label.parent" IS NOT DISTINCT FROM 'fib.call.1'
|
||||
AND "return".".thread.this" IS NOT DISTINCT FROM "input".".thread.this")
|
||||
UNION ALL
|
||||
(SELECT "input".".iteration",
|
||||
"input".".mark",
|
||||
"input".".thread.this",
|
||||
"input".".label.parent",
|
||||
"input"."fib.n"
|
||||
FROM "loop" AS "input"
|
||||
WHERE "input".".label.this" IS NOT DISTINCT FROM 'fib.wait.1')) AS "input"(".iteration", ".mark", ".thread.this", ".label.parent", "n")
|
||||
)
|
||||
(SELECT "input".".iteration" + 1,
|
||||
"input".".mark" + 1,
|
||||
"input".".thread.this",
|
||||
'fib.mark.1' AS ".label.this",
|
||||
CAST((NULL) AS int),
|
||||
"input".".label.parent",
|
||||
"input"."n" AS "fib.n",
|
||||
CAST((NULL) AS int) AS "fib.result.0"
|
||||
FROM "fib.assignment.1" AS "input"
|
||||
WHERE NOT "input"."k")
|
||||
UNION ALL
|
||||
(SELECT "sink".".iteration" + 1,
|
||||
"sink".".mark",
|
||||
"sink".".thread.this",
|
||||
"sink".".label.this",
|
||||
"sink".".thread.parent",
|
||||
"sink".".label.parent",
|
||||
CAST((NULL) AS int) AS "fib.n",
|
||||
CAST((NULL) AS int) AS "fib.result.0"
|
||||
FROM "fib.call.1.prepare" AS "sink")
|
||||
UNION ALL
|
||||
(SELECT "input".".iteration" + 1,
|
||||
"input".".mark",
|
||||
"input".".thread.this",
|
||||
"input".".label.this",
|
||||
"input".".thread.parent",
|
||||
"input".".label.parent",
|
||||
CAST((NULL) AS int) AS "fib.n",
|
||||
CAST((NULL) AS int) AS "fib.result.0"
|
||||
FROM "loop" AS "input"
|
||||
WHERE "input".".label.this" IS NOT DISTINCT FROM 'fib.call.1'
|
||||
AND EXISTS(SELECT 1 AS "dummy"
|
||||
FROM "loop"
|
||||
WHERE "loop".".label.this" IS NOT NULL
|
||||
AND "loop".".label.parent" IS NOT DISTINCT FROM 'fib.call.1'
|
||||
AND ("loop".".thread.this" IS NOT DISTINCT FROM "input".".thread.this" AND
|
||||
"loop".".thread.parent" IS NULL OR
|
||||
"loop".".thread.parent" IS NOT DISTINCT FROM "input".".thread.this")))
|
||||
UNION ALL
|
||||
(SELECT "input".".iteration" + 1,
|
||||
"input".".mark",
|
||||
"input".".thread.this",
|
||||
'fib.wait.1' AS ".label.this",
|
||||
CAST((NULL) AS int),
|
||||
"input".".label.parent",
|
||||
"input"."n" AS "fib.n",
|
||||
CAST((NULL) AS int) AS "fib.result.0"
|
||||
FROM "fib.wait.1.decide" AS "input"
|
||||
WHERE NOT "input".".done")
|
||||
UNION ALL
|
||||
(SELECT "input".".iteration" + 1,
|
||||
"input".".mark",
|
||||
"input".".thread.this",
|
||||
CAST((NULL) AS TEXT) AS ".label.this",
|
||||
CAST((NULL) AS INT) AS ".thread.parent",
|
||||
"input".".label.parent",
|
||||
CAST((NULL) AS int) AS "fib.n",
|
||||
CAST(("input"."n") AS int)
|
||||
FROM "fib.assignment.1" AS "input"
|
||||
WHERE "input"."k")
|
||||
UNION ALL
|
||||
(SELECT "key".".iteration" + 1,
|
||||
"key".".mark",
|
||||
"key".".thread.this",
|
||||
CAST((NULL) AS TEXT) AS ".label.this",
|
||||
CAST((NULL) AS INT) AS ".thread.parent",
|
||||
"key".".label.parent",
|
||||
CAST((NULL) AS int) AS "fib.n",
|
||||
CAST(("aggregate"."n") AS int)
|
||||
FROM (SELECT MIN("key".".mark") AS ".mark",
|
||||
"key".".iteration",
|
||||
"key".".thread.this",
|
||||
"key".".label.parent"
|
||||
FROM "fib.wait.1.decide" AS "key"
|
||||
WHERE "key".".done"
|
||||
GROUP BY "key".".iteration",
|
||||
"key".".thread.this",
|
||||
"key".".label.parent"
|
||||
) AS "key"(".mark", ".iteration", ".thread.this", ".label.parent"),
|
||||
LATERAL (SELECT SUM(CAST(("input"."n") AS INT))
|
||||
FROM "fib.wait.1.decide" AS "input"
|
||||
WHERE "input".".done"
|
||||
AND "key".".iteration" IS NOT DISTINCT FROM "input".".iteration"
|
||||
AND "key".".thread.this" IS NOT DISTINCT FROM "input".".thread.this"
|
||||
AND "key".".label.parent" IS NOT DISTINCT FROM "input".".label.parent") AS "aggregate"("n")
|
||||
WHERE "key".".mark" IS NOT NULL)
|
||||
UNION ALL
|
||||
(SELECT "input".".iteration" + 1,
|
||||
"input".".mark",
|
||||
"input".".thread.this",
|
||||
'fib' AS ".label.this",
|
||||
"input".".thread.this" AS ".thread.parent",
|
||||
'fib.call.1' AS ".label.parent",
|
||||
"input"."argument.0" AS "fib.n",
|
||||
CAST((NULL) AS int) AS "fib.result.0"
|
||||
FROM "fib.call.1.prepare" AS "input"))
|
||||
)
|
||||
TABLE loop) AS "result"
|
||||
ORDER BY ALL
|
||||
----
|
||||
2 0 0 0 fib NULL NULL 2 NULL
|
||||
2 1 1 0 fib.mark.1 NULL NULL 2 NULL
|
||||
2 2 1 1 fib 1 fib.call.1 1 NULL
|
||||
2 2 1 1 fib.call.1 0 NULL NULL NULL
|
||||
2 2 1 2 fib 2 fib.call.1 0 NULL
|
||||
2 2 1 2 fib.call.1 0 NULL NULL NULL
|
||||
2 3 1 1 fib.call.1 0 NULL NULL NULL
|
||||
2 3 1 1 NULL NULL fib.call.1 NULL 1
|
||||
2 3 1 2 fib.call.1 0 NULL NULL NULL
|
||||
2 3 1 2 NULL NULL fib.call.1 NULL 0
|
||||
2 4 0 0 fib.wait.1 NULL NULL 0 NULL
|
||||
2 4 0 0 fib.wait.1 NULL NULL 1 NULL
|
||||
2 5 0 0 NULL NULL NULL NULL 1
|
||||
3 0 0 0 fib NULL NULL 3 NULL
|
||||
3 1 1 0 fib.mark.1 NULL NULL 3 NULL
|
||||
3 2 1 1 fib 1 fib.call.1 2 NULL
|
||||
3 2 1 1 fib.call.1 0 NULL NULL NULL
|
||||
3 2 1 2 fib 2 fib.call.1 1 NULL
|
||||
3 2 1 2 fib.call.1 0 NULL NULL NULL
|
||||
3 3 1 1 fib.call.1 0 NULL NULL NULL
|
||||
3 3 1 2 fib.call.1 0 NULL NULL NULL
|
||||
3 3 1 2 NULL NULL fib.call.1 NULL 1
|
||||
3 3 2 1 fib.mark.1 NULL fib.call.1 2 NULL
|
||||
3 4 0 0 fib.wait.1 NULL NULL 1 NULL
|
||||
3 4 1 1 fib.call.1 0 NULL NULL NULL
|
||||
3 4 2 3 fib 3 fib.call.1 1 NULL
|
||||
3 4 2 3 fib.call.1 1 fib.call.1 NULL NULL
|
||||
3 4 2 4 fib 4 fib.call.1 0 NULL
|
||||
3 4 2 4 fib.call.1 1 fib.call.1 NULL NULL
|
||||
3 5 0 0 fib.wait.1 NULL NULL 1 NULL
|
||||
3 5 1 1 fib.call.1 0 NULL NULL NULL
|
||||
3 5 2 3 fib.call.1 1 fib.call.1 NULL NULL
|
||||
3 5 2 3 NULL NULL fib.call.1 NULL 1
|
||||
3 5 2 4 fib.call.1 1 fib.call.1 NULL NULL
|
||||
3 5 2 4 NULL NULL fib.call.1 NULL 0
|
||||
3 6 0 0 fib.wait.1 NULL NULL 1 NULL
|
||||
3 6 1 1 fib.call.1 0 NULL NULL NULL
|
||||
3 6 1 1 fib.wait.1 NULL fib.call.1 0 NULL
|
||||
3 6 1 1 fib.wait.1 NULL fib.call.1 1 NULL
|
||||
3 7 0 0 fib.wait.1 NULL NULL 1 NULL
|
||||
3 7 1 1 fib.call.1 0 NULL NULL NULL
|
||||
3 7 1 1 NULL NULL fib.call.1 NULL 1
|
||||
3 8 0 0 fib.wait.1 NULL NULL 1 NULL
|
||||
3 8 0 0 fib.wait.1 NULL NULL 1 NULL
|
||||
3 9 0 0 NULL NULL NULL NULL 2
|
||||
2010
external/duckdb/test/sql/cte/test_giant_union_all.test_slow
vendored
Normal file
2010
external/duckdb/test/sql/cte/test_giant_union_all.test_slow
vendored
Normal file
File diff suppressed because it is too large
Load Diff
32
external/duckdb/test/sql/cte/test_issue_5673.test
vendored
Normal file
32
external/duckdb/test/sql/cte/test_issue_5673.test
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# name: test/sql/cte/test_issue_5673.test
|
||||
# description: Issue #5673 and #4987: CTE and Table name are name shadowing
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
create or replace table orders(ordered_at int);
|
||||
|
||||
statement ok
|
||||
create or replace table stg_orders(ordered_at int);
|
||||
|
||||
statement ok
|
||||
insert into orders values (1);
|
||||
|
||||
statement ok
|
||||
insert into stg_orders values (1);
|
||||
|
||||
query I
|
||||
with
|
||||
orders as (
|
||||
select * from main.stg_orders
|
||||
where ordered_at >= (select max(ordered_at) from main.orders)
|
||||
),
|
||||
some_more_logic as (
|
||||
select *
|
||||
from orders
|
||||
)
|
||||
select * from some_more_logic;
|
||||
----
|
||||
1
|
||||
110
external/duckdb/test/sql/cte/test_moderate_union_all.test
vendored
Normal file
110
external/duckdb/test/sql/cte/test_moderate_union_all.test
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
# name: test/sql/cte/test_moderate_union_all.test
|
||||
# description: Test moderate chain of UNION ALL statements
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
CREATE VIEW union_view AS
|
||||
SELECT 0 i
|
||||
UNION ALL
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT 2
|
||||
UNION ALL
|
||||
SELECT 3
|
||||
UNION ALL
|
||||
SELECT 4
|
||||
UNION ALL
|
||||
SELECT 5
|
||||
UNION ALL
|
||||
SELECT 6
|
||||
UNION ALL
|
||||
SELECT 7
|
||||
UNION ALL
|
||||
SELECT 8
|
||||
UNION ALL
|
||||
SELECT 9
|
||||
UNION ALL
|
||||
SELECT 10
|
||||
UNION ALL
|
||||
SELECT 11
|
||||
UNION ALL
|
||||
SELECT 12
|
||||
UNION ALL
|
||||
SELECT 13
|
||||
UNION ALL
|
||||
SELECT 14
|
||||
UNION ALL
|
||||
SELECT 15
|
||||
UNION ALL
|
||||
SELECT 16
|
||||
UNION ALL
|
||||
SELECT 17
|
||||
UNION ALL
|
||||
SELECT 18
|
||||
UNION ALL
|
||||
SELECT 19
|
||||
UNION ALL
|
||||
SELECT 20
|
||||
UNION ALL
|
||||
SELECT 21
|
||||
UNION ALL
|
||||
SELECT 22
|
||||
UNION ALL
|
||||
SELECT 23
|
||||
UNION ALL
|
||||
SELECT 24
|
||||
UNION ALL
|
||||
SELECT 25
|
||||
UNION ALL
|
||||
SELECT 26
|
||||
UNION ALL
|
||||
SELECT 27
|
||||
UNION ALL
|
||||
SELECT 28
|
||||
UNION ALL
|
||||
SELECT 29
|
||||
UNION ALL
|
||||
SELECT 30
|
||||
UNION ALL
|
||||
SELECT 31
|
||||
UNION ALL
|
||||
SELECT 32
|
||||
UNION ALL
|
||||
SELECT 33
|
||||
UNION ALL
|
||||
SELECT 34
|
||||
UNION ALL
|
||||
SELECT 35
|
||||
UNION ALL
|
||||
SELECT 36
|
||||
UNION ALL
|
||||
SELECT 37
|
||||
UNION ALL
|
||||
SELECT 38
|
||||
UNION ALL
|
||||
SELECT 39
|
||||
UNION ALL
|
||||
SELECT 40
|
||||
UNION ALL
|
||||
SELECT 41
|
||||
UNION ALL
|
||||
SELECT 42
|
||||
UNION ALL
|
||||
SELECT 43
|
||||
UNION ALL
|
||||
SELECT 44
|
||||
UNION ALL
|
||||
SELECT 45
|
||||
UNION ALL
|
||||
SELECT 46
|
||||
UNION ALL
|
||||
SELECT 47
|
||||
UNION ALL
|
||||
SELECT 48
|
||||
UNION ALL
|
||||
SELECT 49
|
||||
|
||||
query IIII
|
||||
SELECT COUNT(*), MIN(i), MAX(i), AVG(i) FROM union_view
|
||||
----
|
||||
50 0 49 24.5
|
||||
59
external/duckdb/test/sql/cte/test_nested_recursive_cte.test
vendored
Normal file
59
external/duckdb/test/sql/cte/test_nested_recursive_cte.test
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
# name: test/sql/cte/test_nested_recursive_cte.test
|
||||
# description: Test Nested Recursive Common Table Expressions (CTE)
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
query I
|
||||
WITH RECURSIVE t(x) AS
|
||||
(
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT x+1
|
||||
FROM t
|
||||
WHERE x < 4
|
||||
),
|
||||
u(x) AS
|
||||
(
|
||||
SELECT *
|
||||
FROM t
|
||||
UNION ALL
|
||||
SELECT u.x * 2 + t.x
|
||||
FROM u, t
|
||||
WHERE u.x < 32
|
||||
)
|
||||
SELECT *
|
||||
FROM u
|
||||
ORDER BY x
|
||||
LIMIT 5;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
3
|
||||
4
|
||||
|
||||
query III
|
||||
WITH RECURSIVE collatz(x, t, steps) AS
|
||||
(
|
||||
SELECT x, x, 0
|
||||
FROM (WITH RECURSIVE n(t) AS (SELECT 1 UNION ALL SELECT t+1 FROM n WHERE t < 10) SELECT * FROM n) AS _(x)
|
||||
UNION ALL
|
||||
(SELECT x, CASE WHEN t%2 = 1 THEN t * 3 + p ELSE t / 2 END, steps + p
|
||||
FROM collatz, (WITH RECURSIVE n(t) AS (SELECT 1 UNION ALL SELECT t+1 FROM n WHERE t < 1) SELECT * FROM n) AS _(p)
|
||||
WHERE t <> 1)
|
||||
)
|
||||
SELECT * FROM collatz WHERE t = 1
|
||||
ORDER BY x;
|
||||
----
|
||||
1 1 0
|
||||
2 1 1
|
||||
3 1 7
|
||||
4 1 2
|
||||
5 1 5
|
||||
6 1 8
|
||||
7 1 16
|
||||
8 1 3
|
||||
9 1 19
|
||||
10 1 6
|
||||
30
external/duckdb/test/sql/cte/test_outer_joins_recursive_cte.test
vendored
Normal file
30
external/duckdb/test/sql/cte/test_outer_joins_recursive_cte.test
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# name: test/sql/cte/test_outer_joins_recursive_cte.test
|
||||
# description: Test Recursive Common Table Expressions (CTE) with outer joins
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE v(x INT);
|
||||
|
||||
statement ok
|
||||
INSERT INTO v
|
||||
VALUES
|
||||
(1),(2),(3);
|
||||
|
||||
query II
|
||||
WITH RECURSIVE t(x) AS
|
||||
(
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT x + 1
|
||||
FROM (SELECT t.x+1 FROM v AS _(p) FULL OUTER JOIN t ON t.x = p) AS _(x)
|
||||
WHERE x < 10
|
||||
) SELECT * FROM v AS _(p) RIGHT OUTER JOIN t ON t.x = p ORDER BY p, t NULLS LAST;
|
||||
----
|
||||
1 1
|
||||
3 3
|
||||
NULL 5
|
||||
NULL 7
|
||||
NULL 9
|
||||
145
external/duckdb/test/sql/cte/test_recursive_cte_tutorial.test
vendored
Normal file
145
external/duckdb/test/sql/cte/test_recursive_cte_tutorial.test
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
# name: test/sql/cte/test_recursive_cte_tutorial.test
|
||||
# description: Test Recursive CTEs from the CyberTec tutorial: https://www.cybertec-postgresql.com/en/recursive-queries-postgresql/
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE emp (empno INTEGER PRIMARY KEY,
|
||||
ename VARCHAR,
|
||||
job VARCHAR,
|
||||
mgr INTEGER,
|
||||
hiredate DATE,
|
||||
sal DOUBLE,
|
||||
comm DOUBLE,
|
||||
deptno INTEGER);
|
||||
|
||||
statement ok
|
||||
INSERT INTO emp VALUES (7839, 'KING', 'PRESIDENT', NULL, DATE '1981-11-17', 5000.00, NULL, 10);
|
||||
INSERT INTO emp VALUES (7698, 'BLAKE', 'MANAGER', 7839, DATE '1981-05-01', 2850.00, NULL, 30);
|
||||
INSERT INTO emp VALUES (7782, 'CLARK', 'MANAGER', 7839, DATE '1981-06-09', 2450.00, NULL, 10);
|
||||
INSERT INTO emp VALUES (7566, 'JONES', 'MANAGER', 7839, DATE '1981-04-02', 2975.00, NULL, 20);
|
||||
INSERT INTO emp VALUES (7902, 'FORD', 'ANALYST', 7566, DATE '1981-12-03', 3000.00, NULL, 20);
|
||||
INSERT INTO emp VALUES (7369, 'SMITH', 'CLERK', 7902, DATE '1980-12-17', 800.00, NULL, 20);
|
||||
INSERT INTO emp VALUES (7499, 'ALLEN', 'SALESMAN', 7698, DATE '1981-02-20', 1600.00, 300.00, 30);
|
||||
INSERT INTO emp VALUES (7521, 'WARD', 'SALESMAN', 7698, DATE '1981-02-22', 1250.00, 500.00, 30);
|
||||
INSERT INTO emp VALUES (7654, 'MARTIN', 'SALESMAN', 7698, DATE '1981-09-28', 1250.00, 1400.00, 30);
|
||||
INSERT INTO emp VALUES (7844, 'TURNER', 'SALESMAN', 7698, DATE '1981-09-08', 1500.00, 0.00, 30);
|
||||
INSERT INTO emp VALUES (7900, 'JAMES', 'CLERK', 7698, DATE '1981-12-03', 950.00, NULL, 30);
|
||||
INSERT INTO emp VALUES (7934, 'MILLER', 'CLERK', 7782, DATE '1982-01-23', 1300.00, NULL, 10);
|
||||
|
||||
query II
|
||||
WITH RECURSIVE ctename AS (
|
||||
SELECT empno, ename
|
||||
FROM emp
|
||||
WHERE empno = 7566
|
||||
UNION ALL
|
||||
SELECT emp.empno, emp.ename
|
||||
FROM emp
|
||||
JOIN ctename ON emp.mgr = ctename.empno
|
||||
)
|
||||
SELECT * FROM ctename;
|
||||
----
|
||||
7566 JONES
|
||||
7902 FORD
|
||||
7369 SMITH
|
||||
|
||||
query III
|
||||
WITH RECURSIVE ctename AS (
|
||||
SELECT empno, ename,
|
||||
0 AS level
|
||||
FROM emp
|
||||
WHERE empno = 7566
|
||||
UNION ALL
|
||||
SELECT emp.empno, emp.ename,
|
||||
ctename.level + 1
|
||||
FROM emp
|
||||
JOIN ctename ON emp.mgr = ctename.empno
|
||||
)
|
||||
SELECT * FROM ctename;
|
||||
----
|
||||
7566 JONES 0
|
||||
7902 FORD 1
|
||||
7369 SMITH 2
|
||||
|
||||
query III
|
||||
WITH RECURSIVE ctename AS (
|
||||
SELECT empno, ename,
|
||||
ename AS path
|
||||
FROM emp
|
||||
WHERE empno = 7566
|
||||
UNION ALL
|
||||
SELECT emp.empno, emp.ename,
|
||||
ctename.path || ' -> ' || emp.ename
|
||||
FROM emp
|
||||
JOIN ctename ON emp.mgr = ctename.empno
|
||||
)
|
||||
SELECT * FROM ctename;
|
||||
----
|
||||
7566 JONES JONES
|
||||
7902 FORD JONES -> FORD
|
||||
7369 SMITH JONES -> FORD -> SMITH
|
||||
|
||||
statement ok
|
||||
CREATE VIEW ctenames AS (
|
||||
WITH RECURSIVE ctename AS (
|
||||
SELECT empno, ename,
|
||||
ename AS path
|
||||
FROM emp
|
||||
WHERE empno = 7566
|
||||
UNION ALL
|
||||
SELECT emp.empno, emp.ename,
|
||||
ctename.path || ' -> ' || emp.ename
|
||||
FROM emp
|
||||
JOIN ctename ON emp.mgr = ctename.empno
|
||||
)
|
||||
SELECT * FROM ctename
|
||||
);
|
||||
|
||||
query III
|
||||
SELECT * FROM ctenames;
|
||||
----
|
||||
7566 JONES JONES
|
||||
7902 FORD JONES -> FORD
|
||||
7369 SMITH JONES -> FORD -> SMITH
|
||||
|
||||
require no_alternative_verify
|
||||
|
||||
statement ok
|
||||
PRAGMA disable_verification
|
||||
|
||||
query II
|
||||
WITH RECURSIVE fib AS (
|
||||
SELECT 1 AS n,
|
||||
1::bigint AS "fibₙ",
|
||||
1::bigint AS "fibₙ₊₁"
|
||||
UNION ALL
|
||||
SELECT n+1,
|
||||
"fibₙ₊₁",
|
||||
"fibₙ" + "fibₙ₊₁"
|
||||
FROM fib
|
||||
)
|
||||
SELECT n, "fibₙ" FROM fib
|
||||
LIMIT 20;
|
||||
----
|
||||
1 1
|
||||
2 1
|
||||
3 2
|
||||
4 3
|
||||
5 5
|
||||
6 8
|
||||
7 13
|
||||
8 21
|
||||
9 34
|
||||
10 55
|
||||
11 89
|
||||
12 144
|
||||
13 233
|
||||
14 377
|
||||
15 610
|
||||
16 987
|
||||
17 1597
|
||||
18 2584
|
||||
19 4181
|
||||
20 6765
|
||||
179
external/duckdb/test/sql/cte/test_recursive_cte_union.test
vendored
Normal file
179
external/duckdb/test/sql/cte/test_recursive_cte_union.test
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
# name: test/sql/cte/test_recursive_cte_union.test
|
||||
# description: Test Recursive Common Table Expressions UNION (CTE)
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# simple recursive CTE
|
||||
query I
|
||||
with recursive t as (select 1 as x union select x+1 from t where x < 3) select * from t order by x
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
query I
|
||||
with recursive t(x) as (select 1 union select x+1 from t where x < 3) select * from t order by x
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# test some aliases
|
||||
query I
|
||||
with recursive t(x) as (select 1 union select x+1 from t where x < 3) select zz from t t1(zz) order by zz
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
query I
|
||||
with recursive t(x) as (select 1 union select zzz+1 from t t1(zzz) where zzz < 3) select zz from t t1(zz) order by zz
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# UNION semantics prevents infinite loop here
|
||||
query I
|
||||
with recursive t as (select 1 as x union select x from t) select * from t
|
||||
----
|
||||
1
|
||||
|
||||
# simple recursive CTE with an alias
|
||||
query I
|
||||
with recursive t as (select 1 as x union select x+1 from t as m where m.x < 3) select * from t order by x
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# recursive CTE with multiple references and aliases
|
||||
query I
|
||||
with recursive t as (select 1 as x union select m.x+f.x from t as m, t as f where m.x < 3) select * from t order by x
|
||||
----
|
||||
1
|
||||
2
|
||||
4
|
||||
|
||||
# strings and multiple columns
|
||||
query IT
|
||||
with recursive t as (select 1 as x, 'hello' as y union select x+1, y || '-' || 'hello' from t where x < 3) select * from t order by x;
|
||||
----
|
||||
1 hello
|
||||
2 hello-hello
|
||||
3 hello-hello-hello
|
||||
|
||||
# referencing same CTE multiple times
|
||||
query I
|
||||
with recursive t as (select 1 as x union select x+1 from t where x < 3) select min(a1.x) from t a1, t a2;
|
||||
----
|
||||
1
|
||||
|
||||
# nested uncorrelated subquery
|
||||
query I
|
||||
with recursive t as (select 1 as x union select x+(SELECT 1) from t where x < 3) select * from t order by x;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# some of the following recursive queries are terminated by the LIMIT clause
|
||||
# this requires CTE inlining, which enable_verification disables
|
||||
require no_alternative_verify
|
||||
|
||||
statement ok
|
||||
PRAGMA disable_verification
|
||||
|
||||
# hash join
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select * from (select x from t where x < 5) tbl(i) join (select 1) tbl2(i) using (i)) select * from t limit 3;
|
||||
----
|
||||
1
|
||||
1
|
||||
1
|
||||
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select * from (select 1) tbl2(i) join (select x from t where x < 5) tbl(i) using (i)) select * from t limit 3;
|
||||
----
|
||||
1
|
||||
1
|
||||
1
|
||||
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select * from (select x from t where x < 5) tbl(i) join (select first(i) from (values (1)) tbl3(i) limit 1) tbl2(i) using (i)) select * from t limit 3;
|
||||
----
|
||||
1
|
||||
1
|
||||
1
|
||||
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select * from (select first(i) from (values (1)) tbl3(i) limit 1) tbl2(i) join (select x from t where x < 5) tbl(i) using (i)) select * from t limit 3;
|
||||
----
|
||||
1
|
||||
1
|
||||
1
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# correlated subquery
|
||||
query I
|
||||
with recursive t as (select 1 as x union select x+(SELECT 1+t.x) from t where x < 5) select * from t order by x;
|
||||
----
|
||||
1
|
||||
3
|
||||
7
|
||||
|
||||
# use with recursive in table creation
|
||||
statement ok
|
||||
create table integers as with recursive t as (select 1 as x union select x+1 from t where x < 3) select * from t;
|
||||
|
||||
# more complex uncorrelated subquery
|
||||
query I
|
||||
with recursive t as (select (select min(x) from integers) as x union select x+1 from t where x < 3) select * from t order by x;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# aggregate functions
|
||||
query I
|
||||
with recursive t as (select 1 as x union select sum(x+1) from t where x < 3) select * from t order by 1 nulls last
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
NULL
|
||||
|
||||
# order by is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as (select 1 as x union select sum(x+1) from t where x < 3 order by x) select * from t
|
||||
----
|
||||
|
||||
# limit is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as (select 1 as x union select sum(x+1) from t where x < 3 LIMIT 1) select * from t
|
||||
----
|
||||
|
||||
# offset is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as (select 1 as x union select sum(x+1) from t where x < 3 OFFSET 1) select * from t
|
||||
----
|
||||
|
||||
# offset is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as (select 1 as x union select sum(x+1) from t where x < 3 LIMIT 1 OFFSET 1) select * from t
|
||||
----
|
||||
|
||||
# create a view from a recursive cte
|
||||
statement ok
|
||||
create view vr as (with recursive t(x) as (select 1 union select x+1 from t where x < 3) select * from t order by x)
|
||||
|
||||
query I
|
||||
select * from vr
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
144
external/duckdb/test/sql/cte/test_recursive_cte_union_all.test
vendored
Normal file
144
external/duckdb/test/sql/cte/test_recursive_cte_union_all.test
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
# name: test/sql/cte/test_recursive_cte_union_all.test
|
||||
# description: Test Recursive Common Table Expressions UNION ALL (CTE)
|
||||
# group: [cte]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# simple recursive CTE
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select x+1 from t where x < 3) select * from t
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# simple recursive CTE with an alias
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select x+1 from t as m where m.x < 3) select * from t
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# recursive CTE with multiple references and aliases
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select m.x+f.x from t as m, t as f where m.x < 3) select * from t
|
||||
----
|
||||
1
|
||||
2
|
||||
4
|
||||
|
||||
# strings and multiple columns
|
||||
query IT
|
||||
with recursive t as (select 1 as x, 'hello' as y union all select x+1, y || '-' || 'hello' from t where x < 3) select * from t;
|
||||
----
|
||||
1 hello
|
||||
2 hello-hello
|
||||
3 hello-hello-hello
|
||||
|
||||
# referencing same CTE multiple times
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select x+1 from t where x < 3) select min(a1.x) from t a1, t a2;
|
||||
----
|
||||
1
|
||||
|
||||
# nested uncorrelated subquery
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select x+(SELECT 1) from t where x < 3) select * from t;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# use with recursive in table creation
|
||||
statement ok
|
||||
create table integers as with recursive t as (select 1 as x union all select x+1 from t where x < 3) select * from t;
|
||||
|
||||
# more complex uncorrelated subquery
|
||||
query I
|
||||
with recursive t as (select (select min(x) from integers) as x union all select x+1 from t where x < 3) select * from t;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# aggregate function
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select sum(x+1) AS x from t where x < 3 group by x) select * from t
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
|
||||
# some of the following recursive queries are terminated by the LIMIT clause
|
||||
# this requires CTE inlining, which enable_verification disables
|
||||
require no_alternative_verify
|
||||
|
||||
statement ok
|
||||
PRAGMA disable_verification
|
||||
|
||||
# infinite aggregate function: will result in timeout if pipelining is not implemented
|
||||
query I
|
||||
with recursive t as (select 1 as x union all select sum(x+1) AS x from t where x < 3)
|
||||
select * from (select * from t limit 10) t1(x) order by x nulls last
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
# recursive CTE with table-producing function
|
||||
query I
|
||||
WITH RECURSIVE t AS (
|
||||
SELECT 1 AS i
|
||||
UNION ALL
|
||||
SELECT j
|
||||
FROM t, generate_series(0, 10, 1) series(j)
|
||||
WHERE j=i+1
|
||||
)
|
||||
SELECT * FROM t;
|
||||
----
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
|
||||
# order by is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as (select 1 as x union all select x+1 from t where x < 3 order by x) select * from t
|
||||
----
|
||||
<REGEX>:.*Parser Error.*recursive query is not allowed.*
|
||||
|
||||
# limit is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as (select 1 as x union all select x+1 from t where x < 3 LIMIT 1) select * from t
|
||||
----
|
||||
<REGEX>:.*Parser Error.*recursive query is not allowed.*
|
||||
|
||||
# offset is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as (select 1 as x union all select x+1 from t where x < 3 OFFSET 1) select * from t
|
||||
----
|
||||
<REGEX>:.*Parser Error.*recursive query is not allowed.*
|
||||
|
||||
# offset is not allowed in the recursive term of ctes
|
||||
statement error
|
||||
with recursive t as (select 1 as x union all select x+1 from t where x < 3 LIMIT 1 OFFSET 1) select * from t
|
||||
----
|
||||
<REGEX>:.*Parser Error.*recursive query is not allowed.*
|
||||
Reference in New Issue
Block a user