Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ MYSQL_SERVER_URI="root:mysecretpassword@tcp(127.0.0.1:3306)/mysql?multiStatement
- `/postgresql/` - PostgreSQL parser and converter
- `/dolphin/` - MySQL parser (uses TiDB parser)
- `/sqlite/` - SQLite parser
- `/duckdb/` - DuckDB 2.0 parser (uses darkwing, the pure Go port of
DuckDB's PEG parser); its dialect seeds are generated by
`/internal/tools/sqlc-duckdb-gen` from a live DuckDB CLI
- `<engine>/dialect/` - The engine's type system and standard library, as
JSONL read by `/internal/core/seed`
- `/internal/core/` - The analysis core: catalog, analyzer and dialect seeds
Expand Down
2 changes: 1 addition & 1 deletion docs/howto/analyze.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ provided. The schema is always read from the `--schema` file.
## Flags

- `--dialect`, `-d` - The SQL dialect to use. One of `postgresql`, `mysql`,
`sqlite`, `clickhouse`, `googlesql`, or `mssql`. Required.
`sqlite`, `clickhouse`, `googlesql`, `mssql`, or `duckdb`. Required.
- `--schema`, `-s` - Path to the schema (DDL) file. Required.
- `--ast` - Include each statement's AST in the output. Defaults to `false`.

Expand Down
2 changes: 1 addition & 1 deletion docs/howto/parse.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ provided.
## Flags

- `--dialect`, `-d` - The SQL dialect to use. One of `postgresql`, `mysql`,
`sqlite`, `clickhouse`, `googlesql`, or `mssql`. Required.
`sqlite`, `clickhouse`, `googlesql`, `mssql`, or `duckdb`. Required.

## Examples

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/riza-io/grpc-go v0.2.0
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/sqlc-dev/darkwing v0.1.0
github.com/sqlc-dev/doubleclick v1.0.0
github.com/sqlc-dev/marino v0.3.0
github.com/sqlc-dev/meyer v0.1.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiT
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/sqlc-dev/darkwing v0.1.0 h1:P5dtJebmCiy10e6DcnBQ2d7Mwuz636obuSAzTlr/1Qo=
github.com/sqlc-dev/darkwing v0.1.0/go.mod h1:kPb+99a6U+oVWtLhsuvkuDb/YRm8deK6x+W/9mX6uug=
github.com/sqlc-dev/doubleclick v1.0.0 h1:2/OApfQ2eLgcfa/Fqs8WSMA6atH0G8j9hHbQIgMfAXI=
github.com/sqlc-dev/doubleclick v1.0.0/go.mod h1:ODHRroSrk/rr5neRHlWMSRijqOak8YmNaO3VAZCNl5Y=
github.com/sqlc-dev/marino v0.3.0 h1:e9cinBXJFFa3yRpokYNNinWvkewgd6XVDgnlG0bOmTw=
Expand Down
11 changes: 8 additions & 3 deletions internal/cmd/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ Examples:
# Analyze a SQL Server (T-SQL) query
sqlc analyze --dialect mssql --schema schema.sql query.sql

# Analyze a DuckDB query
sqlc analyze --dialect duckdb --schema schema.sql query.sql

# Analyze a query piped via stdin
echo "-- name: GetAuthor :one
SELECT * FROM authors WHERE id = $1;" | sqlc analyze --dialect postgresql --schema schema.sql
Expand All @@ -59,7 +62,7 @@ Examples:
return err
}
if dialect == "" {
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)")
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, clickhouse, googlesql, mssql, or duckdb)")
}

schemaPath, err := cmd.Flags().GetString("schema")
Expand Down Expand Up @@ -122,8 +125,10 @@ Examples:
engine = config.EngineGoogleSQL
case "mssql", "sqlserver":
engine = config.EngineMSSQL
case "duckdb":
engine = config.EngineDuckDB
default:
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)", dialect)
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, clickhouse, googlesql, mssql, or duckdb)", dialect)
}

sql := config.SQL{
Expand Down Expand Up @@ -165,7 +170,7 @@ Examples:
return nil
},
}
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)")
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, clickhouse, googlesql, mssql, or duckdb)")
cmd.Flags().StringP("schema", "s", "", "path to the schema file")
cmd.Flags().BoolP("ast", "", false, "include the statement AST in the output")
return cmd
Expand Down
14 changes: 10 additions & 4 deletions internal/cmd/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/sqlc-dev/sqlc/internal/engine/clickhouse"
"github.com/sqlc-dev/sqlc/internal/engine/dolphin"
"github.com/sqlc-dev/sqlc/internal/engine/duckdb"
"github.com/sqlc-dev/sqlc/internal/engine/googlesql"
"github.com/sqlc-dev/sqlc/internal/engine/mssql"
"github.com/sqlc-dev/sqlc/internal/engine/postgresql"
Expand Down Expand Up @@ -63,15 +64,18 @@ Examples:
sqlc parse --dialect googlesql queries.sql

# Parse SQL Server (T-SQL) SQL
sqlc parse --dialect mssql queries.sql`,
sqlc parse --dialect mssql queries.sql

# Parse DuckDB SQL
sqlc parse --dialect duckdb queries.sql`,
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
dialect, err := cmd.Flags().GetString("dialect")
if err != nil {
return err
}
if dialect == "" {
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)")
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, clickhouse, googlesql, mssql, or duckdb)")
}

