Reference
Accepted SQL

Accepted SQL

Thunderduck runs DuckDB's dialect. Every statement is classified before the engine sees it, and a refusal is structured — read it rather than retrying variations.

Always allowed

SELECT, plus DESCRIBE, SHOW TABLES and read-only pragmas, which the parser treats as selects.

Allowed when the caller can write

INSERT, UPDATE, DELETE, CREATE, DROP, ALTER — subject to the catalog being writable and, for API and AI callers, the token carrying a write scope.

Never allowed

ATTACH, COPY, non-read PRAGMA, SET, INSTALL/LOAD, CALL, EXPORT, VACUUM, CREATE SECRET, explicit transactions, and the query() and getenv() functions. These reconfigure the engine rather than touching data; permission to change data is not permission to reconfigure the engine that runs it.

EXPLAIN

EXPLAIN <stmt> is unwrapped and the inner statement judged by these same rules, because EXPLAIN ANALYZE <stmt> genuinely executes the statement. For a plan without execution, use the cost estimate instead.

Reading files

read_csv, read_parquet, read_json, read_xlsx and friends accept a catalog/path first argument, which is rewritten to the catalog's bucket with its own credentials.

Local filesystem paths and arbitrary URLs are rejected — in a subquery or a CREATE TABLE … AS SELECT just as in a bare SELECT. A path must start with one of your catalog names; anything else is refused, as are computed paths ('raw/' || name). Reference a catalog rather than a path, and if the data lives in object storage, register it as a catalog once instead of pasting a URL into every query.

Path and function rules

  • A read path must start with a catalog name.
  • No ? or # in paths, so DuckDB's ? single-character glob is not available; use * or [...]. No .. segments either.
  • No line may start with .; write 0.5, not .5.
  • Table functions are an allowlist: read_csv, read_csv_auto, read_parquet, parquet_scan, read_json, read_json_auto, read_ndjson, read_ndjson_auto, read_text, read_xlsx, glob, clickhouse_query, range, generate_series, unnest, repeat, histogram, and the metadata functions duckdb_tables, duckdb_columns, duckdb_views, duckdb_schemas, duckdb_databases, duckdb_types, duckdb_constraints, duckdb_indexes, duckdb_functions and duckdb_keywords. duckdb_secrets, duckdb_settings and duckdb_extensions are not available.
  • Passthrough functions such as postgres_query and bigquery_query cannot be called directly; pushdown to those engines is automatic.
  • S3, GCS and Azure catalogs without their own credentials cannot be read.
  • ClickHouse catalogs must use a public DNS hostname, not an IP address or an internal name.

Syntax vs binding

A syntax error fails immediately, in the response. A binding error — unknown table, unknown column — arrives a moment later as a failed query, because resolving names requires your catalog credentials, and those are only opened where the query actually runs.