Skip to content

Parser gaps-f: Snowflake CALL, DATA METRIC FUNCTION, POLICY_CONTEXT and recorded expression fixes - #61

Merged
kvlonge merged 18 commits into
mainfrom
fix/parser-gaps-f
Nov 5, 2026
Merged

kvlonge merged 18 commits into
mainfrom
fix/parser-gaps-f

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Parser batch gaps-f (lane B: scripting, expressions, functions; plus ALTER TABLE/VIEW DATA METRIC FUNCTION, agreed with C).

  • Functions and expressions: data metric function query arguments; default-schema db..fn( ) and CALL db..x!method( ); ! method receivers; stage-reference refusals; INTERVAL precision and field rules; ->> flow operator; ANY/ALL value lists; ** <array> variadic; IPADDRESS '…' typed literal; ESCAPE as an alias; :<keyword> binds; NOT NULL on a structured ARRAY element and MAP value; a string refused as a window frame bound.
  • Statements: plain Snowflake CALL as a Call node (malformed argument lists refused); EXECUTE USING POLICY_CONTEXT ( … ) AS <query> (new ExecuteUsingPolicyContext node); { ADD | DROP | MODIFY } DATA METRIC FUNCTION in ALTER TABLE and ALTER VIEW (new DataMetricFunctionAction); BEGIN WORK/TRANSACTION NAME keeps the name (auditor withhold); DECLARE nested procedures.
  • Snowflake-only rules apply in faithful mode only, so the polyglot comparison is unchanged; the exact check passed on 5ae92e0 (exit 0, 843 s).

Coverage diff against main 77e10ee (catalogue c9ce0ff + evidence 1c56796): 0 forms lost, 0 obligations lost, +1,151 obligations, parsed-now-refused 0, syntax-error-now-accepted 0. A first measurement found 26 parsed-now-refused rows (CALL SNOWFLAKE..ANOMALY_INSIGHTS!…), fixed in 7b2075b. Forms gained: 0 on that catalogue, because most forms still wait on observe triage and reviews; the 3-hour cap was reached before the 67-form floor.

…IP, exact check pending)

A qualified call takes a bare query argument, as data metric functions do
(SNOWFLAKE.CORE.NULL_COUNT(SELECT c FROM t)); a call may leave out the
schema (db..f(x)); the ! method syntax needs a name or MODEL( <names> )
receiver and a method; stage references refuse @'x', @"x y" and
@<reserved word>; INTERVAL types keep a precision of 1 to 9 (0 to 9 for
seconds after TO) and need a field; DECLARE takes nested procedures; an
unquoted reserved word is no later name part; BEGIN WORK/TRANSACTION NAME
keeps the name.
…nd empty lambdas

A trailing ESCAPE with nothing after it is an alias, :<keyword> is a bind
variable and :"x" is refused, a bare @ before , or ) is a stage argument,
and ( ) -> x is refused. Two corpus inputs the stage-name refusal now rejects
are listed as expected rejections.
->> chains statements as an Operator node and is no longer a JSON operator
in Snowflake expressions. ANY/ALL take a value list, STRING( ) takes empty
parentheses, and only SELECT is refused as a later dotted name part, the one
word recorded. Corpus inputs refused by recorded rules (a bare INTERVAL type,
->> inside expressions, a string stage name) are listed as expected rejections.
… flow only under faithful calls

** <array> in a call's arguments is a Variadic node, like PostgreSQL's
VARIADIC, and IPADDRESS '<text>' is a typed literal. The flow operator and
the refusal of ->> as a JSON operator apply only with Snowflake's faithful-call
rules, so the polyglot comparison keeps its JSON reading and needs no
expected rejections for it.
…th colon

INTERVAL m1 YEAR and v1 :'v1' are recorded syntax errors. Both refusals apply
only with Snowflake's faithful-call rules.
… whatever it expects

