Skip to content

Commit daf744a

Browse files
committed
goldeneye: generate the SQLite dialect from the official sqlite3 shell
Add a sqlite package to goldeneye that reads pragma_function_list from the sqlite3 shell sqlite.org publishes, run against an in-memory database, and writes internal/engine/sqlite/dialect/functions.jsonl from it. `install sqlite` downloads the pinned release (3.53.4, the one the ncruces/go-sqlite3 driver embeds) into the user cache directory and checks it against the SHA3-256 the download page lists, the same way the clickhouse installer works; SQLITE3 names a shell to use instead. SQLite records a function's name, kind and argument count and nothing about types, so the return and argument types come from a table in sqlite/signatures.go. A built-in function the shell reports that the table lacks fails the run, as does a table entry the shell does not report. Aggregates are told apart from window functions by calling each without OVER, since SQLite marks every aggregate 'w'. SQLite has no catalog of types or operators, so those files stay hand-written. Regenerating the committed file adds the JSON, date and time, window and percentile functions the hand-written list lacked, corrects the misspelled random and randomblob entries, marks group_concat nullable as it is over no rows, and drops soundex, which the official build does not compile in. The goldens that move follow from those. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RYkxvtwH6GgysuWYP87vyj
1 parent 8f23752 commit daf744a

13 files changed

Lines changed: 938 additions & 124 deletions

File tree

.github/workflows/gen.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ jobs:
2424
check-latest: true
2525
- run: go run ./cmd/goldeneye install clickhouse
2626
working-directory: internal/goldeneye
27+
- run: go run ./cmd/goldeneye install sqlite
28+
working-directory: internal/goldeneye
2729
- run: go run ./cmd/goldeneye generate
2830
working-directory: internal/goldeneye
2931
env:

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ is not available skip.
153153
```bash
154154
cd internal/goldeneye
155155
go run ./cmd/goldeneye install clickhouse # download the pinned clickhouse binary once
156+
go run ./cmd/goldeneye install sqlite # download the pinned sqlite3 shell once
156157
POSTGRESQL_SERVER_URI="postgres://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable" go test ./...
157158
go run ./cmd/goldeneye generate postgresql # rewrite the files after a change
158159
```

internal/endtoend/testdata/builtins/sqlite/go/aggfunc.sql.go

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/builtins/sqlite/go/scalarfunc.sql.go

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/table_function/sqlite/go/query.sql.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/engine/sqlite/dialect/functions.jsonl

Lines changed: 166 additions & 92 deletions
Large diffs are not rendered by default.

internal/engine/sqlite/stdlib.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,8 @@ import (
55
)
66

77
// defaultSchema is SQLite's standard library, read from the dialect
8-
// directory's functions.jsonl.
9-
//
10-
// The functions are drawn from:
11-
//
12-
// https://www.sqlite.org/lang_aggfunc.html
13-
// https://www.sqlite.org/lang_mathfunc.html
14-
// https://www.sqlite.org/lang_corefunc.html
8+
// directory's functions.jsonl, which internal/goldeneye generates from the
9+
// sqlite3 shell's pragma_function_list.
1510
func defaultSchema(name string) *catalog.Schema {
1611
return &catalog.Schema{Name: name, Funcs: stdlib()}
1712
}

internal/goldeneye/README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ reads the files: the files are the contract. Run it from this directory:
1515

