Skip to content
Open
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
13 changes: 11 additions & 2 deletions docs/reference/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@ SQLCEXPERIMENT=nofoo # explicitly disable foo experiment
SQLCEXPERIMENT=foo,nobar # enable foo, disable bar
```

Currently, no experiments are defined. Experiments will be documented here as
they are introduced.
The following experiments are defined:

### coreanalyzer

Routes `sqlc generate` through the core catalog and analyzer instead of each
engine's own analysis path. This is the same analysis used by `sqlc analyze`,
and the only analysis path for the ClickHouse and GoogleSQL engines.

```
SQLCEXPERIMENT=coreanalyzer
```

## SQLCCACHE

Expand Down
6 changes: 5 additions & 1 deletion internal/cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,11 @@ func (g *generator) ProcessResult(ctx context.Context, combo config.CombinedSett

func parse(ctx context.Context, name, dir string, sql config.SQL, combo config.CombinedSettings, parserOpts opts.Parser, stderr io.Writer) (*compiler.Result, bool) {
defer trace.StartRegion(ctx, "parse").End()
c, err := compiler.NewCompiler(sql, combo, parserOpts)
var copts []compiler.Option
if parserOpts.Experiment.CoreAnalyzer {
copts = append(copts, compiler.WithCoreAnalysis())
}
c, err := compiler.NewCompiler(sql, combo, parserOpts, copts...)
defer func() {
if c != nil {
c.Close(ctx)
Expand Down
4 changes: 3 additions & 1 deletion internal/cmd/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ func processQuerySets(ctx context.Context, rp ResultProcessor, conf *config.Conf
sql.Queries = joined

var name, lang string
parseOpts := opts.Parser{}
parseOpts := opts.Parser{
Experiment: o.Env.Experiment,
}

switch {
case sql.Gen.Go != nil:
Expand Down
56 changes: 56 additions & 0 deletions internal/compiler/catalog_core.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package compiler

import (
"strings"

"github.com/sqlc-dev/sqlc/internal/core"
"github.com/sqlc-dev/sqlc/internal/sql/ast"
"github.com/sqlc-dev/sqlc/internal/sql/catalog"
)

// coreResultCatalog dumps the core catalog into the legacy catalog shape a
// Result carries, so codegen sees the same table models either way a query
// set was analyzed. Only relations make the trip: codegen reads tables and
// their columns to build models, and none of the types, functions or
// operators the core catalog also holds.
func coreResultCatalog(c *core.Catalog) (*catalog.Catalog, error) {
cat := catalog.New("public")
namespaces, err := c.Namespaces()
if err != nil {
return nil, err
}
for _, ns := range namespaces {
schema := &catalog.Schema{Name: ns.Name}
tables, err := c.TablesInNamespace(ns.OID)
if err != nil {
return nil, err
}
for _, table := range tables {
cols, err := c.ClassCodegenColumns(table.OID)
if err != nil {
return nil, err
}
t := &catalog.Table{Rel: &ast.TableName{Schema: ns.Name, Name: table.Name}}
for _, col := range cols {
// The catalog names an array type after its element with the
// suffix appended, which is codegen's data type and array
// flag in one string. The core catalog holds one dimension,
// and codegen renders a "[]" per dimension.
dataType, isArray := strings.CutSuffix(col.TypeName, core.ArraySuffix)
column := &catalog.Column{
Name: col.Name,
Type: ast.TypeName{Name: dataType},
IsNotNull: col.NotNull,
IsArray: isArray,
}
if isArray {
column.ArrayDims = 1
}
t.Columns = append(t.Columns, column)
}
schema.Tables = append(schema.Tables, t)
}
cat.Schemas = append(cat.Schemas, schema)
}
return cat, nil
}
7 changes: 7 additions & 0 deletions internal/compiler/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ func (c *Compiler) parseCatalogCore(files []schemaFile, merr *multierr.Error) er
}
// Whatever apply reported is already in merr, which the caller returns.
c.coreCatalog = cat

// Codegen consumes the catalog through the Result, in the legacy shape.
legacy, err := coreResultCatalog(cat)
if err != nil {
return fmt.Errorf("%s: dump catalog: %w", c.conf.Engine, err)
}
c.catalog = legacy
return nil
}

Expand Down
8 changes: 8 additions & 0 deletions internal/compiler/parse_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ func coreColumn(c core.Column) *Column {
NotNull: c.NotNull,
IsArray: c.IsArray,
}
// The core reports arrays without dimensions, and codegen renders one
// "[]" per dimension.
if c.IsArray {
col.ArrayDims = 1
}
if c.Source != nil && c.Source.Table != "" {
col.Table = &ast.TableName{Schema: c.Source.Schema, Name: c.Source.Table}
col.TableAlias = c.Source.TableAlias
Expand All @@ -113,6 +118,9 @@ func coreParamColumn(p core.Parameter, params *named.ParamSet) *Column {
NotNull: p.NotNull,
IsArray: p.IsArray,
}
if p.IsArray {
col.ArrayDims = 1
}
if p.Source != nil && p.Source.Table != "" {
col.Table = &ast.TableName{Schema: p.Source.Schema, Name: p.Source.Table}
col.OriginalName = p.Source.Column
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"command": "generate",
"env": {
"SQLCEXPERIMENT": "coreanalyzer"
}
}
31 changes: 31 additions & 0 deletions internal/endtoend/testdata/experiment_coreanalyzer/mysql/go/db.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.

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

15 changes: 15 additions & 0 deletions internal/endtoend/testdata/experiment_coreanalyzer/mysql/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- name: GetAuthor :one
SELECT * FROM authors
WHERE id = ?;

-- name: ListAuthors :many
SELECT id, name FROM authors
ORDER BY name;

-- name: CreateAuthor :execresult
INSERT INTO authors (id, name, bio)
VALUES (?, ?, ?);

-- name: DeleteAuthor :exec
DELETE FROM authors
WHERE id = ?;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE authors (
id bigint PRIMARY KEY,
name varchar(255) NOT NULL,
bio text
);
12 changes: 12 additions & 0 deletions internal/endtoend/testdata/experiment_coreanalyzer/mysql/sqlc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "1",
"packages": [
{
"path": "go",
"engine": "mysql",
"name": "querytest",
"schema": "schema.sql",
"queries": "query.sql"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"command": "generate",
"env": {
"SQLCEXPERIMENT": "coreanalyzer"
}
}

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.

Loading
Loading