The snapshot took Snowflake's verdict from a case's checked phase, which is
none for every observe case, so a receipted observe case the parser stopped
accepting never reached the diff (#55's three regressions, audit 38bed22).

Each case result now carries what Snowflake's parser did, by every syntax
receipt of its SQL, setup and session whatever the case id: parsed when all
stopped after parsing with an errno other than 1003, refused when all are a
positioned 1003 or a 921, and nothing for a positionless 1003 or receipts that
disagree. The diff fails on a parsed case the parser now rejects, as before,
and also on a refused case it now accepts.
CAST ( NULL AS INTERVAL SECOND ( 9 ) , ( 3 ) ) is a recorded syntax error that
the interval precision change had let through as CAST's comma format. The
refusal applies only with Snowflake's faithful-call rules.
…s Snowflake does

- In faithful Snowflake mode a plain CALL parses as a Call node, as WITH ... CALL
  already did, so malformed argument lists are refused instead of kept as a command.
- EXECUTE USING POLICY_CONTEXT ( <name> => <value>, ... ) AS <query> parses as an
  ExecuteUsingPolicyContext node.
- A string is refused as a window frame bound value.
…BLE and ALTER VIEW

A DataMetricFunctionAction holds the items, each a function name, its ON
arguments and its clauses (SENSITIVITY, ANOMALY_DETECTION, EXPECTATION changes,
WITHIN GROUP ... GROUP LIMIT, EXECUTE AS ROLE, FILTER, SUSPEND and RESUME).
The ON list takes columns, then optionally TABLE ( <name> ( <column>, ... ) )
or a lambda; the column list may be empty, as Snowflake's receipts show.
…TS!METHOD( )

The structured CALL refused the 26 receipted class method calls that leave the
schema out; the coverage diff's parsed-now-refused line caught them.
… rules to faithful Snowflake parsing

The exact check compares the polyglot modes with sqlglot, which refuses
ARRAY(VARCHAR NOT NULL); these Snowflake-only rules now apply where the CALL and
frame-bound rules do.
polyglot has no NOT NULL element type, so the type-name check unwraps the
wrapper before converting; it compares base names (ARRAY, MAP) only.
…lake_commands.rs

commands.rs passed fensu's 2,000-line limit after merging main; these Snowflake
EXECUTE forms sit with the other Snowflake commands.
@kvlonge
kvlonge merged commit f3c75ab into main Nov 5, 2026

kvlonge commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

Gate (D94) and landing record.

  • Command: make check-merge RECORDER=0 on the exact head f3c75ab3a132fdd62bf299818f9780b51f846900, one build job. Exit 0.
  • The head contains main 0861df090463bb9f7d1d9e87e53171651fa9031d (List documented (D113) syntax-error flips apart in the coverage diff (D135) #60, with Parse a Snowflake CREATE DATABASE ROLE by name #59 and Join changed cases to Snowflake's receipts in the coverage diff, whatever they expect #58), merged in as merge commits. Two earlier gate runs stopped at lint: an untracked scratch example (moved out of the worktree), and commands.rs passing fensu's 2,000-line limit after the merge (fixed in f3c75ab by moving the Snowflake EXECUTE parsers to snowflake_commands.rs).
  • Exact polyglot check: exit 0 on 5ae92e0 (843 s); later commits are a merge of main and a pure move.
  • Landed by fast-forward: main = f3c75ab3. main tree = head tree = 63b85c0426ae4908f59a6d2e7fa741e14107189c.
  • Coverage diff against the committed baseline in the gate: no regression, DOCUMENTED or CATALOGUE lines; 0 forms lost, 0 obligations lost; 89 obligations gained (56 before this PR).
  • Measured against main a398f2e on the approved catalogue b393c9a with evidence aa78224: +1,458 obligations, 0 lost. Receipted Snowflake-parsed cases now rejected: 0. Snowflake syntax errors now accepted: 0. An earlier run had 26 parsed-now-refused rows (CALL SNOWFLAKE . . ANOMALY_INSIGHTS!…), fixed in 7b2075b.
  • Form gains against the 67-form floor: 0 forms gained in this tool's view, because forms verify only through the auditor's reviews. The 3-hour cap was reached at 08:38Z, before the floor. Of the 462 settled-accept (D133) cases in B's six families, 97 remain rejected or opaque (C's worklist listed 387 on c793813).
  • Stale reviews: the gate printed none. Reviews that bind the parser tree go stale on any parser commit until the auditor renews them in D118.

kvlonge added a commit that referenced this pull request Nov 5, 2026
Reads the 301 forms newly eligible at main f3c75ab, catalogue 7d000b3
and evidence 21e794d: 281 approved, 19 findings, 1 withheld. BEGIN
WORK/TRANSACTION NAME is approved. Receipt-direct regression check
against a398f2e: 0 regressions.
@kvlonge
kvlonge deleted the fix/parser-gaps-f branch November 9, 2026 21:32
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