Skip to content

Snowflake: parse UNDROP <TABLE|DYNAMIC TABLE|SCHEMA|DATABASE|VIEW> - #18

Open
sabir-akhadov-localstack wants to merge 59 commits into
mainfrom
lav-1400-undrop-grammar
Open

Snowflake: parse UNDROP <TABLE|DYNAMIC TABLE|SCHEMA|DATABASE|VIEW>#18
sabir-akhadov-localstack wants to merge 59 commits into
mainfrom
lav-1400-undrop-grammar

Conversation

@sabir-akhadov-localstack

Copy link
Copy Markdown
Collaborator

Adds first-class UNDROP grammar for the Snowflake statement family (TABLE, DYNAMIC TABLE, SCHEMA, DATABASE) plus VIEW.

VIEW parses into Statement::Undrop so the consumer (snowflake-rs) can reject it with Snowflake's exact unsupported-feature error rather than a generic parse error.

Consumed by localstack/snowflake-rs LAV-1400.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

sabir-akhadov-localstack and others added 30 commits June 23, 2026 02:57
Thread or_replace through parse_create_role and CreateRole AST node so
CREATE OR REPLACE ROLE parses and round-trips.
The quote-escaper kept an 'already escaped' peek-ahead heuristic that left
an adjacent quote pair untouched. A decoded value containing an embedded
empty-string literal ('') is indistinguishable from a pre-escaped quote, so
it was under-escaped. Quoted-string AST nodes hold the decoded value, so
escaping is the pure inverse: double every quote unconditionally.

Updates the with_unescape(false) round-trip tests, which relied on the
heuristic, to assert the new quote-doubled serialization.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add CATALOG_TABLE_NAME and AUTO_REFRESH to CreateTable for
externally-managed Iceberg tables, accept comma- or space-separated
Iceberg options in free order, relax the BASE_LOCATION requirement for
externally-managed tables, and parse DROP ICEBERG TABLE [IF EXISTS]
<name> [PURGE].
Add a parser test covering the FILE_FORMAT = <name> COPY INTO shorthand
(unquoted ident, quoted string, and the unaffected parenthesized form).

