Skip to content

Commit 7345d78

Browse files
committed
Support UPDATE,INSERT,DELETE inside WITH clause (PostgreSQL)
1 parent d667899 commit 7345d78

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

src/cst/Select.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ import { FrameClause } from "./WindowFrame";
1414
import { Literal, StringLiteral } from "./Literal";
1515
import { MysqlModifier } from "./dialects/Mysql";
1616
import { ColumnDefinition } from "./CreateTable";
17-
import { PostgresqlOperator, PostgresqlOperatorExpr } from "./Node";
17+
import {
18+
DeleteStmt,
19+
InsertStmt,
20+
PostgresqlOperator,
21+
PostgresqlOperatorExpr,
22+
UpdateStmt,
23+
} from "./Node";
1824

1925
export type AllSelectNodes =
2026
| CompoundSelectStmt
@@ -149,7 +155,8 @@ export interface CommonTableExpr extends BaseNode {
149155
materializedKw?:
150156
| Keyword<"MATERIALIZED">
151157
| [Keyword<"NOT">, Keyword<"MATERIALIZED">];
152-
expr: ParenExpr<SubSelect>;
158+
// PostgreSQL supports UPDATE, DELETE, and INSERT in WITH clause
159+
expr: ParenExpr<SubSelect | DeleteStmt | InsertStmt | UpdateStmt>;
153160
search?: CteSearchClause;
154161
cycle?: CteCycleClause;
155162
}

src/parser.pegjs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ common_table_expr
191191
columns:(__ paren$list$column)?
192192
asKw:(__ AS)
193193
materialized:(__ cte_materialized)?
194-
select:(__ paren$compound_select_stmt)
194+
expr:(__ paren$cte_expr)
195195
search:(__ cte_search_clause)?
196196
cycle:(__ cte_cycle_clause)? {
197197
return loc({
@@ -200,7 +200,7 @@ common_table_expr
200200
columns: read(columns),
201201
asKw: read(asKw),
202202
materializedKw: read(materialized),
203-
expr: read(select),
203+
expr: read(expr),
204204
search: read(search),
205205
cycle: read(cycle),
206206
});
@@ -209,6 +209,10 @@ common_table_expr
209209
cte_materialized
210210
= kws:(NOT __ MATERIALIZED / MATERIALIZED) { return read(kws); }
211211

212+
cte_expr
213+
= compound_select_stmt
214+
/ stmt:(update_stmt / insert_stmt / delete_stmt) &postgres { return stmt; }
215+
212216
cte_search_clause
213217
= kw:(SEARCH __ (BREADTH / DEPTH) __ FIRST __ BY __) columns:list$ident
214218
setKw:(__ SET __) result:ident &postgres {
@@ -4944,6 +4948,7 @@ paren$__template__
49444948

49454949
paren$cast_arg = .
49464950
paren$compound_select_stmt = .
4951+
paren$cte_expr = .
49474952
paren$empty_list = .
49484953
paren$entity_name = .
49494954
paren$expr = .

test/select/with.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,17 @@ describe("select WITH", () => {
6060
SELECT * FROM search_graph
6161
`);
6262
});
63+
64+
it("supports INSERT inside WITH", () => {
65+
testWc(`WITH t1 AS (INSERT INTO foo VALUES (1) RETURNING *) SELECT * FROM t1`);
66+
});
67+
68+
it("supports UPDATE inside WITH", () => {
69+
testWc(`WITH t1 AS (UPDATE foo SET bar = 1 RETURNING *) SELECT * FROM t1`);
70+
});
71+
72+
it("supports DELETE inside WITH", () => {
73+
testWc(`WITH t1 AS (DELETE FROM foo RETURNING *) SELECT * FROM t1`);
74+
});
6375
});
6476
});

0 commit comments

Comments
 (0)