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
86 changes: 86 additions & 0 deletions .github/workflows/gen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,89 @@ jobs:
path: internal/engine/sqlite/dialect
- name: Fail if the committed dialect differs
run: git add -N internal/engine/sqlite && git diff --exit-code --stat -- internal/engine/sqlite

mssql:
name: generate mssql dialect
runs-on: ubuntu-24.04
services:
mssql:
image: mcr.microsoft.com/mssql/server:2025-latest
env:
ACCEPT_EULA: Y
MSSQL_SA_PASSWORD: Mysecretpassword1!
ports:
- 1433:1433
options: --health-cmd "/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P 'Mysecretpassword1!' -Q 'SELECT 1'" --health-interval 10s --health-timeout 5s --health-retries 10
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version-file: internal/goldeneye/go.mod
check-latest: true
- run: go run ./cmd/goldeneye generate mssql
working-directory: internal/goldeneye
env:
MSSQL_SERVER_URI: sqlserver://sa:Mysecretpassword1!@localhost:${{ job.services.mssql.ports['1433'] }}?encrypt=disable
- name: Save results
uses: actions/upload-artifact@v7
with:
name: dialect-mssql
path: internal/engine/mssql/dialect
- name: Fail if the committed dialect differs
run: git add -N internal/engine/mssql && git diff --exit-code --stat -- internal/engine/mssql

spanner:
name: generate googlesql dialect
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version-file: internal/goldeneye/go.mod
check-latest: true
# Spanner Omni is run the way its quickstart runs it, on the host
# network, since a service container cannot be given a command.
- name: Start Spanner Omni
run: |
docker run -d --name spanneromni --network host us-docker.pkg.dev/spanner-omni/images/spanner-omni:2026.r2.1-beta start-single-server
for i in $(seq 1 60); do
if docker exec spanneromni /google/spanner/bin/spanner databases list >/dev/null 2>&1; then exit 0; fi
sleep 5
done
docker logs spanneromni
exit 1
- run: go run ./cmd/goldeneye generate spanner
working-directory: internal/goldeneye
env:
SPANNER_SERVER_URI: localhost:15000
- name: Save results
uses: actions/upload-artifact@v7
with:
name: dialect-googlesql
path: internal/engine/googlesql/dialect
- name: Fail if the committed dialect differs
run: git add -N internal/engine/googlesql && git diff --exit-code --stat -- internal/engine/googlesql

duckdb:
name: generate duckdb dialect
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version-file: internal/goldeneye/go.mod
check-latest: true
# The current build of DuckDB's v2.0 preview channel, until 2.0 is
# released: a later build than the dialect was generated from shows up
# as a difference.
- run: go run ./cmd/goldeneye install duckdb
working-directory: internal/goldeneye
- run: go run ./cmd/goldeneye generate duckdb
working-directory: internal/goldeneye
- name: Save results
uses: actions/upload-artifact@v7
with:
name: dialect-duckdb
path: internal/engine/duckdb/dialect
- name: Fail if the committed dialect differs
run: git add -N internal/engine/duckdb && git diff --exit-code --stat -- internal/engine/duckdb
10 changes: 7 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,19 @@ from a live database by `/internal/goldeneye`, a nested module, and its tests
verify the committed files against one byte for byte. The same module checks
the `analyze_*` cases under `/internal/endtoend/testdata/` against what the
database itself reports for them, so a `fixture.sql` next to a case's schema
gives the queries rows to run against. ClickHouse, MySQL and SQLite have the
check today; engines whose database is not available skip.
gives the queries rows to run against. ClickHouse, DuckDB, MySQL, SQLite,
SQL Server and Spanner have the check today; engines whose database is not
available skip.

```bash
cd internal/goldeneye
go run ./cmd/goldeneye install clickhouse # download the pinned clickhouse binary once
go run ./cmd/goldeneye install duckdb # download the current DuckDB 2.0 preview build once
go run ./cmd/goldeneye install sqlite # build the pinned sqlite3 shells once; needs a C compiler
POSTGRESQL_SERVER_URI="postgres://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable" \
MYSQL_SERVER_URI="root:mysecretpassword@tcp(127.0.0.1:3306)/mysql" go test ./...
MYSQL_SERVER_URI="root:mysecretpassword@tcp(127.0.0.1:3306)/mysql" \
MSSQL_SERVER_URI="sqlserver://sa:Mysecretpassword1!@127.0.0.1:1433?encrypt=disable" \
SPANNER_SERVER_URI="localhost:15000" go test ./...
go run ./cmd/goldeneye generate postgresql # rewrite the files after a change
```

Expand Down
18 changes: 18 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,21 @@ services:
POSTGRES_DB: postgres
POSTGRES_PASSWORD: mysecretpassword
POSTGRES_USER: postgres

mssql:
image: "mcr.microsoft.com/mssql/server:2025-latest"
ports:
- "1433:1433"
restart: always
environment:
ACCEPT_EULA: "Y"
MSSQL_SA_PASSWORD: "Mysecretpassword1!"

