Skip to content

fix(snowflake): read keyword values, option keys and patterns faithfully in Snowflake trees - #238

Merged
kvlonge merged 27 commits into
mainfrom
fix/snowflake-tree-fidelity-2
Nov 15, 2026
Merged

kvlonge merged 27 commits into
mainfrom
fix/snowflake-tree-fidelity-2

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 15, 2026

Copy link
Copy Markdown
Contributor

Why

Re-reviews of Snowflake forms found trees that filed documented keyword values (TYPE = CSV, REFRESH_MODE = FULL) and option-list keys as table names, kept a MATCH_RECOGNIZE pattern as text, and lost spellings such as TEMP and AS. New receipt batches also needed their cases settled.

Changes

  • fix(snowflake): a property's documented bare keyword values are keywords (var, upper-cased) at top level and in nested option lists; other bare words stay names.
  • fix(snowflake): option-list keys on the ALTER USER and routine paths and in storage locations are keys, not objects; a group's object types are keywords.
  • fix(receipts): 31 more reviewed post-parse Snowflake errors classify as semantic.
  • fix(snowflake): MATCH_RECOGNIZE PATTERN is a tree of variables, anchors, groups and quantifiers.
  • fix(snowflake): temporary functions and procedures keep their TEMP spelling; altered columns keep COLUMN and SET DATA TYPE words; RESAMPLE keeps AS; COPY = ( GRANTS ), cortex search AS, CREATE SNOWFLAKE class privileges and DCM database accounts keep their parts.
  • fix(snowflake): receipt fixes for an unquoted s3:// URL, EXECUTE AS USER placement in ALTER TASK SET, and UNSET COMMENT on a consumer's token.
  • feat(syntax-cases): one case per option when Snowflake refuses the all-options case; observe cases settle from agreeing receipts; redacted locations are counted.
  • chore(syntax-coverage): evidence pinned with the new receipts; 196 changed forms judged again (101 scoped, 95 in full) and approved; baseline re-recorded.

Still open: options covered only by a refused case, all-optional branches with no valid case, CUBE and GROUPING SETS as calls, DMF TABLE() types, RETURNS TABLE and CALL WITH options as text.

Verification

  • Each fix has parser tests that fail on the previous code.
  • Verified forms 2,994 to 3,087 of 3,351: gross 93, drops 0, net +93.
  • syntax-coverage diff exits 0 with nothing lost or contradicted.
  • make check-ci passes on the final head.

…mantic

Each errno names an object lookup, a value check or a cross-option rule that
runs after Snowflake's parser accepted the statement. Errnos 603, 630, 926 and
392032 stay unestablished.
…otal

A form whose catalogue status is absent_from_source is left out of the total,
the verified count and its family tally, even when all its obligations are
satisfied, and is counted only as absent.
CREATE TEMP FUNCTION and CREATE TEMPORARY FUNCTION gave the same tree. A
function now records temporary_spelling as tables do, reading past SECURE and
AGGREGATE to the temporary word.
…ses the case with every option

When the only case covering an option is the case with every option and
Snowflake refused it as a syntax error, the form is derived again unpacked,
so that each option is also tried on its own.
OBJECT_TYPES = DATABASES gave a table named DATABASES. Each plain one-word
object type is now the keyword it names, as multi-word integration types
already are; other group properties keep one-word values as names.
COPY = ( GRANTS ) gave a table named GRANTS. Properties whose values are
keywords now share one list, so COPY and a group's OBJECT_TYPES both read
plain one-word values as keywords.
In ALTER EXTERNAL VOLUME ... STORAGE_LOCATION = ( NAME = 'm' ... ), each
option key gave a table named after it. An unqualified key of a KEY = value
pair is now an identifier; KEY => value stays a named argument.
IS_GENERATED ( ) AS v1 and IS_GENERATED ( ) v1 gave the same tree. RESAMPLE
now records, by position, which metadata column aliases followed AS.
…d record the ALTER STAGE and ALTER TASK probes
…as semantic

Each errno names an unresolved dependency, an account qualifier, an undeclared
asset, an undefined task graph member, an unsupported argument type, a bucket
name, a task schedule or a parameter value that Snowflake checks after parsing.
Errno 603 stays unestablished.
…g receipts

A documented positive Snowflake refuses was left observed. Its agreeing
receipts now settle it like any other observed case, so Snowflake's outcome
becomes the expectation; it keeps its documented mark, so the gate still only
lists the parser accepting it.
The query of CREATE CORTEX SEARCH SERVICE was filed under the index
keyword (ON or TEXT INDEXES), which is already kept as a property.
It now uses AS, as other CREATE kinds with a query do.
…as a name

GRANT CREATE SNOWFLAKE.<schema>.<class> kept the whole path in the
privilege's name, so SNOWFLAKE..BUDGET left an empty schema in a raw
string. The privilege is now CREATE with a class name in a new optional
Privilege.class field, where a left-out schema is a null part with
schema_omitted set, as a class instance's CREATE already keeps it.
…mer's token

Snowflake parses ALTER EXTERNAL CONSUMER ... MODIFY { PROGRAMMATIC ACCESS
TOKEN | PAT } <name> UNSET COMMENT (a recorded semantic error), and
refuses a bare UNSET. MODIFY now takes SET properties or UNSET COMMENT.
Snowflake reads DEFINE DATABASE <a>.<b> as a database in another account
and refuses it only after parsing (a recorded semantic error). A DEFINE
DATABASE now takes that qualifier, kept in a new optional
CreateDatabase.account field; CREATE DATABASE still takes one name.
CREATE TEMP PROCEDURE and CREATE TEMPORARY PROCEDURE gave the same tree.
A procedure now records temporary_spelling the way a function does.
Values such as OVERLAP_POLICY = NO_OVERLAP, REFRESH_MODE = FULL, TYPE = CSV,
DIRECTION = OUTBOUND and a file format's ENCODING = UTF8 were filed as table
names, the same shape as an object name written in that slot. Each property
whose documented syntax offers bare keyword values now reads those values as
keywords on the CREATE, ALTER SET and nested option-list paths; any other
bare word still stays a name.
In ALTER USER SET WORKLOAD_IDENTITY = ( ANOMALY_DETECTION = TRUE ) and other
parenthesised option lists read on the ALTER routine and user paths, each
pair's key was filed as a table name. CREATE USER and the resource paths key
the same pairs by a plain name; the ALTER path now does the same.
…d and option-key fixes changed

196 forms approved after their trees changed: 101 scoped re-reviews of the
changed cases and 95 full reviews. The baseline is re-recorded at the new
parser tree; no form or obligation is lost.
@kvlonge
kvlonge enabled auto-merge November 15, 2026 10:39
@kvlonge
kvlonge added this pull request to the merge queue Nov 15, 2026
Merged via the queue into main with commit cadf081 Nov 15, 2026
9 checks passed
@kvlonge
kvlonge deleted the fix/snowflake-tree-fidelity-2 branch November 15, 2026 12:06
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