diff --git a/driver.go b/driver.go index 3e93a8e..708a29a 100644 --- a/driver.go +++ b/driver.go @@ -85,9 +85,13 @@ func newZetaSQLiteConn(db *sql.DB, catalog *internal.Catalog) (*ZetaSQLiteConn, if err != nil { return nil, fmt.Errorf("failed to get sqlite3 connection: %w", err) } + analyzer, err := internal.NewAnalyzer(catalog) + if err != nil { + return nil, fmt.Errorf("failed to create analyzer: %w", err) + } return &ZetaSQLiteConn{ conn: conn, - analyzer: internal.NewAnalyzer(catalog), + analyzer: analyzer, }, nil } diff --git a/internal/analyzer.go b/internal/analyzer.go index 950f9bd..acb81b7 100644 --- a/internal/analyzer.go +++ b/internal/analyzer.go @@ -20,15 +20,19 @@ type Analyzer struct { opt *zetasql.AnalyzerOptions } -func NewAnalyzer(catalog *Catalog) *Analyzer { +func NewAnalyzer(catalog *Catalog) (*Analyzer, error) { + opt, err := newAnalyzerOptions() + if err != nil { + return nil, err + } return &Analyzer{ catalog: catalog, - opt: newAnalyzerOptions(), + opt: opt, namePath: &NamePath{}, - } + }, nil } -func newAnalyzerOptions() *zetasql.AnalyzerOptions { +func newAnalyzerOptions() (*zetasql.AnalyzerOptions, error) { langOpt := zetasql.NewLanguageOptions() langOpt.SetNameResolutionMode(zetasql.NameResolutionDefault) langOpt.SetProductMode(types.ProductInternal) @@ -90,11 +94,17 @@ func newAnalyzerOptions() *zetasql.AnalyzerOptions { ast.CreateViewStmt, ast.DropFunctionStmt, }) + // Enable QUALIFY without WHERE + //https://github.com/google/zetasql/issues/124 + err := langOpt.EnableReservableKeyword("QUALIFY", true) + if err != nil { + return nil, err + } opt := zetasql.NewAnalyzerOptions() opt.SetAllowUndeclaredParameters(true) opt.SetLanguage(langOpt) opt.SetParseLocationRecordType(zetasql.ParseLocationRecordFullNodeScope) - return opt + return opt, nil } func (a *Analyzer) SetAutoIndexMode(enabled bool) { diff --git a/query_test.go b/query_test.go index 2ba909d..d848d4e 100644 --- a/query_test.go +++ b/query_test.go @@ -1807,7 +1807,6 @@ FROM UNNEST(['c', NULL, 'b', 'a']) AS x`, {"a", nil, "a", "c"}, }, }, - { name: "window range", query: ` @@ -3037,6 +3036,15 @@ FROM Produce WHERE Produce.category = 'vegetable' QUALIFY rank <= 3`, {"cabbage", int64(3)}, }, }, + // Regression test goccy/go-zetasqlite#123 + { + name: "qualify without group by / where / having", + query: `WITH toks AS (SELECT 1 AS x UNION ALL SELECT 2 AS x) + SELECT x FROM toks QUALIFY MAX(x) OVER (PARTITION BY x) > 1`, + expectedRows: [][]interface{}{ + {int64(2)}, + }, + }, // Regression test goccy/go-zetasqlite#150 { name: "qualify group",