Also reflow a pre-existing unformatted block in parser/mod.rs so
'cargo fmt --all -- --check' (CI codestyle) passes.
…ORMAT objects, WRITE + CREATE TABLE privileges (#12)
parse_literal_string now consumes Token::DollarQuotedString in the
Snowflake dialect, so $$...$$ is accepted anywhere a string literal
is expected (e.g. COMMENT ON ... IS $$...$$).
Give ShowProcedures and ShowFunctions the shared ShowStatementOptions so
they accept the IN { ACCOUNT | DATABASE | SCHEMA } scope clause (and the
bare IN <db>.<schema> form) in addition to the LIKE filter, matching the
other scoped SHOW variants.
A wire placeholder (?, $n, ?name) in a COPY INTO stage-name position is
carried through as a single identifier part so the bound stage reference
can be resolved server-side.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Inside a BEGIN … END body the surrounding statement list expects to
consume the trailing ';' itself; leave it via prev_token().
Recognise PUT/GET file-transfer statements inside a scripting BEGIN...END
block as Statement::PutGetFiles so the block parses. Operands are not
modelled: an unquoted file:// path triggers the // single-line-comment
lexer rule, so the statement tail is scanned at the raw-token level up to
its terminator rather than parsed.
Allow a CREATE TABLE column list to name columns without a data type
(e.g. CREATE TABLE t(id) AS SELECT 123), deferring type inference to the
AS query. Gated behind a new Dialect::supports_create_table_optional_column_type
hook, enabled only for SnowflakeDialect; a bare name is accepted only when
immediately followed by ',' or ')' so malformed data types still error.
sabir-akhadov-localstack and others added 29 commits July 7, 2026 13:11
…ALIZATION_WAREHOUSE, SCHEDULER, IMMUTABLE WHERE
Adds ShowStreams and AlterStream statements, DescribeObjectType::Stream,
the STREAMS keyword, and an EOF-anchored error for the invalid
DESCRIBE TABLE STREAM <name> shape (matching real Snowflake).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A stage table factor followed by a comma join (e.g.
FROM @stage/f.jsonl, LATERAL FLATTEN(...)) failed to parse when the
comma abutted the stage path, because parse_stage_name_identifier
consumed the comma and then reported the following token (LATERAL) as
unexpected. Add a Token::Comma stop-arm mirroring the Period/LParen
arms so the comma is pushed back and the shared comma-join/LATERAL
handling takes over.
…test

The ShowObjects struct gained a `dynamic` field but this exhaustive
pattern in test_show_objects was not updated, breaking the test crate
build. Add `..` so the suite compiles.
…ad projections

Dotted sub-paths ($1:a.b), ::TYPE casts (incl. bare $1::INT), and their
combinations in COPY INTO <table> FROM (SELECT ...) data-load transformations
previously failed at parse (unexpected '.'/'::') because the dedicated item
parser consumed only the leading single-word element and committed. Guard the
item as fully consumed (next token is ',' or FROM); otherwise fail so
maybe_parse rolls back to the general select-item fallback.
Re-parse a single-quoted CREATE PROCEDURE body the same way as a
dollar-quoted one, so string-literal bodies with doubled '' quotes
parse into a ConditionalStatements block.
Extend parse_select_into to accept a colon placeholder (e.g.
SELECT ... INTO :var) as the target in dialects that opt in via
supports_select_into_placeholder_target (Snowflake scripting). The
:name placeholder text is preserved as the object-name part so the
round-trip is stable and downstream can distinguish it from a bare
table target. Bare-identifier targets are unchanged.
Add DescribeObjectType::MaterializedView, an AlterTableType::MaterializedView
ALTER parser (RENAME / CLUSTER BY / DROP CLUSTERING KEY / SUSPEND / RESUME /
SET/UNSET SECURE|COMMENT|CONTACT|DATA_METRIC_SCHEDULE), and a materialized_view
marker on TRUNCATE so the emulator can distinguish an MV target.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an additive Expr::LikeAnyAll variant modelling
<subj> [NOT] {LIKE|ILIKE} {ANY|ALL} (p1, ..., pN) [ESCAPE e],
leaving the single-pattern Expr::Like / Expr::ILike shape untouched.
The LIKE/ILIKE infix parser now routes a parenthesized {ANY|ALL} (...)
list into the new variant.
Accept `@stage (FILE_FORMAT => …, PATTERN => …)` table-function args on the
FROM stage of a `COPY INTO <table> FROM (SELECT … FROM @stage (…))` load, and
carry them on a new `CopyIntoSnowflake::from_obj_args` field.
…nator

Accept CREATE [OR REPLACE] STREAM [IF NOT EXISTS] <name> ON VIEW <name> in
addition to ON TABLE <name>, and carry the source kind (Table vs View) on the
CreateStream AST node via a new StreamSourceKind enum. Display round-trips both
forms.
…/RELY)

Extend ConstraintCharacteristics with the remaining three Snowflake constraint
properties — { ENABLE | DISABLE }, { VALIDATE | NOVALIDATE } and
{ RELY | NORELY } — so they can be given in any order alongside DEFERRABLE /
INITIALLY / ENFORCED on inline column constraints, out-of-line table
constraints and ALTER TABLE ADD CONSTRAINT. Parsing is gated on a new
Dialect::supports_informational_constraint_properties hook (Snowflake only),
since ENABLE, DISABLE and VALIDATE are keywords used elsewhere. Display
round-trips the full set.

Also add TableConstraint::clear_characteristics(), for consumers whose target
dialect has no grammar for the characteristics Snowflake accepts.
Counterpart to TableConstraint::clear_characteristics for inline column
constraints, so a consumer targeting a dialect without the constraint
characteristics grammar can drop them from a column list in one call
instead of hand-matching the constraint-bearing ColumnOption variants.
Decode \ooo, \xhh and \uhhhh as Unicode code points, keep \0 as NUL,
collapse unrecognized letters (\a, \Z) to the bare letter, and raise a
tokenizer error on malformed \x / \u — gated behind a new
supports_snowflake_string_literal_escapes dialect capability so other
backslash-escaping dialects keep MySQL/BigQuery semantics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ame>

Add first-class UNDROP grammar for the statement family. VIEW parses so
the consumer can reject it with Snowflake's unsupported-feature error
rather than a parse error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

3 participants