Snowflake SQL Formatter
Format Snowflake SQL with QUALIFY, FLATTEN, VARIANT paths and time travel clauses laid out properly.
Your Snowflake SQL
Formatted Snowflake SQL
Snowflake queries have a particular shape: raw semi-structured data in a VARIANT column, a LATERAL FLATTEN to expand an array inside it, colon paths and :: casts to pull typed values out, and a QUALIFY at the bottom to keep one row per key. Written on one line it is dense; broken into clauses it reads as the four-step pipeline it actually is.
With the Snowflake dialect selected, the formatter recognises all of that syntax as first-class, including the time travel clauses that make a table reference carry a point in history. Everything runs locally — Snowflake queries tend to be full of real table names and identifiers, and none of it leaves your browser.
How to use the snowflake formatter
- 1
Paste the query
From a Snowsight worksheet, a dbt model, a task definition or the query history.
- 2
Format and check the QUALIFY and the FLATTEN
Those two clauses control your row count. Once they are on their own lines, an unintended fan-out from a
FLATTENis much easier to spot. - 3
Copy back into the worksheet or your model
Plain text output with no markup, ready to paste anywhere.
Snowflake syntax the formatter treats as its own clause
QUALIFY. Given its own top-level line alongsideWHERE,GROUP BYandHAVING, which is exactly where it belongs logically:QUALIFYfilters on the result of a window function after it has been computed, the wayHAVINGfilters on aggregates. Without it, the same deduplication needs a subquery wrapping the whole select.LATERAL FLATTEN. The table function that expands an array or object inside aVARIANT. It is printed in theFROMlist beside the other sources, with theinput =>named argument kept on the same line, so the fan-out it introduces is visible.- VARIANT colon paths.
payload:order_id::stringcombines a colon path into semi-structured data with a cast to a real type. Both are kept glued to the expression rather than spaced out as operators —payload:items[0].skustays in one piece too. - Time travel.
AT(TIMESTAMP => …),AT(OFFSET => …),BEFORE(STATEMENT => …)andCLONE … BEFORE(…)are parsed as part of the table reference. One quirk: withOFFSETthe argument is broken onto extra lines, becauseOFFSETis also a pagination keyword. Using theTIMESTAMPform when you can gives cleaner output. - Semi-structured functions.
PARSE_JSON,OBJECT_CONSTRUCT,ARRAY_AGGand the rest format like ordinary function calls, with nested arguments indented.
Time travel is a table-reference modifier
It is easy to read AT and BEFORE as clauses of the query. They are not — they attach to a single table reference and change which version of that table is read. That means different tables in the same query can be read at different points in time, which is occasionally exactly what you want and occasionally the bug.
Formatting puts each source on its own line in the FROM list, so a stray time travel modifier on one of three joined tables becomes visible. Retention is a property of the account and table, not the query: the default window is one day, extendable up to ninety on Enterprise editions, and a query asking for a point outside it fails rather than approximating.
Warehouse cost, and what a formatter cannot change
Snowflake bills warehouse credits by size and uptime, with per-second billing after a sixty-second minimum. What drives that bill is data scanned, spilling to remote storage, and how long a warehouse stays awake — not how your SQL is laid out. Formatting has no effect on credit consumption. The parser strips whitespace before planning.
What it does affect is the review step before the query runs. Pruning depends on the filters in your WHERE clause matching the table clustering; a query whose predicates each sit on their own line is one you can check against the clustering key in a few seconds. For the actual numbers, the query profile and QUERY_HISTORY are the sources of truth, and this tool has no access to either — it never connects to an account.
Snowflake Formatter FAQ
Does it understand QUALIFY?
Yes. QUALIFY is recognised as a top-level clause and printed alongside WHERE and GROUP BY, with the window function expression indented beneath it.
Will my VARIANT colon paths survive formatting?
Yes. Expressions like payload:items[0].sku::string are kept as a single expression with no spaces inserted around the colon, the bracket subscript or the cast.
Why does AT(OFFSET => -300) come out on several lines?
Because OFFSET is also a pagination keyword and the tokeniser gives it clause-level treatment. The query is unchanged. If the layout bothers you, the TIMESTAMP form of time travel formats cleanly.
Can it format a Snowflake stored procedure?
It formats the SQL statements. A procedure body written in JavaScript, Python or Snowflake Scripting is a different language, and the formatter does not attempt to lay out its control flow.
Does the tool connect to my Snowflake account?
No. There is no credential field and no network call. It is a text tool that runs in your browser and never sees your data or your warehouse.