// Determine input source
Expand Down Expand Up @@ -110,8 +114,10 @@ Examples:
parser = googlesql.NewParser()
case "mssql", "sqlserver":
parser = mssql.NewParser()
case "duckdb":
parser = duckdb.NewParser()
default:
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)", dialect)
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, clickhouse, googlesql, mssql, or duckdb)", dialect)
}

// Read the full source so each statement's name and command can be
Expand Down Expand Up @@ -155,6 +161,6 @@ Examples:
return nil
},
}
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, clickhouse, googlesql, or mssql)")
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, clickhouse, googlesql, mssql, or duckdb)")
return cmd
}
11 changes: 8 additions & 3 deletions internal/compiler/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/sqlc-dev/sqlc/internal/dbmanager"
"github.com/sqlc-dev/sqlc/internal/engine/clickhouse"
"github.com/sqlc-dev/sqlc/internal/engine/dolphin"
"github.com/sqlc-dev/sqlc/internal/engine/duckdb"
"github.com/sqlc-dev/sqlc/internal/engine/googlesql"
"github.com/sqlc-dev/sqlc/internal/engine/mssql"
"github.com/sqlc-dev/sqlc/internal/engine/postgresql"
Expand Down Expand Up @@ -58,10 +59,10 @@ func NewCompiler(conf config.SQL, combo config.CombinedSettings, parserOpts opts
o(c)
}

// ClickHouse, GoogleSQL and SQL Server have no legacy analysis path to
// fall back to.
// ClickHouse, GoogleSQL, SQL Server and DuckDB have no legacy analysis
// path to fall back to.
switch conf.Engine {
case config.EngineClickHouse, config.EngineGoogleSQL, config.EngineMSSQL:
case config.EngineClickHouse, config.EngineGoogleSQL, config.EngineMSSQL, config.EngineDuckDB:
c.coreAnalysis = true
}
if c.coreAnalysis {
Expand Down Expand Up @@ -144,6 +145,10 @@ func (c *Compiler) initCore() error {
c.parser = mssql.NewParser()
c.selector = newDefaultSelector()
dialect = mssql.Dialect()
case config.EngineDuckDB:
c.parser = duckdb.NewParser()
c.selector = newDefaultSelector()
dialect = duckdb.Dialect()
default:
return fmt.Errorf("unknown engine: %s", c.conf.Engine)
}
Expand Down
1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const (
EngineClickHouse Engine = "clickhouse"
EngineGoogleSQL Engine = "googlesql"
EngineMSSQL Engine = "mssql"
EngineDuckDB Engine = "duckdb"
)

type Config struct {
Expand Down
5 changes: 5 additions & 0 deletions internal/endtoend/testdata/analyze_basic/duckdb/exec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"command": "analyze",
"args": ["--dialect", "duckdb", "--schema", "schema.sql", "query.sql"],
"contexts": ["base"]
}
2 changes: 2 additions & 0 deletions internal/endtoend/testdata/analyze_basic/duckdb/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- name: ListAuthors :many
SELECT id, name, bio, royalties, created FROM authors;
7 changes: 7 additions & 0 deletions internal/endtoend/testdata/analyze_basic/duckdb/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE authors (
id BIGINT PRIMARY KEY,
name TEXT NOT NULL,
bio TEXT,
royalties DECIMAL(10,2) NOT NULL,
created TIMESTAMP NOT NULL
);
44 changes: 44 additions & 0 deletions internal/endtoend/testdata/analyze_basic/duckdb/stdout.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[
{
"name": "ListAuthors",
"cmd": ":many",
"columns": [
{
"name": "id",
"data_type": "bigint",
"not_null": true,
"is_array": false,
"table": "authors"
},
{
"name": "name",
"data_type": "text",
"not_null": true,
"is_array": false,
"table": "authors"
},
{
"name": "bio",
"data_type": "text",
"not_null": false,
"is_array": false,
"table": "authors"
},
{
"name": "royalties",
"data_type": "decimal",
"not_null": true,
"is_array": false,
"table": "authors"
},
{
"name": "created",
"data_type": "timestamp",
"not_null": true,
"is_array": false,
"table": "authors"
}
],
"params": []
}
]
5 changes: 5 additions & 0 deletions internal/endtoend/testdata/analyze_dml/duckdb/exec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"command": "analyze",
"args": ["--dialect", "duckdb", "--schema", "schema.sql", "query.sql"],
"contexts": ["base"]
}
13 changes: 13 additions & 0 deletions internal/endtoend/testdata/analyze_dml/duckdb/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- name: CreateAuthor :one
INSERT INTO authors (id, name, bio) VALUES ($1, $2, $3) RETURNING id;

-- name: UpdateAuthor :exec
UPDATE authors SET name = $name, bio = $bio WHERE id = $id;

-- name: DeleteBooksByAuthor :exec
DELETE FROM books USING authors a WHERE books.author_id = a.id AND a.name = $1;

-- name: TitlesFromBooks :many
INSERT INTO books (id, author_id, title)
SELECT id + 1000, author_id, upper(title) FROM books WHERE price > $min_price
RETURNING id, title;
12 changes: 12 additions & 0 deletions internal/endtoend/testdata/analyze_dml/duckdb/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CREATE TABLE authors (
id BIGINT PRIMARY KEY,
name TEXT NOT NULL,
bio TEXT
);

CREATE TABLE books (
id BIGINT PRIMARY KEY,
author_id BIGINT NOT NULL,
title TEXT NOT NULL,
price DECIMAL(10,2)
);
Loading
Loading