Skip to content

feat(syntax): check the head and option lists of Snowflake statements kept as text - #206

Merged
kvlonge merged 3 commits into
mainfrom
feat/syntax-option-lists
Nov 12, 2026
Merged

kvlonge merged 3 commits into
mainfrom
feat/syntax-option-lists

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

Why

Snowflake CREATE and ALTER statements with no structured grammar stay opaque raw text, and the parser accepted any of them: 1,869 cases with a receipted syntax error. A grammar review also found three trees that misdescribe the SQL.

Changes

  • One shared check reads an opaque CREATE or ALTER (including CREATE TAG, STAGE, STREAM and FILE FORMAT) before the raw fallback. It refuses bad IF [NOT] EXISTS, missing or reserved names, an ALTER with no action, = without a name or value, bad tag lists, unbalanced parentheses, RENAME without TO, AS with no body and a dangling operand word. Accepted trees are unchanged.
  • DELETE USING a subquery is a derived table in using_items.
  • A semantic view's name is a table reference, and an explicit AS is recorded.
  • FIRST or LAST on a join with no ON or USING is the joined table's alias, as Snowflake reads it.
  • receipt-disagreements.toml and baseline.json regenerated; the list only shrinks.

Verification

Before → after on evidence 2cae594b:

  • False accepts: 2,125 → 798.
  • False rejects: 405 → 405.
  • Other receipts: 355 → 350.
  • Verified forms: 2,411 → 2,410 of 3,351.

Validated is not parsed. The checked statements stay opaque. Opaque accepts of cases Snowflake parsed stay at 1,920 in 154 forms. The checker counts these as unsatisfied, so none becomes verified. Structured trees for them are left to later grammar work.

sf.query.join.join.syntax loses its approval. Snowflake read its FIRST/LAST cases as aliases (errno 2003, not 1868), so the old count overstated coverage. It returns when read-order cases are recorded.

Across all 61,904 cases, no parsed case is now refused, and accepted trees outside the three fixes are byte-identical. New regression tests cover both changes. make check-ci passed.

… kept as text

A Snowflake CREATE or ALTER with no structured grammar fell back to raw
text and accepted anything. One shared check now reads it before the
fallback and refuses what Snowflake refuses: a malformed IF [NOT] EXISTS,
a missing or reserved name, an ALTER name with no action after it, a
property with no name or value around `=`, a malformed tag list,
unbalanced parentheses, RENAME without TO, AS with no body, a reserved
keyword used as a name, and a word that needs an operand at the end.
The tree stays the same raw text. TAG, STAGE, STREAM and FILE FORMAT
creates, which keep their own raw parsers, run the same check.
…AST join aliases as what they are

A DELETE USING subquery was a table with an empty name and the query in
its hints; it is now a derived table in using_items, as a FROM subquery
is, with its alias, column aliases and AS spelling. A semantic view's
name was a column node; it is now a table reference, and an explicit AS
in its clauses is recorded. On a join with no ON or USING, FIRST or LAST
followed by parentheses is the joined table's alias and column aliases,
as Snowflake reads it, not a read-order clause.
The check of Snowflake statements kept as text clears 1,327 syntax
errors the parser accepted and 5 other contradicted receipts; the list
only shrinks. Those statements stay opaque, so no form becomes verified
through them. The join form whose FIRST and LAST cases Snowflake reads
as table aliases loses its approval until cases with a read-order
clause are recorded.
@kvlonge
kvlonge enabled auto-merge November 12, 2026 15:24
@kvlonge
kvlonge added this pull request to the merge queue Nov 12, 2026
Merged via the queue into main with commit 72ad5d2 Nov 12, 2026
13 checks passed
@kvlonge
kvlonge deleted the feat/syntax-option-lists branch November 12, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant