Skip to content

Commit 3f589f6

Browse files
avaminglimy-ship-it
authored andcommitted
Forbid writable CTE with SELECT INTO clause.
Fix issue: #1214 Cloudberry currently only support CTEs with one writable clause, SELECT INTO caluse with a writable CTE should also be forbidden as it will create a new table with data inserted. Authored-by: Zhang Mingli [email protected]
1 parent f7cbca1 commit 3f589f6

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed

src/backend/parser/analyze.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,25 @@ transformOptionalSelectInto(ParseState *pstate, Node *parseTree)
340340
stmt->intoClause = NULL;
341341

342342
parseTree = (Node *) ctas;
343+
344+
if (stmt->withClause)
345+
{
346+
/*
347+
* Just transform to check p_hasModifyingCTE, cte list will be transformed inside SELECT stmt.
348+
*/
349+
transformWithClause(pstate, stmt->withClause);
350+
/*
351+
* Since Cloudberry currently only support a single writer gang, only one
352+
* writable clause is permitted per CTE. Once we get flexible gangs
353+
* with more than one writer gang we can lift this restriction.
354+
*/
355+
if (pstate->p_hasModifyingCTE)
356+
ereport(ERROR,
357+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
358+
errmsg("writable CTE queries cannot be used with writable queries"),
359+
errdetail("Apache Cloudberry currently only support CTEs with one writable clause, called in a non-writable context."),
360+
errhint("Rewrite the query to only include one writable clause.")));
361+
}
343362
}
344363
}
345364

src/test/regress/expected/with.out

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3239,3 +3239,28 @@ select * from with_test;
32393239
(1 row)
32403240

32413241
drop table with_test;
3242+
--
3243+
-- writable CTE with SELECT INTO clause.
3244+
--
3245+
CREATE TABLE t_w_cte(a integer);
3246+
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table.
3247+
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
3248+
EXPLAIN(COSTS OFF, VERBOSE) WITH ins AS (
3249+
INSERT INTO t_w_cte(a) VALUES (1), (2), (3)
3250+
RETURNING a
3251+
)
3252+
SELECT sum(a) INTO t_w_cte_1 FROM ins;
3253+
ERROR: writable CTE queries cannot be used with writable queries
3254+
DETAIL: Apache Cloudberry currently only support CTEs with one writable clause, called in a non-writable context.
3255+
HINT: Rewrite the query to only include one writable clause.
3256+
DROP TABLE t_w_cte;
3257+
CREATE TABLE t_w_cte_relp(a integer) distributed replicated;
3258+
EXPLAIN(COSTS OFF, VERBOSE) WITH ins AS (
3259+
INSERT INTO t_w_cte_relp(a) VALUES (1), (2), (3)
3260+
RETURNING a
3261+
)
3262+
SELECT sum(a) INTO t_w_cte_relp_1 FROM ins;
3263+
ERROR: writable CTE queries cannot be used with writable queries
3264+
DETAIL: Apache Cloudberry currently only support CTEs with one writable clause, called in a non-writable context.
3265+
HINT: Rewrite the query to only include one writable clause.
3266+
DROP TABLE t_w_cte_relp;

src/test/regress/expected/with_optimizer.out

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3259,3 +3259,28 @@ select * from with_test;
32593259
(1 row)
32603260

32613261
drop table with_test;
3262+
--
3263+
-- writable CTE with SELECT INTO clause.
3264+
--
3265+
CREATE TABLE t_w_cte(a integer);
3266+
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table.
3267+
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
3268+
EXPLAIN(COSTS OFF, VERBOSE) WITH ins AS (
3269+
INSERT INTO t_w_cte(a) VALUES (1), (2), (3)
3270+
RETURNING a
3271+
)
3272+
SELECT sum(a) INTO t_w_cte_1 FROM ins;
3273+
ERROR: writable CTE queries cannot be used with writable queries
3274+
DETAIL: Apache Cloudberry currently only support CTEs with one writable clause, called in a non-writable context.
3275+
HINT: Rewrite the query to only include one writable clause.
3276+
DROP TABLE t_w_cte;
3277+
CREATE TABLE t_w_cte_relp(a integer) distributed replicated;
3278+
EXPLAIN(COSTS OFF, VERBOSE) WITH ins AS (
3279+
INSERT INTO t_w_cte_relp(a) VALUES (1), (2), (3)
3280+
RETURNING a
3281+
)
3282+
SELECT sum(a) INTO t_w_cte_relp_1 FROM ins;
3283+
ERROR: writable CTE queries cannot be used with writable queries
3284+
DETAIL: Apache Cloudberry currently only support CTEs with one writable clause, called in a non-writable context.
3285+
HINT: Rewrite the query to only include one writable clause.
3286+
DROP TABLE t_w_cte_relp;

src/test/regress/sql/with.sql

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,3 +1575,22 @@ create temp table with_test (i int);
15751575
with with_test as (select 42) insert into with_test select * from with_test;
15761576
select * from with_test;
15771577
drop table with_test;
1578+
1579+
--
1580+
-- writable CTE with SELECT INTO clause.
1581+
--
1582+
CREATE TABLE t_w_cte(a integer);
1583+
EXPLAIN(COSTS OFF, VERBOSE) WITH ins AS (
1584+
INSERT INTO t_w_cte(a) VALUES (1), (2), (3)
1585+
RETURNING a
1586+
)
1587+
SELECT sum(a) INTO t_w_cte_1 FROM ins;
1588+
DROP TABLE t_w_cte;
1589+
1590+
CREATE TABLE t_w_cte_relp(a integer) distributed replicated;
1591+
EXPLAIN(COSTS OFF, VERBOSE) WITH ins AS (
1592+
INSERT INTO t_w_cte_relp(a) VALUES (1), (2), (3)
1593+
RETURNING a
1594+
)
1595+
SELECT sum(a) INTO t_w_cte_relp_1 FROM ins;
1596+
DROP TABLE t_w_cte_relp;

0 commit comments

Comments
 (0)