# Spanner Omni, the downloadable Spanner, serves plaintext gRPC on port
# 15000 and its console on 15026; its quickstart runs it on the host
# network.
spanner:
image: "us-docker.pkg.dev/spanner-omni/images/spanner-omni:2026.r2.1-beta"
command: start-single-server
network_mode: host
restart: always
4 changes: 2 additions & 2 deletions internal/endtoend/testdata/analyze_basic/googlesql/schema.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CREATE TABLE users (
id INT64 NOT NULL,
name STRING NOT NULL,
bio STRING,
name STRING(MAX) NOT NULL,
bio STRING(MAX),
) PRIMARY KEY (id);
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
{
"name": "name",
"type": {
"name": "string"
"name": "string",
"args": [
{
"ident": "max"
}
]
},
"table": "users"
}
Expand Down
4 changes: 2 additions & 2 deletions internal/endtoend/testdata/analyze_dml/googlesql/schema.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CREATE TABLE users (
id INT64 NOT NULL,
name STRING NOT NULL,
bio STRING,
name STRING(MAX) NOT NULL,
bio STRING(MAX),
) PRIMARY KEY (id);
49 changes: 42 additions & 7 deletions internal/endtoend/testdata/analyze_dml/googlesql/stdout.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
"column": {
"name": "name",
"type": {
"name": "string"
"name": "string",
"args": [
{
"ident": "max"
}
]
},
"table": "users"
}
Expand All @@ -30,7 +35,12 @@
"name": "bio",
"type": {
"name": "string",
"nullable": true
"nullable": true,
"args": [
{
"ident": "max"
}
]
},
"table": "users"
}
Expand All @@ -51,7 +61,12 @@
{
"name": "name",
"type": {
"name": "string"
"name": "string",
"args": [
{
"ident": "max"
}
]
},
"table": "users"
}
Expand All @@ -72,7 +87,12 @@
"column": {
"name": "name",
"type": {
"name": "string"
"name": "string",
"args": [
{
"ident": "max"
}
]
},
"table": "users"
}
Expand All @@ -90,7 +110,12 @@
"name": "bio",
"type": {
"name": "string",
"nullable": true
"nullable": true,
"args": [
{
"ident": "max"
}
]
},
"table": "users"
}
Expand Down Expand Up @@ -121,7 +146,12 @@
{
"name": "name",
"type": {
"name": "string"
"name": "string",
"args": [
{
"ident": "max"
}
]
},
"table": "users"
}
Expand All @@ -132,7 +162,12 @@
"column": {
"name": "name",
"type": {
"name": "string"
"name": "string",
"args": [
{
"ident": "max"
}
]
},
"table": "users"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CREATE TABLE users (
id INT64 NOT NULL,
name STRING NOT NULL,
bio STRING,
name STRING(MAX) NOT NULL,
bio STRING(MAX),
) PRIMARY KEY (id);

CREATE TABLE posts (
Expand Down
28 changes: 24 additions & 4 deletions internal/endtoend/testdata/analyze_select/googlesql/stdout.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,25 @@
{
"name": "name",
"type": {
"name": "string"
"name": "string",
"args": [
{
"ident": "max"
}
]
},
"table": "users"
},
{
"name": "bio",
"type": {
"name": "string",
"nullable": true
"nullable": true,
"args": [
{
"ident": "max"
}
]
},
"table": "users"
}
Expand All @@ -48,7 +58,12 @@
{
"name": "name",
"type": {
"name": "string"
"name": "string",
"args": [
{
"ident": "max"
}
]
},
"table": "users"
},
Expand Down Expand Up @@ -93,7 +108,12 @@
"column": {
"name": "name",
"type": {
"name": "string"
"name": "string",
"args": [
{
"ident": "max"
}
]
},
"table": "users"
}
Expand Down
5 changes: 5 additions & 0 deletions internal/endtoend/testdata/analyze_types/bigquery/exec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"command": "analyze",
"args": ["--dialect", "googlesql", "--schema", "schema.sql", "query.sql"],
"contexts": ["base"]
}
16 changes: 16 additions & 0 deletions internal/endtoend/testdata/analyze_types/bigquery/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- name: AllTypes :many
SELECT * FROM things;

-- name: Casts :one
SELECT
CAST(@a AS NUMERIC(5,2)) AS a,
CAST(@b AS ARRAY<INT64>) AS b,
CAST(@c AS STRUCT<x INT64>) AS c,
CAST(@d AS STRING(5)) AS d,
SAFE_CAST(@e AS BIGNUMERIC) AS e,
[1, 2] AS f
FROM things;

-- name: Params :one
SELECT id FROM things
WHERE s = @s AND ai = @ai AND n = @n AND st = @st AND smax = @smax;
21 changes: 21 additions & 0 deletions internal/endtoend/testdata/analyze_types/bigquery/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CREATE TABLE things (
id INT64 NOT NULL,
s STRING(10),
smax STRING(MAX),
n NUMERIC(10,2),
bn BIGNUMERIC,
byt BYTES(MAX),
ai ARRAY<INT64>,
as2 ARRAY<STRING(MAX)>,
st STRUCT<a INT64, b STRING>,
ast ARRAY<STRUCT<x INT64>>,
ts TIMESTAMP,
d DATE,
j JSON,
g GEOGRAPHY,
iv INTERVAL,
b BOOL,
f FLOAT64,
f32 FLOAT32,
tl TOKENLIST
) PRIMARY KEY (id);
Loading
Loading