1616
```bash
1717
go run ./cmd/goldeneye install clickhouse # download the pinned clickhouse binary once
18+
go run ./cmd/goldeneye install sqlite # download the pinned sqlite3 shell once
1819
go run ./cmd/goldeneye check # check every engine whose database is available
1920
go run ./cmd/goldeneye check postgresql # check one engine
2021
go run ./cmd/goldeneye generate [engine] # rewrite the generated files from the database
@@ -54,14 +55,29 @@ the hand-written files alone, and the checks do not look at them.
5455
`clickhouse/install.go`, and a download that does not match is discarded.
5556
ClickHouse describes its functions no further than their names, so
5657
`functions.jsonl` is hand-written.
58+
- **`sqlite`** needs no server either: `functions.jsonl` comes from
59+
`pragma_function_list` of the `sqlite3` shell sqlite.org publishes, run
60+
against an in-memory database. SQLite describes its functions as far as
61+
their names, their kinds and the number of arguments each overload takes,
62+
and no further — it types values, not functions — so what each returns and
63+
what its arguments hold comes from the table in `sqlite/signatures.go`,
64+
and a built-in function the shell reports that the table does not know
65+
fails the run rather than being guessed at. The shell is downloaded once
66+
per pinned release by `install` into the user cache directory, or supplied
67+
through the `SQLITE3` environment variable; the pinned release, which is
68+
the one the main module's driver embeds, and the SHA3-256 of each
69+
platform's download live in `sqlite/install.go`. SQLite has no catalog of
70+
types or operators, so `types.jsonl` and `operators.jsonl` are
71+
hand-written.
5772

5873
## Layout
5974

6075
- `dialect/` — the record types the files are made of, mirrored from
6176
`internal/core/seed`, and the helpers that write a generated set of files
6277
into an engine directory or diff it against what is committed.
63-
- `postgresql/`, `duckdb/`, `clickhouse/` — one package per engine, each
64-
exposing `Locate`, `Version` and `Generate`, and a test that runs the check.
78+
- `postgresql/`, `duckdb/`, `clickhouse/`, `sqlite/` — one package per
79+
engine, each exposing `Locate`, `Version` and `Generate`, and a test that
80+
runs the check.
6581
- `cmd/goldeneye/` — the command.
6682

6783
The analysis checks — verifying the `analyze_*` cases under

internal/goldeneye/cmd/goldeneye/main.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Usage, from internal/goldeneye:
66
//
77
// go run ./cmd/goldeneye install clickhouse # download the pinned clickhouse binary
8+
// go run ./cmd/goldeneye install sqlite # download the pinned sqlite3 shell
89
// go run ./cmd/goldeneye generate [engine] # rewrite the generated files from the database
910
// go run ./cmd/goldeneye check [engine] # compare the committed files with the database
1011
//
@@ -26,6 +27,7 @@ import (
2627
"github.com/sqlc-dev/sqlc/internal/goldeneye/dialect"
2728
"github.com/sqlc-dev/sqlc/internal/goldeneye/duckdb"
2829
"github.com/sqlc-dev/sqlc/internal/goldeneye/postgresql"
30+
"github.com/sqlc-dev/sqlc/internal/goldeneye/sqlite"
2931
)
3032

3133
func main() {
@@ -36,14 +38,14 @@ func main() {
3638
}
3739

3840
const usage = `usage:
39-
goldeneye install clickhouse [-version V]
40-
download the pinned clickhouse binary into the user cache directory
41+
goldeneye install clickhouse|sqlite [-version V]
42+
download the pinned binary for an engine into the user cache directory
4143
goldeneye generate [engine]
4244
rewrite the generated dialect files from the database, for every available engine or one
4345
goldeneye check [engine]
4446
compare the committed dialect files with the database, for every available engine or one
4547
46-
engines: clickhouse, duckdb, postgresql`
48+
engines: clickhouse, duckdb, postgresql, sqlite`
4749

4850
// engine is one database goldeneye knows how to read a dialect from.
4951
type engine struct {
@@ -61,6 +63,19 @@ var engines = []engine{
6163
{clickhouse.Engine, clickhouse.Locate, clickhouse.Version, clickhouse.Generate},
6264
{duckdb.Engine, duckdb.Locate, duckdb.Version, duckdb.Generate},
6365
{postgresql.Engine, postgresql.Locate, postgresql.Version, postgresql.Generate},
66+
{sqlite.Engine, sqlite.Locate, sqlite.Version, sqlite.Generate},
67+
}
68+
69+
// installer downloads the binary an engine is read through, for the engines
70+
// that need no server and whose release is pinned in their package.
71+
type installer struct {
72+
defaultVersion string
73+
install func(ctx context.Context, version, goos, goarch string, progress io.Writer) (string, error)
74+
}
75+
76+
var installers = map[string]installer{
77+
clickhouse.Engine: {clickhouse.DefaultVersion, clickhouse.Install},
78+
sqlite.Engine: {sqlite.DefaultVersion, sqlite.Install},
6479
}
6580

6681
func run(ctx context.Context, args []string, stdout, stderr io.Writer) error {
@@ -84,16 +99,20 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) error {
8499
}
85100

86101
func install(ctx context.Context, args []string, stdout, stderr io.Writer) error {
87-
if len(args) == 0 || args[0] != clickhouse.Engine {
88-
return errors.New("install takes the engine to install: clickhouse")
102+
if len(args) == 0 {
103+
return errors.New("install takes the engine to install: clickhouse or sqlite")
104+
}
105+
inst, ok := installers[args[0]]
106+
if !ok {
107+
return fmt.Errorf("install takes the engine to install, clickhouse or sqlite, not %q", args[0])
89108
}
90-
fs := flag.NewFlagSet("install", flag.ContinueOnError)
109+
fs := flag.NewFlagSet("install "+args[0], flag.ContinueOnError)
91110
fs.SetOutput(stderr)
92-
version := fs.String("version", clickhouse.DefaultVersion, "ClickHouse release to install")
111+
version := fs.String("version", inst.defaultVersion, args[0]+" release to install")
93112
if err := fs.Parse(args[1:]); err != nil {
94113
return err
95114
}
96-
path, err := clickhouse.Install(ctx, *version, runtime.GOOS, runtime.GOARCH, stderr)
115+
path, err := inst.install(ctx, *version, runtime.GOOS, runtime.GOARCH, stderr)
97116
if err != nil {
98117
return err
99118
}

0 commit comments

Comments
 (0)