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
2 changes: 2 additions & 0 deletions .github/workflows/gen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jobs:
check-latest: true
- run: go run ./cmd/goldeneye install clickhouse
working-directory: internal/goldeneye
- run: go run ./cmd/goldeneye install sqlite
working-directory: internal/goldeneye
- run: go run ./cmd/goldeneye generate
working-directory: internal/goldeneye
env:
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ 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 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" go test ./...
go run ./cmd/goldeneye generate postgresql # rewrite the files after a change
```
Expand Down
7 changes: 7 additions & 0 deletions internal/core/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ func applyCreateTable(cat *core.Catalog, stmt *ast.CreateTableStmt) error {
if stmt.Name == nil {
return fmt.Errorf("create table with nil name")
}
// A virtual table's module is the dialect's word for the extension it
// needs, the way CREATE EXTENSION is PostgreSQL's.
if stmt.Using != "" {
if err := cat.LoadExtension(stmt.Using); err != nil {
return err
}
}
nsOID, err := resolveOrCreateNamespace(cat, stmt.Name.Schema)
if err != nil {
return err
Expand Down
17 changes: 6 additions & 11 deletions internal/core/seed/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,12 @@ import (
"github.com/sqlc-dev/sqlc/internal/core"
)

// applyExtension applies the named extension's directory to a catalog that
// has already been seeded. Unlike the dialect's own seed, an extension lands
// in a catalog full of types, so everything it names is resolved against what
// is there before being created.
func applyExtension(cat *core.Catalog, fsys fs.FS, name string) error {
dir := path.Join(ExtensionsDir, name)
if _, err := fs.Stat(fsys, dir); err != nil {
// An extension sqlc has no data for adds nothing, the way the legacy
// catalog has always treated one.
return nil
}
// applyExtension applies the extension directory dir, relative to the
// dialect, to a catalog that has already been seeded. Unlike the dialect's
// own seed, an extension lands in a catalog full of types, so everything it
// names is resolved against what is there before being created.
func applyExtension(cat *core.Catalog, fsys fs.FS, dir string) error {
name := path.Base(dir)
sub, err := fs.Sub(fsys, dir)
if err != nil {
return fmt.Errorf("seed: extension %s: %w", name, err)
Expand Down
63 changes: 57 additions & 6 deletions internal/core/seed/seed.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
//
// A dialect may also hold an extensions/ directory with one directory per
// extension, each a smaller bundle of the same files, applied when a schema
// says CREATE EXTENSION.
// says CREATE EXTENSION — or, for a dialect whose settings map virtual table
// modules to extensions, CREATE VIRTUAL TABLE ... USING.
package seed

import (
Expand All @@ -28,6 +29,7 @@ import (
"fmt"
"io"
"io/fs"
"path"
"slices"
"strings"

Expand Down Expand Up @@ -78,6 +80,15 @@ type Settings struct {
// same kind of value resolves. "*" makes every seeded type implicitly
// castable to every other, for dialects that compare across categories.
CastCategories string `json:"cast_categories,omitempty"`

// Modules names the extension a virtual table module belongs to, for a
// dialect whose schemas say CREATE VIRTUAL TABLE ... USING rather than
// CREATE EXTENSION: SQLite's fts5 module comes with the functions its
// enable_fts5 compile option adds.
Modules map[string]string `json:"modules,omitempty"`

// fsys is the dialect directory the settings were read from.
fsys fs.FS
}

// Type is a type the dialect defines. Aliases are spellings of the same type
Expand Down Expand Up @@ -155,21 +166,60 @@ func Dialect(fsys fs.FS, dir string) core.Option {
if err != nil {
return fmt.Errorf("seed: %s: %w", dir, err)
}
if err := apply(cat, sub); err != nil {
settings, err := loadSettings(sub)
if err != nil {
return err
}
if err := apply(cat, sub, settings); err != nil {
return err
}
cat.SetExtensionLoader(func(name string) error {
return applyExtension(cat, sub, name)
dir, ok := settings.extensionDir(name)
if !ok {
// An extension sqlc has no data for adds nothing, the way
// the legacy catalog has always treated one.
return nil
}
return applyExtension(cat, sub, dir)
})
return nil
})
}

func apply(cat *core.Catalog, fsys fs.FS) error {
settings, err := loadSettings(fsys)
// ExtensionDir resolves what a schema named — an extension, or a virtual
// table module the dialect's settings map to one — to the extension's
// directory under dir, reporting whether the dialect has data for it.
func ExtensionDir(fsys fs.FS, dir, name string) (string, bool) {
sub, err := fs.Sub(fsys, dir)
if err != nil {
return err
return "", false
}
settings, err := loadSettings(sub)
if err != nil {
return "", false
}
rel, ok := settings.extensionDir(name)
if !ok {
return "", false
}
return path.Join(dir, rel), true
}

// extensionDir is the directory of the extension a name refers to,
// relative to the dialect, if the dialect ships one.
func (s Settings) extensionDir(name string) (string, bool) {
if ext, ok := s.Modules[strings.ToLower(name)]; ok {
name = ext
}
dir := path.Join(ExtensionsDir, name)
if _, err := fs.Stat(s.fsys, dir); err != nil {
return "", false
}
return dir, true
}

func apply(cat *core.Catalog, fsys fs.FS, settings Settings) error {
var err error
b := &builder{
cat: cat,
settings: settings,
Expand Down Expand Up @@ -222,6 +272,7 @@ func loadSettings(fsys fs.FS) (Settings, error) {
if settings.Dialect == "" {
return Settings{}, fmt.Errorf("seed: %s: dialect has no name", SettingsFile)
}
settings.fsys = fsys
return settings, nil
}

Expand Down
16 changes: 8 additions & 8 deletions internal/endtoend/testdata/builtins/sqlite/go/aggfunc.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions internal/endtoend/testdata/builtins/sqlite/go/mathfunc.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 14 additions & 14 deletions internal/endtoend/testdata/builtins/sqlite/go/scalarfunc.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion internal/engine/sqlite/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ func NewCatalog() *catalog.Catalog {
Schemas: []*catalog.Schema{
defaultSchema(def),
},
Extensions: map[string]struct{}{},
LoadExtension: loadExtension,
Extensions: map[string]struct{}{},
}
}
10 changes: 9 additions & 1 deletion internal/engine/sqlite/dialect/dialect.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,13 @@
"comparison_categories": "BNSDU",
"arithmetic": ["+", "-", "*", "/", "%"],
"arithmetic_categories": "N",
"cast_categories": "*"
"cast_categories": "*",
"modules": {
"fts3": "enable_fts3",
"fts4": "enable_fts3",
"fts5": "enable_fts5",
"geopoly": "enable_geopoly",
"rtree": "enable_rtree",
"rtree_i32": "enable_rtree"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{"name":"matchinfo","args":[{"type":"any"}],"returns":"blob"}
{"name":"matchinfo","args":[{"type":"any"},{"type":"text"}],"returns":"blob"}
{"name":"offsets","args":[{"type":"any"}],"returns":"text"}
{"name":"optimize","args":[{"type":"any"}],"returns":"text"}
{"name":"snippet","args":[{"type":"any","has_default":true},{"type":"any","has_default":true},{"type":"text","has_default":true},{"type":"text","has_default":true},{"type":"integer","has_default":true},{"type":"integer","has_default":true},{"type":"any","mode":"v"}],"returns":"text"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{"name":"bm25","args":[{"type":"any","has_default":true},{"type":"real","mode":"v"}],"returns":"real"}
{"name":"fts5_get_locale","args":[{"type":"any","has_default":true},{"type":"integer","has_default":true},{"type":"any","mode":"v"}],"returns":"text","nullable":true}
{"name":"fts5_insttoken","args":[{"type":"any"}],"returns":"any"}
{"name":"fts5_locale","args":[{"type":"text"},{"type":"text"}],"returns":"text"}
{"name":"fts5_source_id","returns":"text"}
{"name":"highlight","args":[{"type":"any","has_default":true},{"type":"integer","has_default":true},{"type":"text","has_default":true},{"type":"text","has_default":true},{"type":"any","mode":"v"}],"returns":"text"}
{"name":"snippet","args":[{"type":"any","has_default":true},{"type":"any","has_default":true},{"type":"text","has_default":true},{"type":"text","has_default":true},{"type":"integer","has_default":true},{"type":"integer","has_default":true},{"type":"any","mode":"v"}],"returns":"text"}
Loading
Loading