From 5c2e41244b421a893c7263d9c17f48fb7bd4413c Mon Sep 17 00:00:00 2001 From: Arav-Arun Date: Mon, 19 Oct 2026 18:59:41 +0530 Subject: [PATCH] BREAKING! Rename execute_expr to execute_immediate_expr --- src/cst/PreparedStatements.ts | 6 +++--- src/cst/ProceduralLanguage.ts | 6 +++--- src/parser.pegjs | 8 ++++---- src/showNode/prepared_statements.ts | 3 ++- test/proc/for.test.ts | 9 ++++++++- test/proc/return.test.ts | 12 +++++++++++- 6 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/cst/PreparedStatements.ts b/src/cst/PreparedStatements.ts index ade53bb0..05cd0373 100644 --- a/src/cst/PreparedStatements.ts +++ b/src/cst/PreparedStatements.ts @@ -10,7 +10,7 @@ export type AllPreparedStatementNodes = | PrepareFromClause | DeallocateAll | ExecuteUsingClause - | ExecuteExpr; + | ExecuteImmediateExpr; export type AllPreparedStatements = | PrepareStmt @@ -75,8 +75,8 @@ export interface ExecuteUsingClause extends BaseNode { // EXECUTE inside PL/pgSQL, as in: // - RETURN QUERY EXECUTE 'SELECT * FROM tbl' USING var1, var2; // - FOR rec IN EXECUTE 'SELECT * FROM tbl' LOOP ... END LOOP; -export interface ExecuteExpr extends BaseNode { - type: "execute_expr"; +export interface ExecuteImmediateExpr extends BaseNode { + type: "execute_immediate_expr"; executeKw: Keyword<"EXECUTE">; expr: Expr; using?: ExecuteUsingClause; diff --git a/src/cst/ProceduralLanguage.ts b/src/cst/ProceduralLanguage.ts index 4d9b870f..a9c0eedb 100644 --- a/src/cst/ProceduralLanguage.ts +++ b/src/cst/ProceduralLanguage.ts @@ -15,7 +15,7 @@ import { } from "./Expr"; import { StringLiteral } from "./Literal"; import { CommaClause } from "./Node"; -import { ExecuteExpr } from "./PreparedStatements"; +import { ExecuteImmediateExpr } from "./PreparedStatements"; import { AsClause } from "./OtherClauses"; import { Program } from "./Program"; import { SubSelect } from "./Select"; @@ -298,7 +298,7 @@ export interface ForLoopStmt extends BaseNode { forKw: Keyword<"FOR">; left: Identifier; inKw: Keyword<"IN">; - right: SubSelect | ForRange | ExecuteExpr; + right: SubSelect | ForRange | ExecuteImmediateExpr; loop: LoopStmt; } @@ -375,7 +375,7 @@ export interface ReturnNextStmt extends BaseNode { export interface ReturnQueryStmt extends BaseNode { type: "return_query_stmt"; returnQueryKw: [Keyword<"RETURN">, Keyword<"QUERY">]; - expr: SubSelect | ExecuteExpr; + expr: SubSelect | ExecuteImmediateExpr; } // RAISE diff --git a/src/parser.pegjs b/src/parser.pegjs index cda537c2..92cc967e 100644 --- a/src/parser.pegjs +++ b/src/parser.pegjs @@ -5729,7 +5729,7 @@ for_stmt } for_loop_stmt - = kw:(FOR __) left:(ident __) inKw:(IN __) right:((execute_expr / dml_statement / for_range) __) loop:loop_stmt { + = kw:(FOR __) left:(ident __) inKw:(IN __) right:((execute_immediate_expr / dml_statement / for_range) __) loop:loop_stmt { return loc({ type: "for_loop_stmt", forKw: read(kw), @@ -5807,7 +5807,7 @@ call_stmt } return_stmt - = &plpgsql kw:(RETURN __ QUERY __) expr:(compound_select_stmt / execute_expr) { + = &plpgsql kw:(RETURN __ QUERY __) expr:(compound_select_stmt / execute_immediate_expr) { return loc({ type: "return_query_stmt", returnQueryKw: read(kw), expr }); } / &plpgsql kw:(RETURN __ NEXT __) expr:expr { @@ -5979,10 +5979,10 @@ execute_using_clause }); } -execute_expr +execute_immediate_expr = kw:(EXECUTE __) expr:expr using:(__ execute_using_clause)? { return loc({ - type: "execute_expr", + type: "execute_immediate_expr", executeKw: read(kw), expr, using: read(using), diff --git a/src/showNode/prepared_statements.ts b/src/showNode/prepared_statements.ts index 4ae5cebe..d66be38b 100644 --- a/src/showNode/prepared_statements.ts +++ b/src/showNode/prepared_statements.ts @@ -15,5 +15,6 @@ export const preparedStatementsMap: FullTransformMap< execute_immediate_stmt: (node) => show([node.executeKw, node.immediateKw, node.expr, node.into, node.using]), execute_using_clause: (node) => show([node.usingKw, node.values]), - execute_expr: (node) => show([node.executeKw, node.expr, node.using]), + execute_immediate_expr: (node) => + show([node.executeKw, node.expr, node.using]), }; diff --git a/test/proc/for.test.ts b/test/proc/for.test.ts index f8f93e3f..6bd5644c 100644 --- a/test/proc/for.test.ts +++ b/test/proc/for.test.ts @@ -1,4 +1,4 @@ -import { dialect, parse, testWc } from "../test_utils"; +import { dialect, parse, parseStmt, testWc } from "../test_utils"; describe("FOR..IN", () => { dialect(["bigquery"], () => { @@ -134,6 +134,13 @@ describe("FOR..IN", () => { }); describe("FOR IN EXECUTE .. LOOP", () => { + it.each(["", " USING var1, var2"])("parses EXECUTE%s as execute_immediate_expr", (using) => { + expect(parseStmt(`FOR x IN EXECUTE 'SELECT 1'${using} LOOP NULL; END LOOP`)).toMatchObject({ + type: "for_loop_stmt", + right: { type: "execute_immediate_expr" }, + }); + }); + it("supports basic EXECUTE", () => { testWc(` FOR x IN EXECUTE 'SELECT 1' LOOP diff --git a/test/proc/return.test.ts b/test/proc/return.test.ts index ffb2fd9e..a37ffdf0 100644 --- a/test/proc/return.test.ts +++ b/test/proc/return.test.ts @@ -1,4 +1,4 @@ -import { dialect, parse, testWc } from "../test_utils"; +import { dialect, parse, parseStmt, testWc } from "../test_utils"; describe("RETURN", () => { dialect(["bigquery", "plpgsql"], () => { @@ -34,6 +34,16 @@ describe("RETURN", () => { testWc(`RETURN QUERY EXECUTE 'SELECT * FROM tbl'`); }); + it.each(["", " USING var1, var2"])( + "parses RETURN QUERY EXECUTE%s as execute_immediate_expr", + (using) => { + expect(parseStmt(`RETURN QUERY EXECUTE 'SELECT * FROM tbl'${using}`)).toMatchObject({ + type: "return_query_stmt", + expr: { type: "execute_immediate_expr" }, + }); + } + ); + it("supports RETURN QUERY EXECUTE with string-expression", () => { testWc(`RETURN QUERY EXECUTE 'SELECT * FROM tbl' || ' WHERE id = ' || var1`); });