Skip to content

fix(syntax): parse Snowflake CLONE kinds and security AS REPLICA forms - #55

Merged
kvlonge merged 5 commits into
mainfrom
fix/snowflake-clone-replica
Nov 5, 2026
Merged

kvlonge merged 5 commits into
mainfrom
fix/snowflake-clone-replica

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Parses the CREATE ... CLONE kinds lane C kept and the security AS REPLICA forms, on top of #54 (gaps-e).

  • CLONE: ALERT, STAGE, STREAM, SEQUENCE, FILE FORMAT, DATABASE ROLE, EVENT TABLE, and DYNAMIC / ICEBERG / DYNAMIC ICEBERG / TRANSIENT DYNAMIC / LOCAL or GLOBAL TEMPORARY / VOLATILE TABLE parse into CreateObject with source CLONE, reusing fix(syntax): parser gaps batch e (TASK CLONE, CREATE … FROM, quoting, recorded refusals) #54's node. Each takes the documented time travel clause { AT | BEFORE } ( { TIMESTAMP | OFFSET | STATEMENT } => <expr> ) as a typed HistoricalData, and its documented trailing options (COPY GRANTS, COPY TAGS, COPY = ( … ), TARGET_LAG, WAREHOUSE, EXECUTE AS USER, USE SECONDARY ROLES). Any other trailing word is refused. CREATE ROLE … CLONE is refused, since Snowflake clones only a DATABASE ROLE.
  • Database, schema and table clones keep their nodes. In Snowflake they now take the typed time travel clause and their documented options (IGNORE TABLES WITH INSUFFICIENT DATA RETENTION, IGNORE HYBRID TABLES, INCLUDE INTERNAL STAGES; COPY options for tables). CreateDatabase gains a properties list (skipped when empty).
  • AS REPLICA: CREATE CONNECTION / FAILOVER GROUP / REPLICATION GROUP [ IF NOT EXISTS ] AS REPLICA OF .. parses into CreateObject with source REPLICA; only a connection takes COMMENT.
  • Exact check: polyglot keeps the clone time travel clause as raw text, so at_clause / clone_at_clause are listed as kept fields, and tests/parser/test_snowflake_create_clone.rs pins the trees.

Receipted clone cases: 268 of 268 scored right (99 before). AS REPLICA cases have no receipts yet (the replication holds), but all 84 catalogue expectations match. Coverage diff against main 0c8952e, on the 0c8952e catalogue and evidence through import 121: +15 forms, +775 obligations, 0 lost. Seven of those forms are this PR's clone forms; the other eight came with #54.

Gate: make check-merge RECORDER=0 is running on 77e10ee; the result will be posted here.

CREATE ... CLONE now parses for ALERT, STAGE, STREAM, SEQUENCE, FILE
FORMAT, DATABASE ROLE, EVENT TABLE and the dynamic, Iceberg, temporary
and volatile tables into CreateObject with source CLONE, with the
documented time travel clause and trailing options. Database, schema
and table clones take their typed time travel and documented options.
CREATE CONNECTION, FAILOVER GROUP and REPLICATION GROUP ... AS REPLICA
OF org.account.name parse into CreateObject with source REPLICA.

The polyglot exact check lists the typed time travel clause as a kept
field, since polyglot keeps it as raw text.
…flake-clone-replica

# Conflicts:
#	crates/sqlquack-syntax/tests/parser.rs
Outside Snowflake, CREATE SCHEMA and CREATE DATABASE kept their clone time
travel clause with the same loop; it is now one helper, which keeps
commands.rs within the file length limit after the merge.

kvlonge commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

Gate (D94) on 77e10ee, which contains main 497ad27 (#54): make check-merge RECORDER=0 exited 0. That covers fmt, clippy -D warnings, ruff, ty, fensu (0 faults), the syntax coverage and evidence/polyglot guards, generated and referee cases, the Python API, and every Rust test suite, including the polyglot exact check.

Coverage diff against main 497ad27 (gate-profile checker, same catalogue and evidence tree for both): +5 forms, +405 obligations, 0 lost. Gained: create-alert-clone, create-clone.database-schema-clone, create-clone.event-table-clone, create-clone.table-clone, create-stage-clone.

Since the description was written: merged gaps-e 497ad27, and the schema and database clones share their raw AT/BEFORE capture outside Snowflake, so commands.rs stays within the file length limit. Landing by fast-forward.

@kvlonge
kvlonge merged commit 77e10ee into main Nov 5, 2026
kvlonge added a commit that referenced this pull request Nov 5, 2026
kvlonge added a commit that referenced this pull request Nov 5, 2026
Snowflake reads CREATE DATABASE ROLE ; and CREATE DATABASE ROLE CLONE d2
as a database named ROLE (recorded success); #55 took them as a database
role without a name.
kvlonge added a commit that referenced this pull request Nov 5, 2026
… 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.
@kvlonge
kvlonge deleted the fix/snowflake-clone-replica branch November 9, 2026 21:31
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