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.
| Feature | Detail | Status |
|---|
| Seeded PAT | | 🟢 |
| Session context functions | | 🟢 |
| Feature | Detail | Status |
|---|
| SELECT, CTE, window | | 🟢 |
| QUALIFY | | 🟢 |
| TRY_CAST | | 🟢 |
| IFF / NVL / NVL2 / ZEROIFNULL | | 🟢 |
| TO_DATE / TO_VARCHAR / TO_TIMESTAMP | | 🟢 |
| DATEDIFF | | 🟢 |
| DATEADD | DAY, 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 | | 🟢 |
| MERGE | duckdb: Parser Error: syntax error at or near “MERGE” | 🔴 |
| Decimal keeps its scale | | 🟢 |
| NULL is null, not a word | | 🟢 |
| Unparseable SQL is refused | | 🟢 |
| Feature | Detail | Status |
|---|
| VARIANT columns | | 🟢 |
| Colon path | | 🟢 |
| Colon path with a cast | | 🟢 |
| LATERAL FLATTEN over VARIANT | value 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_CONSTRUCT | duckdb: Catalog Error: Scalar Function with name object_construct does not exist! | 🔴 |
| Feature | Detail | Status |
|---|
| CREATE STAGE | | 🟢 |
| LIST | Walks 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 | | 🟢 |
| A prefix is refused | Real Snowflake resolves a stage reference by prefix and loads EVERY file under it, which is the ordinary way to load a paged feed. This resolves one name and the .gz AUTO_COMPRESS leaves, so a prefix is refused BY NAME. It used to come back as duckdb’s own words about a path inside the container, which left the reader to work out that the feature was missing rather than the file. | 🟢 |
| PUT | The driver uploads the bytes itself, as it does against a real account: the answer names LOCAL_FS and the stage directory, and the connector’s file transfer agent does the copying. AUTO_COMPRESS defaults to TRUE, so the stage holds <name>.gz. Set SNOWFLAKE_STAGE_CLIENT_DIR when the client sees the stage at a different path than the server does. | 🟢 |
| REMOVE | duckdb: Parser Error: syntax error at or near “REMOVE” | 🔴 |
| INFER_SCHEMA | duckdb: Parser Error: syntax error at or near “TABLE” | 🔴 |
| Feature | Detail | Status |
|---|
| TASK_HISTORY | | 🟢 |
| Feature | Detail | Status |
|---|
| SHOW TABLES | | 🟢 |
| DESCRIBE TABLE | | 🟢 |
| information_schema.columns | | 🟢 |
| SHOW FUNCTIONS | | 🟢 |
| CREATE SCHEMA | | 🟢 |
| Time Travel | duckdb: Parser Error: syntax error at or near “OFFSET” | 🔴 |
| CLONE | duckdb: Parser Error: syntax error at or near “CLONE” | 🔴 |
| GRANT / roles | duckdb: Parser Error: syntax error at or near “GRANT” | 🔴 |
| Feature | Detail | Status |
|---|
| CREATE TASK | SCHEDULE 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 TASK | Runs the named task and everything downstream of it, as Snowflake does. A resumed root task also fires on its own interval. Its runs, and the runs of everything downstream, are readable through TASK_HISTORY(). | 🟢 |
| DROP TASK | | 🟢 |
| USING CRON is refused | | 🟢 |
| A manual task (no SCHEDULE, no AFTER) | | 🟢 |
| EXECUTE TASK on a manual task | | 🟢 |
| CREATE STREAM | APPEND-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 procedures | duckdb: Catalog Error: Table Function with name system$wait does not exist! | 🔴 |
| Feature | Detail | Status |
|---|
| CREATE / SHOW / SUSPEND | | 🟢 |
54 of 62 answered.