Skip to content

Commit 76429cb

Browse files
committed
Remove the analyzerv2 experiment and database-only analyzer mode
Remove the analyzerv2 experiment flag and everything reachable only through it: - The AnalyzerV2 flag in the SQLCEXPERIMENT parser (the generic experiment mechanism stays) - Database-only analysis mode (analyzer.database: only) in the compiler, including the star expander wiring - The internal/x/expander package - EnsureConn, GetColumnNames and IntrospectSchema on the analyzer interface and the PostgreSQL/SQLite implementations - The "only" value for analyzer.database in the config, which reverts to a plain boolean - The accurate_* end-to-end test cases that exercised the experiment Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JyDtVLiKKixbPi6YvdM5wd
1 parent 944b878 commit 76429cb

41 files changed

Lines changed: 16 additions & 2274 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

internal/analyzer/analyzer.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -125,21 +125,7 @@ func (c *CachedAnalyzer) Close(ctx context.Context) error {
125125
return c.a.Close(ctx)
126126
}
127127

128-
func (c *CachedAnalyzer) EnsureConn(ctx context.Context, migrations []string) error {
129-
return c.a.EnsureConn(ctx, migrations)
130-
}
131-
132-
func (c *CachedAnalyzer) GetColumnNames(ctx context.Context, query string) ([]string, error) {
133-
return c.a.GetColumnNames(ctx, query)
134-
}
135-
136128
type Analyzer interface {
137129
Analyze(context.Context, ast.Node, string, []string, *named.ParamSet) (*analysis.Analysis, error)
138130
Close(context.Context) error
139-
// EnsureConn initializes the database connection with the given migrations.
140-
// This is required for database-only mode where we need to connect before analyzing queries.
141-
EnsureConn(ctx context.Context, migrations []string) error
142-
// GetColumnNames returns the column names for a query by preparing it against the database.
143-
// This is used for star expansion in database-only mode.
144-
GetColumnNames(ctx context.Context, query string) ([]string, error)
145131
}

internal/compiler/compile.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package compiler
22

