Repository navigation
fix(parser): end statements at their grammar and gate utility statements per dialect - #872
Conversation
… their grammar Outside SQL Server, statements whose definition holds a statement (PREPARE ... AS, DECLARE ... CURSOR FOR, CREATE FUNCTION/PROCEDURE/TRIGGER/EVENT/ RULE/TASK/VIEW with a single-statement, RETURN or BEGIN ... END body, LOAD DATA) now end with that definition, and GRANT/REVOKE, PostgreSQL COPY, CALL and the other closed utility statements end with their grammar, so a following statement without ';' is an error instead of folding into the text. Also: utility statements are gated to the dialects that have them; PostgreSQL ALTER DEFAULT PRIVILEGES parses; MySQL := assigns only to user variables (PostgreSQL f(a := 1) is a named argument); MariaDB DELETE `history` keeps its quotes; T-SQL ELSE IF chains are parsed iteratively; parseTokens/parseContextTokens share parseScriptItem; MySQL/Oracle ANALYZE TABLE is no longer read as MariaDB ANALYZE <stmt>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
…on lists at same-line statements Review follow-ups to 77185a2: - COPY: E'...' and $$...$$ file names, USING/WITH DELIMITERS; without a dialect (and in Redshift) the PostgreSQL grammar is used when it fits, else the verbatim form. - BigQuery LOAD DATA {INTO | OVERWRITE}. - GRANT: CURRENT_USER(), IDENTIFIER('r'), APPLICATION a, [bracketed] grantees, REQUIRE X509, WITH GRANT OPTION followed by resource limits, IDENTIFIED BY RANDOM PASSWORD, MariaDB IDENTIFIED VIA. - LOAD DATA, CREATE of body-less objects, routines after a quoted or AS (expr) body, PG event triggers, Snowflake PIPE / ALERT end at a statement on the same line (or next line for PIPE / ALERT). - Without a dialect, Oracle-style routines (IS/AS BEGIN ... END name, RETURN type AS LANGUAGE JAVA) run to the next ';' as before. - PostgreSQL name := value requires a non-reserved name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @ajitpratap0's task in 21s —— View job Review of PR #872I read the diff for the core parser changes: What looks good
Suggestions and risks (non-blocking)
Performance and security: the allocs/op figures are identical and ns/op is within noise. Ending statements at their grammar is a security improvement, because Verdict: the design is sound and the diff I read matches the PR description. I have no blocking findings, and the suggestions above are mostly extra tests for the dialect gating. |
|
Claude finished @ajitpratap0's task in 20s —— View job Review of PR #872I read the core parser changes and spot-checked two points from the earlier review against the code. I did not run the test suite, and I did not read Checked against the code
What looks good
Suggestions (non-blocking)
Performance and security: no new concerns. Parsing stays linear, and ending statements at their grammar is a security improvement. Verdict: no blocking issues. The main follow-up is the dialect gating matrix test. |
Summary
Follow-ups from the pre-merge review of #866–#868. A missing
;no longer lets one statement silently swallow the next, and utility statements are accepted only in the dialects that have them.;is an error instead of being folded in. Covered:PREPARE … AS,DECLARE … CURSOR FOR,CREATE FUNCTION/PROCEDURE/TRIGGER/EVENT/RULE/TASKwith a single-statement or quoted body, SnowflakePIPE/ALERT/STREAM, ClickHouseCREATE FUNCTION … AS (x) -> …, andLOAD DATA. Example: PostgreSQLPREPARE s AS SELECT 1\nDROP TABLE tused to be one statement, hiding theDROPfrom the scanner and linter.[bracketed]names, MySQLREQUIRE/resource options/CURRENT_USER(), MariaDBIDENTIFIED VIA, SnowflakeAPPLICATION/IDENTIFIER()), PostgreSQL COPY (old and new option syntax,E''/$$file names,DELIMITERS) and CALL.GRANT … TO u DROP TABLE tis now an error.DO,VACUUM,LOAD DATA(including BigQueryFROM FILES),PRAGMA,ATTACH,OPTIMIZE,FLUSH,KILL,SHOW, andGRANT/SETin SQLite. The generic dialect keeps accepting them all.ALTER DEFAULT PRIVILEGES … GRANT/REVOKEparses and round-trips.:=: MySQL accepts it only in assignments (SET @v := …,SELECT @v := …). PostgreSQLf(a := 1)is parsed as a named argument and renderedf(a => 1).DELETE `history` FROM historykeeps its quotes, so it no longer re-parses asDELETE HISTORY.IF … ELSE IF …chains parse iteratively in linear time. 200 branches used to exceed the depth limit and swallow the next statement.parseScriptItemhelper for both top-level parse loops, with tests for a GO line inside BEGIN…END, a CTE, a subquery, the context path and recovery.Test Plan
gofmt,go vet,golangci-lint run(0 issues),task test:race,task test:cbinding;TestRealWorldCorpusgreen withknown_failures.txtemptyutility_statement_end_test.go, plus GO-line, ELSE IF and named-argument testsSELECT a := 1, Oracle-style routines outside generic/oracle). No quadratic cases (n vs 16n over 39 generators) and no panics (30k truncations).Breaking Changes
Behaviour changes, listed in the CHANGELOG:
:=outside assignments is now rejected.=>.🤖 Generated with Claude Code
https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2