feat: add DuckDB dialect support#2644
Open
adamatmotherduck wants to merge 4 commits intotaozhi8833998:masterfrom
Open
feat: add DuckDB dialect support#2644adamatmotherduck wants to merge 4 commits intotaozhi8833998:masterfrom
adamatmotherduck wants to merge 4 commits intotaozhi8833998:masterfrom
Conversation
Add a complete DuckDB SQL grammar and 107 tests covering DuckDB-specific
syntax. The grammar is based on the PostgreSQL dialect with extensive
modifications for DuckDB features.
Supported DuckDB-specific syntax:
- :: type casts (including array types like ::DATE[])
- QUALIFY clause (window function filtering)
- GROUP BY ALL / ORDER BY ALL
- SELECT * EXCLUDE (...) / REPLACE (...)
- PIVOT / UNPIVOT
- LIST() aggregate with ORDER BY
- Lambda expressions (x -> x + 1)
- Struct literals ({'key': value})
- List literals ([1, 2, 3])
- COLUMNS() expression
- UNION BY NAME / UNION ALL BY NAME
- ASOF JOIN, SEMI JOIN, ANTI JOIN, POSITIONAL JOIN
- INSERT INTO ... BY NAME
- INSERT OR REPLACE / INSERT OR IGNORE
- CREATE OR REPLACE TABLE
- IS NOT DISTINCT FROM
- COPY with subquery support
- FROM-first queries (FROM t WHERE ...)
- DESCRIBE, SUMMARIZE, ATTACH, DETACH
- DuckDB data types (HUGEINT, UBIGINT, BLOB, etc.)
- Composite types (STRUCT, MAP, LIST, UNION)
- PARTITION BY (col1, col2) tuple syntax
Test suite includes real-world query patterns from MotherDuck usage.
Closes taozhi8833998#1944
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add standalone PIVOT syntax (PIVOT table ON col USING aggr()) - Fix PARTITION BY tuple syntax ((col1, col2)) - Fix IS NOT DISTINCT FROM operator - Fix EXCLUDE + REPLACE combined syntax - Fix COPY with subquery (COPY (SELECT ...) TO ...) - Fix INSERT INTO ... BY NAME - Fix ::TYPE[] array type casts in cast_data_type - Add reserved keywords: ASOF, SEMI, ANTI, POSITIONAL, CROSS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When installed directly from GitHub (e.g. github:user/repo#branch), npm needs a prepare script to compile and bundle the parser. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The webpack config outputs to output/prod/build/ but package.json's files field expects build/ at the repo root. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a complete DuckDB SQL dialect to node-sql-parser, enabling parsing and SQL generation for DuckDB-specific syntax. This has been a highly requested feature (13 upvotes).
pegjs/duckdb.pegjs(based on PostgreSQL grammar with extensive DuckDB-specific additions)test/duckdb.spec.jscovering all added featuressrc/files (56 lines added across 8 files) with zero regressions to existing 1515 testsDuckDB-specific syntax supported
::type casts (incl. array)val::INTEGER,arr::DATE[]SELECT ... QUALIFY ROW_NUMBER() OVER (...) = 1SELECT col, SUM(x) FROM t GROUP BY ALLSELECT * EXCLUDE (col) REPLACE (expr AS col)FROM t PIVOT (SUM(x) FOR col IN ('a', 'b'))list_transform(arr, x -> x + 1){'key': value},[1, 2, 3]SELECT COLUMNS('pattern.*') FROM tSELECT * FROM t1 UNION BY NAME SELECT * FROM t2FROM t1 ASOF JOIN t2 ON ...INSERT INTO t BY NAME SELECT * FROM srcINSERT OR REPLACE INTO t ...t1.col IS NOT DISTINCT FROM t2.colCREATE OR REPLACE TABLE t AS SELECT ...COPY (SELECT ...) TO 'file.parquet' (FORMAT PARQUET)FROM t WHERE x > 1 LIMIT 10SUMMARIZE my_tableATTACH 'db.duckdb' AS mydbPARTITION BY (col1, col2)Files changed
pegjs/duckdb.pegjstest/duckdb.spec.jssrc/parser.all.jssrc/util.jssrc/column.jssrc/create.jssrc/expr.jssrc/insert.jssrc/sql.jssrc/union.jsTest plan
npm run buildsucceedsCloses #1944
🤖 Generated with Claude Code