Skip to content

Commit 5f7e289

Browse files
kyleconroyclaude
andcommitted
feat: add GoogleSQL support to sqlc parse
Add a googlesql dialect backed by github.com/sqlc-dev/zetajones, a pure-Go GoogleSQL/ZetaSQL parser that passes the entire upstream googlesql parser golden-test corpus. New files in internal/engine/googlesql/: - parse.go: Parser implementation using zetajones - convert.go: AST converter from zetajones to sqlc AST - utils.go: helpers (identifiers, string unquoting, type rendering) - catalog.go, stdlib.go: catalog initialization - reserved.go: reserved keywords (delegates to zetajones/token) Covers SELECT (joins, subqueries, CTEs, set ops, window functions), INSERT/UPDATE/DELETE (incl. THEN RETURN), CREATE/DROP/TRUNCATE TABLE, and expressions incl. named @params (mapped to the same A_Expr shape the PostgreSQL engine produces, so the named-parameter rewriter consumes them). Unsupported constructs convert to ast.TODO without panicking. Includes an end-to-end case at testdata/parse_basic/googlesql following the config-less exec.json harness. Usage: sqlc parse --dialect googlesql queries.sql Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c372419 commit 5f7e289

12 files changed

Lines changed: 1372 additions & 4 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ require (
2222
github.com/spf13/pflag v1.0.10
2323
github.com/sqlc-dev/doubleclick v1.0.0
2424
github.com/sqlc-dev/marino v0.1.0
25+
github.com/sqlc-dev/zetajones v0.1.0
2526
github.com/tetratelabs/wazero v1.12.0
2627
github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07
2728
github.com/xeipuuv/gojsonschema v1.2.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ github.com/sqlc-dev/doubleclick v1.0.0 h1:2/OApfQ2eLgcfa/Fqs8WSMA6atH0G8j9hHbQIg
7171
github.com/sqlc-dev/doubleclick v1.0.0/go.mod h1:ODHRroSrk/rr5neRHlWMSRijqOak8YmNaO3VAZCNl5Y=
7272
github.com/sqlc-dev/marino v0.1.0 h1:8Fn13vFhx7OUcmDFfRZdf3zARAbNl04Lcy74211ZpIw=
7373
github.com/sqlc-dev/marino v0.1.0/go.mod h1:mQxC2dgDE0DWHMb2B5jZNk7KToJuS6wnxnffBfYnq08=
74+
github.com/sqlc-dev/zetajones v0.1.0 h1:VeG0atx6lNABr9V2bSI5vL9DvOKTHX0XjMqWUE/rv40=
75+
github.com/sqlc-dev/zetajones v0.1.0/go.mod h1:dU1DxwqC6Cahbpnw16KpH1J2waWRDMdwyDSvovMZR4I=
7476
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
7577
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
7678
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=

internal/cmd/parse.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/sqlc-dev/sqlc/internal/engine/clickhouse"
1313
"github.com/sqlc-dev/sqlc/internal/engine/dolphin"
14+
"github.com/sqlc-dev/sqlc/internal/engine/googlesql"
1415
"github.com/sqlc-dev/sqlc/internal/engine/postgresql"
1516
"github.com/sqlc-dev/sqlc/internal/engine/sqlite"
1617
"github.com/sqlc-dev/sqlc/internal/metadata"
@@ -55,15 +56,18 @@ Examples:
5556
sqlc parse --dialect sqlite queries.sql
5657
5758
# Parse ClickHouse SQL
58-
sqlc parse --dialect clickhouse queries.sql`,
59+
sqlc parse --dialect clickhouse queries.sql
60+
61+
# Parse GoogleSQL (BigQuery, Spanner)
62+
sqlc parse --dialect googlesql queries.sql`,
5963
Args: cobra.MaximumNArgs(1),
6064
RunE: func(cmd *cobra.Command, args []string) error {
6165
dialect, err := cmd.Flags().GetString("dialect")
6266
if err != nil {
6367
return err
6468
}
6569
if dialect == "" {
66-
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, or clickhouse)")
70+
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, clickhouse, or googlesql)")
6771
}
6872

6973
// Determine input source
@@ -98,8 +102,10 @@ Examples:
98102
parser = sqlite.NewParser()
99103
case "clickhouse":
100104
parser = clickhouse.NewParser()
105+
case "googlesql":
106+
parser = googlesql.NewParser()
101107
default:
102-
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, or clickhouse)", dialect)
108+
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, clickhouse, or googlesql)", dialect)
103109
}
104110

105111
// Read the full source so each statement's name and command can be
@@ -143,6 +149,6 @@ Examples:
143149
return nil
144150
},
145151
}
146-
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, or clickhouse)")
152+
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, clickhouse, or googlesql)")
147153
return cmd
148154
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"command": "parse",
3+
"args": ["--dialect", "googlesql", "query.sql"],
4+
"contexts": ["base"]
5+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- name: GetValue :one
2+
SELECT 1;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
[
2+
{
3+
"ast": {
4+
"Stmt": {
5+
"DistinctClause": null,
6+
"IntoClause": null,
7+
"TargetList": {
8+
"Items": [
9+
{
10+
"Name": null,
11+
"Indirection": null,
12+
"Val": {
13+
"Val": {
14+
"Ival": 1
15+
},
16+
"Location": 30
17+
},
18+
"Location": 30
19+
}
20+
]
21+
},
22+
"FromClause": null,
23+
"WhereClause": null,
24+
"GroupClause": null,
25+
"HavingClause": null,
26+
"WindowClause": null,
27+
"ValuesLists": null,
28+
"SortClause": null,
29+
"LimitOffset": null,
30+
"LimitCount": null,
31+
"LockingClause": null,
32+
"WithClause": null,
33+
"Op": 0,
34+
"All": false,
35+
"Larg": null,
36+
"Rarg": null
37+
},
38+
"StmtLocation": 23,
39+
"StmtLen": 8
40+
}
41+
}
42+
]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package googlesql
2+
3+
import (
4+
"github.com/sqlc-dev/sqlc/internal/sql/catalog"
5+
)
6+
7+
func NewCatalog() *catalog.Catalog {
8+
def := "main" // GoogleSQL has no implicit schema; use "main" as the default
9+
return &catalog.Catalog{
10+
DefaultSchema: def,
11+
Schemas: []*catalog.Schema{
12+
defaultSchema(def),
13+
},
14+
Extensions: map[string]struct{}{},
15+
}
16+
}

0 commit comments

Comments
 (0)