Skip to content

Commit bf567eb

Browse files
committed
Support PREPARE .. AS in PostgreSQL
1 parent d457f82 commit bf567eb

4 files changed

Lines changed: 49 additions & 4 deletions

File tree

src/cst/PreparedStatements.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { Alias } from "./Alias";
22
import { BaseNode, Keyword } from "./Base";
3+
import { DataType } from "./DataType";
34
import { EntityName, Expr, Identifier, ListExpr, ParenExpr } from "./Expr";
5+
import { AsClause } from "./ProcClause";
6+
import { Statement } from "./Statement";
47

58
export type AllPreparedStatementNodes =
69
| AllPreparedStatements
@@ -18,7 +21,8 @@ export interface PrepareStmt extends BaseNode {
1821
type: "prepare_stmt";
1922
prepareKw: Keyword<"PREPARE">;
2023
name: EntityName;
21-
source: PrepareFromClause;
24+
params?: ParenExpr<ListExpr<DataType>>;
25+
source: PrepareFromClause | AsClause<Statement>;
2226
}
2327

2428
export interface PrepareFromClause extends BaseNode {

src/parser.pegjs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ statement_bigquery
100100
statement_postgres
101101
= analyze_stmt
102102
/ explain_stmt
103+
/ prepare_stmt
103104
/ execute_stmt
104105
/ call_stmt
105106
/ do_stmt
@@ -5526,11 +5527,13 @@ raise_message
55265527
*/
55275528
prepare_stmt
55285529
= kw:(PREPARE __) name:(entity_name __)
5529-
source:prepare_from_clause {
5530+
params:(paren$list$data_type __)?
5531+
source:(prepare_from_clause / as_clause$prepareable_statement) {
55305532
return loc({
55315533
type: "prepare_stmt",
55325534
prepareKw: read(kw),
55335535
name: read(name),
5536+
params: read(params),
55345537
source: source,
55355538
});
55365539
}
@@ -5544,6 +5547,13 @@ prepare_from_clause
55445547
});
55455548
}
55465549

5550+
prepareable_statement
5551+
= compound_select_stmt
5552+
/ insert_stmt
5553+
/ update_stmt
5554+
/ delete_stmt
5555+
/ merge_stmt
5556+
55475557
execute_stmt
55485558
= kw:(EXECUTE __) name:entity_name
55495559
args:(__ (execute_using_clause / paren$list$expr))? {
@@ -7737,6 +7747,7 @@ paren$list$alias$paren$list$column = .
77377747
paren$list$column = .
77387748
paren$list$column_definition = .
77397749
paren$list$create_definition = .
7750+
paren$list$data_type = .
77407751
paren$list$entity_name = .
77417752
paren$list$equals_expr = .
77427753
paren$list$exclusion_param = .
@@ -7804,6 +7815,7 @@ list$column_definition = .
78047815
list$common_table_expr = .
78057816
list$config_parameter_value = .
78067817
list$create_definition = .
7818+
list$data_type = .
78077819
list$delete_clause_table = .
78087820
list$entity_name = .
78097821
list$equals_expr = .
@@ -7902,6 +7914,7 @@ as_clause$__template__
79027914
as_clause$compound_select_stmt = .
79037915
as_clause$func_as_expr_bigquery = .
79047916
as_clause$func_as_expr_postgresql = .
7917+
as_clause$prepareable_statement = .
79057918
as_clause$string_literal = .
79067919
as_clause$expr = .
79077920
/*! as_clause:end */

src/showNode/prepared_statements.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ export const preparedStatementsMap: FullTransformMap<
66
string,
77
AllPreparedStatementNodes
88
> = {
9-
prepare_stmt: (node) => show([node.prepareKw, node.name, node.source]),
9+
prepare_stmt: (node) =>
10+
show([node.prepareKw, node.name, node.params, node.source]),
1011
prepare_from_clause: (node) => show([node.fromKw, node.expr]),
1112
execute_stmt: (node) => show([node.executeKw, node.name, node.args]),
1213
execute_immediate_stmt: (node) =>

test/prepared_statements.test.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { dialect, parse, testWc, test } from "./test_utils";
1+
import { dialect, parse, testWc, test, includeAll } from "./test_utils";
22

33
describe("prepared statements", () => {
44
dialect(["mysql", "mariadb"], () => {
@@ -8,6 +8,33 @@ describe("prepared statements", () => {
88
});
99
});
1010

11+
dialect(["postgresql"], () => {
12+
it("supports PREPARE .. AS statement", () => {
13+
testWc(`PREPARE my_stmt AS SELECT * FROM my_table WHERE id = $1`, {
14+
paramTypes: ["$nr"],
15+
...includeAll,
16+
});
17+
testWc(`PREPARE my_stmt AS UPDATE foo SET bar = $1`, { paramTypes: ["$nr"], ...includeAll });
18+
testWc(`PREPARE my_stmt AS DELETE FROM foo WHERE id = $1`, {
19+
paramTypes: ["$nr"],
20+
...includeAll,
21+
});
22+
testWc(`PREPARE my_stmt AS INSERT INTO foo (bar) VALUES ($1)`, {
23+
paramTypes: ["$nr"],
24+
...includeAll,
25+
});
26+
testWc(`PREPARE my_stmt AS MERGE INTO foo USING bar ON x = $1 WHEN MATCHED THEN DELETE`, {
27+
paramTypes: ["$nr"],
28+
...includeAll,
29+
});
30+
testWc(`PREPARE my_stmt AS VALUES ($1), ($2), ($3)`, { paramTypes: ["$nr"], ...includeAll });
31+
});
32+
33+
it("supports PREPARE .. AS with parameters", () => {
34+
testWc(`PREPARE my_stmt(INT, TEXT) AS SELECT $1, $2`, { paramTypes: ["$nr"], ...includeAll });
35+
});
36+
});
37+
1138
dialect(["mysql", "mariadb", "postgresql"], () => {
1239
it("supports EXECUTE", () => {
1340
testWc(`EXECUTE my_stmt`);

0 commit comments

Comments
 (0)