Skip to content

Parity — v0.1.6

Every row below is a statement real Snowflake accepts, run against the image this repository builds. 🟢 means the emulator answered it; 🔴 means it refused, by name, with the reason recorded.

A refusal is not a bug in itself — this family would rather fail honestly than answer wrongly. A 🔴 with a reason is a gap someone can plan around; a silent success is one nobody can see.

Every 🟢 names a witness in docs/witnesses.json, which is generated from the same run.

FeatureDetailStatus
Seeded PAT🟢
Session context functions🟢
FeatureDetailStatus
SELECT, CTE, window🟢
QUALIFY🟢
TRY_CAST🟢
IFF / NVL / NVL2 / ZEROIFNULL🟢
TO_DATE / TO_VARCHAR / TO_TIMESTAMP🟢
DATEDIFF🟢
DATEADDDAY, WEEK, HOUR, MINUTE and SECOND. MONTH, QUARTER and YEAR are refused: every DuckDB spelling of them widens a DATE to a TIMESTAMP, and a CASE cannot return two types, so the answer would carry the wrong type for a DATE argument. A TIMESTAMP given to the day form is an error here where Snowflake would answer.🟢
GENERATOR / SEQ4🟢
A date series, the way core’s silver builds one🟢
DATEADD(month, …) is refused🟢
LISTAGG / ARRAY_AGG🟢
MERGEduckdb: Parser Error: syntax error at or near “MERGE”🔴
Decimal keeps its scale🟢
NULL is null, not a word🟢
Unparseable SQL is refused🟢
FeatureDetailStatus
VARIANT columns🟢
Colon path🟢
Colon path with a cast🟢
LATERAL FLATTEN over VARIANTvalue and index only. SEQ, KEY, PATH and THIS are not produced, and OUTER, RECURSIVE, PATH and MODE are refused by name because each changes which rows come back.🟢
LATERAL FLATTEN over an array🟢
ARRAY_GENERATE_RANGE🟢
PARSE_JSON🟢
OBJECT_CONSTRUCTduckdb: Catalog Error: Scalar Function with name object_construct does not exist!🔴
FeatureDetailStatus
CREATE STAGE🟢
LISTWalks the whole stage directory, so a named stage created inside it appears in the user stage’s listing.🟢
CREATE FILE FORMAT🟢
COPY INTO from an internal stage🟢
COPY INTO with a named format🟢
COPY INTO JSON🟢
External stages are refused🟢
An unsupported format option is refused🟢
PUTduckdb: Parser Error: syntax error at or near “PUT” — A client-side upload protocol. This emulator takes the bytes from SNOWFLAKE_STAGE_DIR instead.🔴
REMOVEduckdb: Parser Error: syntax error at or near “REMOVE”🔴
INFER_SCHEMAduckdb: Parser Error: syntax error at or near “TABLE”🔴
FeatureDetailStatus
SHOW TABLES🟢
DESCRIBE TABLE🟢
information_schema.columns🟢
SHOW FUNCTIONS🟢
CREATE SCHEMA🟢
Time Travelduckdb: Parser Error: syntax error at or near “OFFSET”🔴
CLONEduckdb: Parser Error: syntax error at or near “CLONE”🔴
GRANT / rolesduckdb: Parser Error: syntax error at or near “GRANT”🔴
FeatureDetailStatus
CREATE TASKSCHEDULE takes ’ SECOND | MINUTE | HOUR’. USING CRON is refused by name — a cron expression means specific wall-clock times, and firing on an interval instead would be a schedule that is not the one asked for. WHEN is refused for the same reason in the other direction: a predicate that is never evaluated makes a conditional task unconditional.🟢
Task graphs (AFTER)🟢
ALTER TASK RESUME / SUSPEND🟢
SHOW TASKS🟢
EXECUTE TASKRuns the named task and everything downstream of it, as Snowflake does. A resumed root task also fires on its own interval. TASK_HISTORY() is not implemented.🟢
DROP TASK🟢
USING CRON is refused🟢
A task with neither SCHEDULE nor AFTER is refused🟢
CREATE STREAMAPPEND-ONLY, and it proves it rather than assuming it. DuckDB keeps no change log, so the stream remembers the first rowid it has not shown and a checksum of the rows it has. If a row before that point is updated or deleted the stream REFUSES TO BE READ, naming what happened — Snowflake would report those as DELETE and INSERT rows, and answering without them would silently drop the change. METADATA$ACTION is always INSERT for the same reason.🟢
Reading a stream🟢
SYSTEM$STREAM_HAS_DATA🟢
SHOW STREAMS🟢
DROP STREAM🟢
Stored proceduresduckdb: Catalog Error: Table Function with name system$wait does not exist!🔴
FeatureDetailStatus
CREATE / SHOW / SUSPEND🟢

50 of 59 answered.