From 26daf0ad99f48b5e176dd054b9cd1f3f7469a8b3 Mon Sep 17 00:00:00 2001 From: noxymon Date: Fri, 6 Mar 2026 10:38:38 +0700 Subject: [PATCH 1/2] feat: Add end-to-end test and compiler support for SQLite boolean arguments with the NOT operator. --- internal/compiler/resolve.go | 14 ++++ .../sqlite_not_bool_arg/sqlite/query.sql | 5 ++ .../sqlite_not_bool_arg/sqlite/query.sql.go | 64 +++++++++++++++++++ .../sqlite_not_bool_arg/sqlite/schema.sql | 3 + .../sqlite_not_bool_arg/sqlite/sqlc.yaml | 9 +++ 5 files changed, 95 insertions(+) create mode 100644 internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql create mode 100644 internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql.go create mode 100644 internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/schema.sql create mode 100644 internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/sqlc.yaml diff --git a/internal/compiler/resolve.go b/internal/compiler/resolve.go index b1fbb1990e..6278a59858 100644 --- a/internal/compiler/resolve.go +++ b/internal/compiler/resolve.go @@ -522,6 +522,20 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar, Column: col, }) + case *ast.BoolExpr: + defaultP := named.NewInferredParam(ref.name, false) + p, isNamed := params.FetchMerge(ref.ref.Number, defaultP) + a = append(a, Parameter{ + Number: ref.ref.Number, + Column: &Column{ + Name: p.Name(), + DataType: "boolean", + IsNamedParam: isNamed, + NotNull: p.NotNull(), + IsSqlcSlice: p.IsSqlcSlice(), + }, + }) + case *ast.ParamRef: a = append(a, Parameter{Number: ref.ref.Number}) diff --git a/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql new file mode 100644 index 0000000000..6c10e957e9 --- /dev/null +++ b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql @@ -0,0 +1,5 @@ +-- name: Example :many +select 1 where not @argname; + +-- name: Example2 :many +select 1 where cast(@argname as boolean); diff --git a/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql.go b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql.go new file mode 100644 index 0000000000..372d6555e8 --- /dev/null +++ b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql.go @@ -0,0 +1,64 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: query.sql + +package db + +import ( + "context" +) + +const example = `-- name: Example :many +select 1 where not ?1 +` + +func (q *Queries) Example(ctx context.Context, argname bool) ([]int64, error) { + rows, err := q.db.QueryContext(ctx, example, argname) + if err != nil { + return nil, err + } + defer rows.Close() + var items []int64 + for rows.Next() { + var column_1 int64 + if err := rows.Scan(&column_1); err != nil { + return nil, err + } + items = append(items, column_1) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const example2 = `-- name: Example2 :many +select 1 where cast(?1 as boolean) +` + +func (q *Queries) Example2(ctx context.Context, argname bool) ([]int64, error) { + rows, err := q.db.QueryContext(ctx, example2, argname) + if err != nil { + return nil, err + } + defer rows.Close() + var items []int64 + for rows.Next() { + var column_1 int64 + if err := rows.Scan(&column_1); err != nil { + return nil, err + } + items = append(items, column_1) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/schema.sql b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/schema.sql new file mode 100644 index 0000000000..5985501b69 --- /dev/null +++ b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/schema.sql @@ -0,0 +1,3 @@ +CREATE TABLE example ( + bar boolean +); diff --git a/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/sqlc.yaml b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/sqlc.yaml new file mode 100644 index 0000000000..63464b7f62 --- /dev/null +++ b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/sqlc.yaml @@ -0,0 +1,9 @@ +version: "2" +sql: + - engine: "sqlite" + queries: "query.sql" + schema: "schema.sql" + gen: + go: + package: "db" + out: "." From 9b4f4884a3691735101310adbd08a26b5c3575ba Mon Sep 17 00:00:00 2001 From: noxymon Date: Fri, 6 Mar 2026 11:02:28 +0700 Subject: [PATCH 2/2] add test data to fix testing --- .../testdata/sqlite_not_bool_arg/sqlite/db.go | 31 +++++++++++++++++++ .../sqlite_not_bool_arg/sqlite/models.go | 13 ++++++++ .../sqlite_not_bool_arg/sqlite/query.sql.go | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/db.go create mode 100644 internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/models.go diff --git a/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/db.go b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/db.go new file mode 100644 index 0000000000..cd5bbb8e08 --- /dev/null +++ b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 + +package db + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/models.go b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/models.go new file mode 100644 index 0000000000..436d16c084 --- /dev/null +++ b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/models.go @@ -0,0 +1,13 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 + +package db + +import ( + "database/sql" +) + +type Example struct { + Bar sql.NullBool +} diff --git a/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql.go b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql.go index 372d6555e8..b0a45aa446 100644 --- a/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql.go +++ b/internal/endtoend/testdata/sqlite_not_bool_arg/sqlite/query.sql.go @@ -13,7 +13,7 @@ const example = `-- name: Example :many select 1 where not ?1 ` -func (q *Queries) Example(ctx context.Context, argname bool) ([]int64, error) { +func (q *Queries) Example(ctx context.Context, argname interface{}) ([]int64, error) { rows, err := q.db.QueryContext(ctx, example, argname) if err != nil { return nil, err