33
import (
4-
"context"
54
"errors"
65
"fmt"
76
"io"
@@ -81,8 +80,6 @@ func (c *Compiler) parseCatalog(schemas []string) error {
8180

8281
func (c *Compiler) parseCatalogLegacy(files []schemaFile, merr *multierr.Error) {
8382
for _, file := range files {
84-
// In database-only mode, we parse the schema to validate syntax
85-
// but don't update the catalog - the database will be the source of truth
8683
stmts, err := c.parser.Parse(strings.NewReader(file.contents))
8784
if err != nil {
8885
// A schema file and a query file are often the same file, so a
@@ -94,11 +91,6 @@ func (c *Compiler) parseCatalogLegacy(files []schemaFile, merr *multierr.Error)
9491
continue
9592
}
9693

97-
// Skip catalog updates in database-only mode
98-
if c.databaseOnlyMode {
99-
continue
100-
}
101-
10294
for i := range stmts {
10395
if err := c.catalog.Update(stmts[i], c); err != nil {
10496
merr.Add(file.name, file.contents, stmts[i].Pos(), err)
@@ -163,15 +155,6 @@ type statement struct {
163155
}
164156

165157
func (c *Compiler) parseQueries(o opts.Parser) (*Result, error) {
166-
ctx := context.Background()
167-
168-
// In database-only mode, initialize the database connection before parsing queries
169-
if c.databaseOnlyMode && c.analyzer != nil {
170-
if err := c.analyzer.EnsureConn(ctx, c.schema); err != nil {
171-
return nil, fmt.Errorf("failed to initialize database connection: %w", err)
172-
}
173-
}
174-
175158
merr := multierr.New()
176159
files, err := sqlpath.Glob(c.conf.Queries)
177160
if err != nil {

internal/compiler/engine.go

Lines changed: 6 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
sqliteanalyze "github.com/sqlc-dev/sqlc/internal/engine/sqlite/analyzer"
1818
"github.com/sqlc-dev/sqlc/internal/opts"
1919
"github.com/sqlc-dev/sqlc/internal/sql/catalog"
20-
"github.com/sqlc-dev/sqlc/internal/x/expander"
2120
)
2221

2322
type Compiler struct {
@@ -40,12 +39,6 @@ type Compiler struct {
4039
coreDialect core.Option
4140

4241
schema []string
43-
44-
// databaseOnlyMode indicates that the compiler should use database-only analysis
45-
// and skip building the internal catalog from schema files (analyzer.database: only)
46-
databaseOnlyMode bool
47-
// expander is used to expand SELECT * and RETURNING * in database-only mode
48-
expander *expander.Expander
4942
}
5043

5144
// Option configures a Compiler.
@@ -81,33 +74,14 @@ func NewCompiler(conf config.SQL, combo config.CombinedSettings, parserOpts opts
8174
c.client = client
8275
}
8376

84-
// Check for database-only mode (analyzer.database: only)
85-
// This feature requires the analyzerv2 experiment to be enabled
86-
databaseOnlyMode := conf.Analyzer.Database.IsOnly() && parserOpts.Experiment.AnalyzerV2
87-
8877
switch conf.Engine {
8978
case config.EngineSQLite:
90-
parser := sqlite.NewParser()
91-
c.parser = parser
79+
c.parser = sqlite.NewParser()
9280
c.catalog = sqlite.NewCatalog()
9381
c.selector = newSQLiteSelector()
9482

95-
if databaseOnlyMode {
96-
// Database-only mode requires a database connection
97-
if conf.Database == nil {
98-
return nil, fmt.Errorf("analyzer.database: only requires database configuration")
99-
}
100-
if conf.Database.URI == "" && !conf.Database.Managed {
101-
return nil, fmt.Errorf("analyzer.database: only requires database.uri or database.managed")
102-
}
103-
c.databaseOnlyMode = true
104-
// Create the SQLite analyzer (implements Analyzer interface)
105-
sqliteAnalyzer := sqliteanalyze.New(*conf.Database)
106-
c.analyzer = analyzer.Cached(sqliteAnalyzer, combo.Global, *conf.Database)
107-
// Create the expander using the analyzer as the column getter
108-
c.expander = expander.New(c.analyzer, parser, parser)
109-
} else if conf.Database != nil {
110-
if conf.Analyzer.Database.IsEnabled() {
83+
if conf.Database != nil {
84+
if conf.Analyzer.Database == nil || *conf.Analyzer.Database {
11185
c.analyzer = analyzer.Cached(
11286
sqliteanalyze.New(*conf.Database),
11387
combo.Global,
@@ -120,27 +94,12 @@ func NewCompiler(conf config.SQL, combo config.CombinedSettings, parserOpts opts
12094
c.catalog = dolphin.NewCatalog()
12195
c.selector = newDefaultSelector()
12296
case config.EnginePostgreSQL:
123-
parser := postgresql.NewParser()
124-
c.parser = parser
97+
c.parser = postgresql.NewParser()
12598
c.catalog = postgresql.NewCatalog()
12699
c.selector = newDefaultSelector()
127100

128-
if databaseOnlyMode {
129-
// Database-only mode requires a database connection
130-
if conf.Database == nil {
131-
return nil, fmt.Errorf("analyzer.database: only requires database configuration")
132-
}
133-
if conf.Database.URI == "" && !conf.Database.Managed {
134-
return nil, fmt.Errorf("analyzer.database: only requires database.uri or database.managed")
135-
}
136-
c.databaseOnlyMode = true
137-
// Create the PostgreSQL analyzer (implements Analyzer interface)
138-
pgAnalyzer := pganalyze.New(c.client, *conf.Database)
139-
c.analyzer = analyzer.Cached(pgAnalyzer, combo.Global, *conf.Database)
140-
// Create the expander using the analyzer as the column getter
141-
c.expander = expander.New(c.analyzer, parser, parser)
142-
} else if conf.Database != nil {
143-
if conf.Analyzer.Database.IsEnabled() {
101+
if conf.Database != nil {
102+
if conf.Analyzer.Database == nil || *conf.Analyzer.Database {
144103
c.analyzer = analyzer.Cached(
145104
pganalyze.New(c.client, *conf.Database),
146105
combo.Global,

internal/compiler/parse.go

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -84,56 +84,7 @@ func (c *Compiler) parseQuery(stmt ast.Node, pp *preprocess.Result, o opts.Parse
8484
}
8585

8686
var anlys *analysis
87-
if c.databaseOnlyMode && c.expander != nil {
88-
// In database-only mode, use the expander for star expansion
89-
// and rely entirely on the database analyzer for type resolution
90-
expandedQuery, err := c.expander.Expand(ctx, rawSQL)
91-
if err != nil {
92-
return nil, fmt.Errorf("star expansion failed: %w", err)
93-
}
94-
95-
// Parse named parameters from the expanded query
96-
expandedStmts, err := c.parser.Parse(strings.NewReader(expandedQuery))
97-
if err != nil {
98-
return nil, fmt.Errorf("parsing expanded query failed: %w", err)
99-
}
100-
if len(expandedStmts) == 0 {
101-
return nil, errors.New("no statements in expanded query")
102-
}
103-
expandedRaw := expandedStmts[0].Raw
104-
105-
// Use the analyzer to get type information from the database
106-
result, err := c.analyzer.Analyze(ctx, expandedRaw, expandedQuery, c.schema, nil)
107-
if err != nil {
108-
return nil, err
109-
}
110-
111-
// Convert the analyzer result to the internal analysis format
112-
var cols []*Column
113-
for _, col := range result.Columns {
114-
cols = append(cols, convertColumn(col))
115-
}
116-
var params []Parameter
117-
for _, p := range result.Params {
118-
params = append(params, Parameter{
119-
Number: int(p.Number),
120-
Column: convertColumn(p.Column),
121-
})
122-
}
123-
124-
// Determine the insert table if applicable
125-
var table *ast.TableName
126-
if insert, ok := expandedRaw.Stmt.(*ast.InsertStmt); ok {
127-
table, _ = ParseTableName(insert.Relation)
128-
}
129-
130-
anlys = &analysis{
131-
Table: table,
132-
Columns: cols,
133-
Parameters: params,
134-
Query: expandedQuery,
135-
}
136-
} else if c.analyzer != nil {
87+
if c.analyzer != nil {
13788
inference, _ := c.inferQuery(raw, rawSQL, pre)
13889
if inference == nil {
13990
inference = &analysis{}

internal/config/config.go

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -124,75 +124,8 @@ type SQL struct {
124124
Analyzer Analyzer `json:"analyzer" yaml:"analyzer"`
125125
}
126126

127-
// AnalyzerDatabase represents the database analyzer setting.
128-
// It can be a boolean (true/false) or the string "only" for database-only mode.
129-
type AnalyzerDatabase struct {
130-
value *bool // nil means not set, true/false for boolean values
131-
isOnly bool // true when set to "only"
132-
}
133-
134-
// IsEnabled returns true if the database analyzer should be used.
135-
// Returns true for both `true` and `"only"` settings.
136-
func (a AnalyzerDatabase) IsEnabled() bool {
137-
if a.isOnly {
138-
return true
139-
}
140-
return a.value == nil || *a.value
141-
}
142-
143-
// IsOnly returns true if the analyzer is set to "only" mode.
144-
func (a AnalyzerDatabase) IsOnly() bool {
145-
return a.isOnly
146-
}
147-
148-
func (a *AnalyzerDatabase) UnmarshalJSON(data []byte) error {
149-
// Try to unmarshal as boolean first
150-
var b bool
151-
if err := json.Unmarshal(data, &b); err == nil {
152-
a.value = &b
153-
a.isOnly = false
154-
return nil
155-
}
156-
157-
// Try to unmarshal as string
158-
var s string
159-
if err := json.Unmarshal(data, &s); err == nil {
160-
if s == "only" {
161-
a.isOnly = true
162-
a.value = nil
163-
return nil
164-
}
165-
return errors.New("analyzer.database must be true, false, or \"only\"")
166-
}
167-
168-
return errors.New("analyzer.database must be true, false, or \"only\"")
169-
}
170-
171-
func (a *AnalyzerDatabase) UnmarshalYAML(unmarshal func(any) error) error {
172-
// Try to unmarshal as boolean first
173-
var b bool
174-
if err := unmarshal(&b); err == nil {
175-
a.value = &b
176-
a.isOnly = false
177-
return nil
178-
}
179-
180-
// Try to unmarshal as string
181-
var s string
182-
if err := unmarshal(&s); err == nil {
183-
if s == "only" {
184-
a.isOnly = true
185-
a.value = nil
186-
return nil
187-
}
188-
return errors.New("analyzer.database must be true, false, or \"only\"")
189-
}
190-
191-
return errors.New("analyzer.database must be true, false, or \"only\"")
192-
}
193-
194127
type Analyzer struct {
195-
Database AnalyzerDatabase `json:"database" yaml:"database"`
128+
Database *bool `json:"database" yaml:"database"`
196129
}
197130

198131
// TODO: Figure out a better name for this

internal/config/v_one.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,7 @@
7979
"type": "object",
8080
"properties": {
8181
"database": {
82-
"oneOf": [
83-
{"type": "boolean"},
84-
{"const": "only"}
85-
]
82+
"type": "boolean"
8683
}
8784
}
8885
},

internal/config/v_two.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,7 @@
8282
"type": "object",
8383
"properties": {
8484
"database": {
85-
"oneOf": [
86-
{"type": "boolean"},
87-
{"const": "only"}
88-
]
85+
"type": "boolean"
8986
}
9087
}
9188
},

internal/endtoend/testdata/accurate_cte/postgresql/stdlib/exec.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

internal/endtoend/testdata/accurate_cte/postgresql/stdlib/go/db.go

Lines changed: 0 additions & 31 deletions
This file was deleted.

internal/endtoend/testdata/accurate_cte/postgresql/stdlib/go/models.go

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)