feat(grammar): declaration attributes and cursors in procedural bodies - #373
Draft
sebsnyk wants to merge 3 commits into
Draft
feat(grammar): declaration attributes and cursors in procedural bodies#373sebsnyk wants to merge 3 commits into
sebsnyk wants to merge 3 commits into
Conversation
Function and procedure bodies could hold SQL statements and RETURN but none of the control flow that PL/pgSQL and PL/SQL bodies are made of. Adds assignment with `:=` or `=`, `NULL`, `IF ... ELSIF ... ELSE ... END IF`, `CASE ... END CASE`, `LOOP`, `WHILE ... LOOP`, `FOR ... IN` over an integer range, a query or a cursor, `FOREACH ... IN ARRAY`, `EXIT` and `CONTINUE` with an optional label and `WHEN`, `<<label>>` on blocks and loops, nested `DECLARE ... BEGIN ... END` blocks and a bare `RETURN`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the error-handling statements of PL/pgSQL and PL/SQL bodies: `RAISE` with a level, a format string and arguments, a condition name, `SQLSTATE` or `USING` options; `ASSERT`; `EXCEPTION WHEN ... THEN` handlers at the end of a function body, procedure body or block, with `OR`-joined conditions, `SQLSTATE` and `OTHERS`; and `GET [CURRENT | STACKED] DIAGNOSTICS`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Declarations gain `%TYPE` and `%ROWTYPE` (also in parameters), `CONSTANT`, `NOT NULL`, `=` and `DEFAULT` initialisers, `ALIAS FOR`, and cursor declarations in both the PL/pgSQL (`c [NO SCROLL] CURSOR (args) FOR query`) and PL/SQL (`CURSOR c RETURN type IS query`) forms. Bodies gain `OPEN`, `FETCH`, `MOVE` and `CLOSE`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Declarations and cursors are where PL/SQL sources fail first, and they are common in PL/pgSQL too:
v employees.salary%type,l_row employees%rowtype,c constant int := 3,n int not null default 0,arg alias for $1,cursor c is select ...,open/fetch ... into/close. Oracle's HR sample schema declares every procedure parameter with%type, so none of its procedures parse past the signature. Against real sources:ERRORnodes with #372src/test/regress/sql/plpgsql.sqlsql/functions/check_default.sqlsource/core/ut_utils.pkbutPLSQL does not move because it needs Oracle's
IS ... END name;header shape and package bodies, which are the next PR.Solution
type_attribute:object_reference % (TYPE | ROWTYPE), accepted wherever a declaration or a function argument takes a type. It is a separate alternative next to_typerather than an addition to_typeitself, so column definitions and casts are untouched.function_declarationacceptsCONSTANT,NOT NULL, and=/DEFAULTas well as:=; a second form coversname ALIAS FOR $n | name. The initialiser itself is unchanged (a parenthesised statement or a literal); allowing any expression there changes the tree of an existing test and is left for a separate PR.cursor_declaration:name [NO SCROLL | SCROLL] CURSOR [(args)] [RETURN type] (FOR | IS) query, and the PL/SQL word orderCURSOR name .... Cursor parameters reusefunction_arguments.open_statement,fetch_statement,move_statement,close_statementingrammar/statements/cursors.js, with the PL/pgSQL directions (NEXT,PRIOR,FIRST,LAST,ABSOLUTE n,RELATIVE n,FORWARD,BACKWARD) andOPEN c FOR queryfor cursor variables.OPEN c FOR EXECUTE ...comes with dynamic SQL in the next PR.DECLAREsection is one hidden rule (_declare_section) shared byfunction_body,procedure_bodyandblock; the tree is unchanged.One resolution worth a look: in
FETCH ABSOLUTE n IN cur, the count is followed byIN, which is also the start ofexpr IN (...). The direction rule isprec.leftso the count reduces first.Notes
tree-sitter test: 531 corpus tests on feat(grammar): RAISE, ASSERT, EXCEPTION handlers and GET DIAGNOSTICS #372, 538 with this PR (4 new intest/corpus/declarations.txt, 3 intest/corpus/cursors.txt), plus the 2 highlight tests. NoERROR/MISSING;scripts/test-keywords.shpasses.STATE_COUNT31012 → 31202 (+0.6% on top of feat(grammar): RAISE, ASSERT, EXCEPTION handlers and GET DIAGNOSTICS #372; +1.9% overmain),parser.c42.5 MB → 42.7 MB.