Skip to content

fix(snowflake): accept column list after CREATE DYNAMIC TABLE options - #90

Merged
lustefaniak merged 1 commit into
mainfrom
lukasz-snowflake-dynamic-table-column-list
Jun 18, 2026
Merged

fix(snowflake): accept column list after CREATE DYNAMIC TABLE options#90
lustefaniak merged 1 commit into
mainfrom
lukasz-snowflake-dynamic-table-column-list

Conversation

@lustefaniak

Copy link
Copy Markdown
Collaborator

Summary

Snowflake permits the column-definition list to appear after the options header (TARGET_LAG / WAREHOUSE / REFRESH_MODE / INITIALIZE) rather than before it. This form is what generator-emitted dynamic-table DDL uses, and it previously failed to parse with Expected end of statement, found: <TYPE>.

CREATE OR REPLACE DYNAMIC TABLE t
TARGET_LAG ='100000 Days'
WAREHOUSE = COMPUTE_WH
REFRESH_MODE = AUTO
INITIALIZE = ON_CREATE
( "SYSTEM_CREATE_DATE" TIMESTAMP_NTZ(9), "ID"VARCHAR(256), ... )
ASSELECT ...

Root cause

Two issues, both in parse_create_table:

  • The bare-word option value (e.g. INITIALIZE = ON_CREATE) was parsed with parse_expr, which greedily treated the trailing column-list ( as a function call on the value word — swallowing ON_CREATE ( "col" TYPE, ... ). Bare-word option values are now parsed as a plain identifier so the ( is left intact.
  • Nothing picked up a column list that appears after the options loop. The up-front parse_columns() runs before the options and saw the first option keyword, not (. A new arm in the options loop parses the column list when it follows the options.

Coverage

New tests cover: column list + AS SELECT, column-list-only (no AS), the no-whitespace "col"TYPE form, and the types TIMESTAMP_NTZ / TIMESTAMP_TZ / NUMBER / VARCHAR / DATE / BOOLEAN. Full suite green (1187 tests); corpus run shows 0 regressions.

https://claude.ai/code/session_012hHZLhjkLPneyPz7jpMWFS

…BLE options
Snowflake allows the column-definition list to appear after the options
header (TARGET_LAG / WAREHOUSE / REFRESH_MODE / INITIALIZE) rather than
before it:
CREATE OR REPLACE DYNAMIC TABLE t
TARGET_LAG = '...' WAREHOUSE = wh REFRESH_MODE = AUTO INITIALIZE = ON_CREATE
( "col" TIMESTAMP_NTZ(9), "id" VARCHAR(256), ... )
AS SELECT ...
This previously failed with "Expected end of statement, found: <TYPE>"
for two reasons:
- The bare-word option value (e.g. INITIALIZE = ON_CREATE) was parsed
with parse_expr, which greedily treated the following column-list `(`
as a function call on the value word. Bare-word option values are now
parsed as a plain identifier so the `(` is left for the column list.
- Nothing picked up a column list appearing after the options loop. The
up-front parse_columns() ran before the options and saw the first
option keyword, not `(`. A new arm in the options loop parses the
column list when it follows the options.
Both the `( ... ) AS SELECT` and column-list-only forms are covered, as
is the no-whitespace `"col"TYPE` form generators emit.
Claude-Session: https://claude.ai/code/session_012hHZLhjkLPneyPz7jpMWFS
@github-actions

github-actionsBot commented Jun 18, 2026

Copy link
Copy Markdown

Corpus Parsing Report

Total: 191713 passed, 1920 failed (99.0% pass rate)

✨ No changes in test results

By Dialect

DialectPassedFailedTotalPass RateDelta
ansi5116958088.1%-
athena3713897.4%-
bigquery423241134243799.7%-
clickhouse2723129285295.5%-
databricks2965184314994.2%-
doris28124070.0%-
dremio27027100.0%-
duckdb112445116996.2%-
exasol5476188.5%-
fabric606100.0%-
generic17385530.9%-
hive35104577.8%-
materialize6142030.0%-
mssql2276407268384.8%-
mysql1513718880.3%-
oracle1046352139874.8%-
postgres1172111128391.3%-
presto5586387.3%-
redshift40503654056899.8%-
singlestore141915094.0%-
snowflake947411389487999.9%+2
spark902011081.8%-
sqlite51166776.1%-
starrocks2943387.9%-
teradata23204353.5%-
trino141377149094.8%-
tsql1653419982.9%-

@lustefaniak
lustefaniak merged commit e81eaa1 into mainJun 18, 2026
5 checks passed
@lustefaniak
lustefaniak deleted the lukasz-snowflake-dynamic-table-column-list branch June 18, 2026 10:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@lustefaniak@grasskode