Getting Started
Quickstart
Install SQLQuack, check a file and convert it to DuckDB SQL.
Install
Section titled “Install”SQLQuack installs from PyPI with Python 3.12 or newer. The package ships the sqlquack command and
the Python library, with DuckDB’s library beside them.
pip install sqlquacksqlquack --versionBuild from source
Section titled “Build from source”To build the command line from the repository instead, use Rust. The repository pins its toolchain
in rust-toolchain.toml, which rustup installs on first use.
git clone https://github.com/sqlstack-io/sqlquackcd sqlquackcargo build --release -p sqlquackThe binary links DuckDB’s prebuilt shared library, which the build downloads to
target/duckdb-download/<target triple>/<DuckDB version>. cargo run puts it on the library path
for you:
cargo run --release -p sqlquack -- check query.sqlTo run target/release/sqlquack directly, point the library path at that directory:
LD_LIBRARY_PATH=target/duckdb-download/x86_64-unknown-linux-gnu/v2.0.0 target/release/sqlquack check query.sqlUse DYLD_LIBRARY_PATH on macOS and PATH on Windows.
Check a file
Section titled “Check a file”check needs no schema. It parses the SQL and reports what Snowflake would reject.
-- orders.sqlSELECT customer_id, SUM(total) AS revenueFROM ordersWHERE status = 'shipped'GROUP BY customer_idQUALIFY revenue > 100$ sqlquack check orders.sqlerror[SQ0203]: QUALIFY needs a window function --> orders.sql:5:1 |5 | QUALIFY revenue > 100 | ^^^^^^^^^^^^^^^^^^^^^ QUALIFY is used without a window function in the SELECT list or QUALIFY | = help: move the condition to WHERE or HAVING, or filter on a window function's resultsqlquack check: found 1 problemMove the condition to HAVING SUM(total) > 100 and check reports no problems.
Convert a file
Section titled “Convert a file”Conversion types every expression, so it needs the columns and Snowflake types of the relations a statement reads. Declare them in a schema file:
{ "ORDERS": [ ["ORDER_ID", "NUMBER(38,0)"], ["CUSTOMER_ID", "NUMBER(38,0)"], ["STATUS", "VARCHAR"], ["TOTAL", "NUMBER(12,2)"], ["ORDERED_AT", "TIMESTAMP_NTZ"] ]}$ sqlquack convert revenue.sql --schema schema.json --builtin-policySELECT "ORDERS"."CUSTOMER_ID" AS "CUSTOMER_ID", CAST(sum("ORDERS"."TOTAL") AS DECIMAL(24,2)) AS "REVENUE"FROM "ORDERS" AS "ORDERS"WHERE ("ORDERS"."STATUS" = 'shipped')GROUP BY "ORDERS"."CUSTOMER_ID"sqlquack convert: done, converted under the built-in defaultThe DuckDB SQL goes to standard output and the progress lines to standard error, so
sqlquack convert revenue.sql … > revenue.duckdb.sql keeps only the SQL.
convert reads sqlquack.toml from the current directory, or the file --policy names. Without
one, or with --builtin-policy, it uses the built-in policy, which refuses every known divergence
but the clock (CURRENT_DATE() and CURRENT_TIMESTAMP() convert with a warning).
See Policy and sessions.
Next steps
Section titled “Next steps”- Reading diagnostics: the output format and JSON fields.
sqlquack census: measure how much of a project converts.- Playground: try SQL in the browser.