Skip to content

Commit 794f498

Browse files
committed
Add analyze support for GoogleSQL via zetajones
Wire the GoogleSQL (zetajones) engine into sqlc's native static analysis so `sqlc analyze --dialect googlesql` infers result columns and parameters from a schema, mirroring the existing PostgreSQL, MySQL, and SQLite support. Changes: - Add the `googlesql` engine constant and register its parser, catalog, and selector in the compiler. - Accept `googlesql` as an `analyze` dialect and document it (and the previously-undocumented `parse` dialect). - Keep named parameters in their native `@name` form when rewriting, since GoogleSQL supports named parameters (Spanner requires them), and quote identifiers with backticks during star expansion. - Include a statement's leading comment in its reported location so the `-- name:` annotation is captured; this also fixes name extraction for `sqlc parse --dialect googlesql`. - Initialize the list fields the compiler walks unconditionally (ReturningList, INSERT ... VALUES TargetList, UPDATE FromClause), fixing nil-pointer panics when analyzing INSERT/UPDATE/DELETE statements. Add end-to-end coverage for basic SELECT analysis and for INSERT/UPDATE/DELETE (including THEN RETURN). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CmGTScco7g1CNc5LjPSJVd
1 parent e209d86 commit 794f498

18 files changed

Lines changed: 254 additions & 19 deletions

File tree

docs/howto/analyze.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ provided. The schema is always read from the `--schema` file.
1818

1919
## Flags
2020

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

docs/howto/parse.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ provided.
2020
## Flags
2121

2222
- `--dialect`, `-d` - The SQL dialect to use. One of `postgresql`, `mysql`,
23-
`sqlite`, or `clickhouse`. Required.
23+
`sqlite`, `clickhouse`, or `googlesql`. Required.
2424

2525
## Examples
2626

internal/cmd/analyze.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ Examples:
3737
# Analyze a SQLite query
3838
sqlc analyze --dialect sqlite --schema schema.sql query.sql
3939
40+
# Analyze a GoogleSQL (BigQuery, Spanner) query
41+
sqlc analyze --dialect googlesql --schema schema.sql query.sql
42+
4043
# Analyze a query piped via stdin
4144
echo "-- name: GetAuthor :one
4245
SELECT * FROM authors WHERE id = $1;" | sqlc analyze --dialect postgresql --schema schema.sql
@@ -50,7 +53,7 @@ Examples:
5053
return err
5154
}
5255
if dialect == "" {
53-
return fmt.Errorf("--dialect flag is required (postgresql, mysql, or sqlite)")
56+
return fmt.Errorf("--dialect flag is required (postgresql, mysql, sqlite, or googlesql)")
5457
}
5558

5659
schemaPath, err := cmd.Flags().GetString("schema")
@@ -107,8 +110,10 @@ Examples:
107110
engine = config.EngineMySQL
108111
case "sqlite":
109112
engine = config.EngineSQLite
113+
case "googlesql":
114+
engine = config.EngineGoogleSQL
110115
default:
111-
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, or sqlite)", dialect)
116+
return fmt.Errorf("unsupported dialect: %s (use postgresql, mysql, sqlite, or googlesql)", dialect)
112117
}
113118

114119
sql := config.SQL{
@@ -150,7 +155,7 @@ Examples:
150155
return nil
151156
},
152157
}
153-
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, or sqlite)")
158+
cmd.Flags().StringP("dialect", "d", "", "SQL dialect to use (postgresql, mysql, sqlite, or googlesql)")
154159
cmd.Flags().StringP("schema", "s", "", "path to the schema file")
155160
cmd.Flags().BoolP("ast", "", false, "include the statement AST in the output")
156161
return cmd

internal/compiler/engine.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/sqlc-dev/sqlc/internal/config"
99
"github.com/sqlc-dev/sqlc/internal/dbmanager"
1010
"github.com/sqlc-dev/sqlc/internal/engine/dolphin"
11+
"github.com/sqlc-dev/sqlc/internal/engine/googlesql"
1112
"github.com/sqlc-dev/sqlc/internal/engine/postgresql"
1213
pganalyze "github.com/sqlc-dev/sqlc/internal/engine/postgresql/analyzer"
1314
"github.com/sqlc-dev/sqlc/internal/engine/sqlite"
@@ -82,6 +83,10 @@ func NewCompiler(conf config.SQL, combo config.CombinedSettings, parserOpts opts
8283
c.parser = dolphin.NewParser()
8384
c.catalog = dolphin.NewCatalog()
8485
c.selector = newDefaultSelector()
86+
case config.EngineGoogleSQL:
87+
c.parser = googlesql.NewParser()
88+
c.catalog = googlesql.NewCatalog()
89+
c.selector = newDefaultSelector()
8590
case config.EnginePostgreSQL:
8691
parser := postgresql.NewParser()
8792
c.parser = parser

internal/compiler/expand.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (c *Compiler) quoteIdent(ident string) string {
7171

7272
func (c *Compiler) quote(x string) string {
7373
switch c.conf.Engine {
74-
case config.EngineMySQL:
74+
case config.EngineMySQL, config.EngineGoogleSQL:
7575
return "`" + x + "`"
7676
default:
7777
return "\"" + x + "\""

internal/config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const (
5454
EngineMySQL Engine = "mysql"
5555
EnginePostgreSQL Engine = "postgresql"
5656
EngineSQLite Engine = "sqlite"
57+
EngineGoogleSQL Engine = "googlesql"
5758
)
5859

5960
type Config struct {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"command": "analyze",
3+
"args": ["--dialect", "googlesql", "--schema", "schema.sql", "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: GetUser :one
2+
SELECT id, name FROM users WHERE id = @id;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CREATE TABLE users (
2+
id INT64 NOT NULL,
3+
name STRING NOT NULL,
4+
bio STRING,
5+
) PRIMARY KEY (id);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[
2+
{
3+
"name": "GetUser",
4+
"cmd": ":one",
5+
"columns": [
6+
{
7+
"name": "id",
8+
"data_type": "int64",
9+
"not_null": true,
10+
"is_array": false,
11+
"table": "users"
12+
},
13+
{
14+
"name": "name",
15+
"data_type": "string",
16+
"not_null": true,
17+
"is_array": false,
18+
"table": "users"
19+
}
20+
],
21+
"params": [
22+
{
23+
"number": 1,
24+
"column": {
25+
"name": "id",
26+
"data_type": "int64",
27+
"not_null": true,
28+
"is_array": false,
29+
"table": "users"
30+
}
31+
}
32+
]
33+
}
34+
]

0 commit comments

Comments
 (0)