From f25b96a5849a2e3e1ee23ef6a59e0bf5c4addd27 Mon Sep 17 00:00:00 2001 From: ryu-ichiroh Date: Tue, 9 May 2023 12:01:34 +0900 Subject: [PATCH 1/4] Generate nullable subselect statements --- internal/compiler/output_columns.go | 19 +++++ .../nullable_subselect/mysql/go/db.go | 31 ++++++++ .../nullable_subselect/mysql/go/models.go | 14 ++++ .../nullable_subselect/mysql/go/query.sql.go | 75 +++++++++++++++++++ .../nullable_subselect/mysql/query.sql | 7 ++ .../nullable_subselect/mysql/sqlc.json | 12 +++ .../postgresql/pgx/v4/go/db.go | 32 ++++++++ .../postgresql/pgx/v4/go/models.go | 14 ++++ .../postgresql/pgx/v4/go/query.sql.go | 68 +++++++++++++++++ .../postgresql/pgx/v4/query.sql | 7 ++ .../postgresql/pgx/v4/sqlc.json | 13 ++++ .../postgresql/pgx/v5/go/db.go | 32 ++++++++ .../postgresql/pgx/v5/go/models.go | 14 ++++ .../postgresql/pgx/v5/go/query.sql.go | 68 +++++++++++++++++ .../postgresql/pgx/v5/query.sql | 7 ++ .../postgresql/pgx/v5/sqlc.json | 13 ++++ .../postgresql/stdlib/go/db.go | 31 ++++++++ .../postgresql/stdlib/go/models.go | 14 ++++ .../postgresql/stdlib/go/query.sql.go | 74 ++++++++++++++++++ .../postgresql/stdlib/query.sql | 7 ++ .../postgresql/stdlib/sqlc.json | 12 +++ .../nullable_subselect/sqlite/go/db.go | 31 ++++++++ .../nullable_subselect/sqlite/go/models.go | 14 ++++ .../nullable_subselect/sqlite/go/query.sql.go | 75 +++++++++++++++++++ .../nullable_subselect/sqlite/query.sql | 7 ++ .../nullable_subselect/sqlite/sqlc.json | 12 +++ .../select_nested_count/mysql/go/query.sql.go | 2 +- .../sqlite/go/query.sql.go | 2 +- 28 files changed, 705 insertions(+), 2 deletions(-) create mode 100644 internal/endtoend/testdata/nullable_subselect/mysql/go/db.go create mode 100644 internal/endtoend/testdata/nullable_subselect/mysql/go/models.go create mode 100644 internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go create mode 100644 internal/endtoend/testdata/nullable_subselect/mysql/query.sql create mode 100644 internal/endtoend/testdata/nullable_subselect/mysql/sqlc.json create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/query.sql create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/sqlc.json create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/query.sql create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/sqlc.json create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/query.sql create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/sqlc.json create mode 100644 internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go create mode 100644 internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go create mode 100644 internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go create mode 100644 internal/endtoend/testdata/nullable_subselect/sqlite/query.sql create mode 100644 internal/endtoend/testdata/nullable_subselect/sqlite/sqlc.json diff --git a/internal/compiler/output_columns.go b/internal/compiler/output_columns.go index dbdbe252b3..0487eb45af 100644 --- a/internal/compiler/output_columns.go +++ b/internal/compiler/output_columns.go @@ -377,6 +377,11 @@ func (c *Compiler) outputColumns(qc *QueryCatalog, node ast.Node) ([]*Column, er if res.Name != nil { first.Name = *res.Name } + + if hasWhereOrHavingClause(n) { + first.NotNull = false + } + cols = append(cols, first) default: @@ -764,3 +769,17 @@ func findColumnForRef(ref *ast.ColumnRef, tables []*Table, targetList *ast.List) return nil } + +// hasWhereOrHavingClause returns true if the statement contains WHERE or HAVING clause +func hasWhereOrHavingClause(node ast.Node) bool { + stmt := node.(*ast.SelectStmt) + + if _, isTODO := stmt.WhereClause.(*ast.TODO); stmt.WhereClause != nil && !isTODO { + return true + } + if _, isTODO := stmt.HavingClause.(*ast.TODO); stmt.HavingClause != nil && !isTODO { + return true + } + + return false +} diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/go/db.go b/internal/endtoend/testdata/nullable_subselect/mysql/go/db.go new file mode 100644 index 0000000000..8c5b31f933 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/mysql/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 + +package querytest + +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/nullable_subselect/mysql/go/models.go b/internal/endtoend/testdata/nullable_subselect/mysql/go/models.go new file mode 100644 index 0000000000..3b363b2288 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/mysql/go/models.go @@ -0,0 +1,14 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 + +package querytest + +import ( + "database/sql" +) + +type Foo struct { + A int32 + B sql.NullInt32 +} diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go new file mode 100644 index 0000000000..a139cedbe4 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go @@ -0,0 +1,75 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 +// source: query.sql + +package querytest + +import ( + "context" + "database/sql" +) + +const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many +SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo +` + +type SubqueryWithHavingClauseRow struct { + A int32 + Total sql.NullInt64 +} + +func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { + rows, err := q.db.QueryContext(ctx, subqueryWithHavingClause) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SubqueryWithHavingClauseRow + for rows.Next() { + var i SubqueryWithHavingClauseRow + if err := rows.Scan(&i.A, &i.Total); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const subqueryWithWhereClause = `-- name: SubqueryWithWhereClause :many +SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo +` + +type SubqueryWithWhereClauseRow struct { + A int32 + Total sql.NullInt64 +} + +func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { + rows, err := q.db.QueryContext(ctx, subqueryWithWhereClause) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SubqueryWithWhereClauseRow + for rows.Next() { + var i SubqueryWithWhereClauseRow + if err := rows.Scan(&i.A, &i.Total); err != nil { + return nil, err + } + items = append(items, i) + } + 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/nullable_subselect/mysql/query.sql b/internal/endtoend/testdata/nullable_subselect/mysql/query.sql new file mode 100644 index 0000000000..d68a4cb80d --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/mysql/query.sql @@ -0,0 +1,7 @@ +CREATE TABLE foo (a int not null, b int); + +-- name: SubqueryWithWhereClause :many +SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo; + +-- name: SubqueryWithHavingClause :many +SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo; diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/sqlc.json b/internal/endtoend/testdata/nullable_subselect/mysql/sqlc.json new file mode 100644 index 0000000000..445bbd1589 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/mysql/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "mysql", + "name": "querytest", + "schema": "query.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go new file mode 100644 index 0000000000..5a2cde8cda --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgconn" + "github.com/jackc/pgx/v4" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go new file mode 100644 index 0000000000..3b363b2288 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go @@ -0,0 +1,14 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 + +package querytest + +import ( + "database/sql" +) + +type Foo struct { + A int32 + B sql.NullInt32 +} diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go new file mode 100644 index 0000000000..3964210ab3 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go @@ -0,0 +1,68 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many +SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo +` + +type SubqueryWithHavingClauseRow struct { + A int32 + Total int64 +} + +func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { + rows, err := q.db.Query(ctx, subqueryWithHavingClause) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SubqueryWithHavingClauseRow + for rows.Next() { + var i SubqueryWithHavingClauseRow + if err := rows.Scan(&i.A, &i.Total); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const subqueryWithWhereClause = `-- name: SubqueryWithWhereClause :many +SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo +` + +type SubqueryWithWhereClauseRow struct { + A int32 + Total int64 +} + +func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { + rows, err := q.db.Query(ctx, subqueryWithWhereClause) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SubqueryWithWhereClauseRow + for rows.Next() { + var i SubqueryWithWhereClauseRow + if err := rows.Scan(&i.A, &i.Total); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/query.sql new file mode 100644 index 0000000000..d68a4cb80d --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/query.sql @@ -0,0 +1,7 @@ +CREATE TABLE foo (a int not null, b int); + +-- name: SubqueryWithWhereClause :many +SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo; + +-- name: SubqueryWithHavingClause :many +SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo; diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/sqlc.json b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/sqlc.json new file mode 100644 index 0000000000..9403bd0279 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/sqlc.json @@ -0,0 +1,13 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "sql_package": "pgx/v4", + "name": "querytest", + "schema": "query.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go new file mode 100644 index 0000000000..7bc02a1d7d --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go new file mode 100644 index 0000000000..99fdb18bf8 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go @@ -0,0 +1,14 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 + +package querytest + +import ( + "github.com/jackc/pgx/v5/pgtype" +) + +type Foo struct { + A int32 + B pgtype.Int4 +} diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go new file mode 100644 index 0000000000..3964210ab3 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go @@ -0,0 +1,68 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many +SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo +` + +type SubqueryWithHavingClauseRow struct { + A int32 + Total int64 +} + +func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { + rows, err := q.db.Query(ctx, subqueryWithHavingClause) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SubqueryWithHavingClauseRow + for rows.Next() { + var i SubqueryWithHavingClauseRow + if err := rows.Scan(&i.A, &i.Total); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const subqueryWithWhereClause = `-- name: SubqueryWithWhereClause :many +SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo +` + +type SubqueryWithWhereClauseRow struct { + A int32 + Total int64 +} + +func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { + rows, err := q.db.Query(ctx, subqueryWithWhereClause) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SubqueryWithWhereClauseRow + for rows.Next() { + var i SubqueryWithWhereClauseRow + if err := rows.Scan(&i.A, &i.Total); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/query.sql new file mode 100644 index 0000000000..d68a4cb80d --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/query.sql @@ -0,0 +1,7 @@ +CREATE TABLE foo (a int not null, b int); + +-- name: SubqueryWithWhereClause :many +SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo; + +-- name: SubqueryWithHavingClause :many +SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo; diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/sqlc.json b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/sqlc.json new file mode 100644 index 0000000000..6645ccbd1b --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/sqlc.json @@ -0,0 +1,13 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "sql_package": "pgx/v5", + "name": "querytest", + "schema": "query.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go new file mode 100644 index 0000000000..8c5b31f933 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 + +package querytest + +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/nullable_subselect/postgresql/stdlib/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go new file mode 100644 index 0000000000..3b363b2288 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go @@ -0,0 +1,14 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 + +package querytest + +import ( + "database/sql" +) + +type Foo struct { + A int32 + B sql.NullInt32 +} diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go new file mode 100644 index 0000000000..05981f2002 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go @@ -0,0 +1,74 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many +SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo +` + +type SubqueryWithHavingClauseRow struct { + A int32 + Total int64 +} + +func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { + rows, err := q.db.QueryContext(ctx, subqueryWithHavingClause) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SubqueryWithHavingClauseRow + for rows.Next() { + var i SubqueryWithHavingClauseRow + if err := rows.Scan(&i.A, &i.Total); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const subqueryWithWhereClause = `-- name: SubqueryWithWhereClause :many +SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo +` + +type SubqueryWithWhereClauseRow struct { + A int32 + Total int64 +} + +func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { + rows, err := q.db.QueryContext(ctx, subqueryWithWhereClause) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SubqueryWithWhereClauseRow + for rows.Next() { + var i SubqueryWithWhereClauseRow + if err := rows.Scan(&i.A, &i.Total); err != nil { + return nil, err + } + items = append(items, i) + } + 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/nullable_subselect/postgresql/stdlib/query.sql b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/query.sql new file mode 100644 index 0000000000..d68a4cb80d --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/query.sql @@ -0,0 +1,7 @@ +CREATE TABLE foo (a int not null, b int); + +-- name: SubqueryWithWhereClause :many +SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo; + +-- name: SubqueryWithHavingClause :many +SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo; diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/sqlc.json b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/sqlc.json new file mode 100644 index 0000000000..c72b6132d5 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "name": "querytest", + "schema": "query.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go new file mode 100644 index 0000000000..8c5b31f933 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 + +package querytest + +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/nullable_subselect/sqlite/go/models.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go new file mode 100644 index 0000000000..c109517b0d --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go @@ -0,0 +1,14 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 + +package querytest + +import ( + "database/sql" +) + +type Foo struct { + A int64 + B sql.NullInt64 +} diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go new file mode 100644 index 0000000000..159db0c937 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go @@ -0,0 +1,75 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.18.0 +// source: query.sql + +package querytest + +import ( + "context" + "database/sql" +) + +const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many +SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) FROM foo +` + +type SubqueryWithHavingClauseRow struct { + A int64 + Count int64 +} + +func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { + rows, err := q.db.QueryContext(ctx, subqueryWithHavingClause) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SubqueryWithHavingClauseRow + for rows.Next() { + var i SubqueryWithHavingClauseRow + if err := rows.Scan(&i.A, &i.Count); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const subqueryWithWhereClause = `-- name: SubqueryWithWhereClause :many +SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) FROM foo +` + +type SubqueryWithWhereClauseRow struct { + A int64 + Count sql.NullInt64 +} + +func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { + rows, err := q.db.QueryContext(ctx, subqueryWithWhereClause) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SubqueryWithWhereClauseRow + for rows.Next() { + var i SubqueryWithWhereClauseRow + if err := rows.Scan(&i.A, &i.Count); err != nil { + return nil, err + } + items = append(items, i) + } + 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/nullable_subselect/sqlite/query.sql b/internal/endtoend/testdata/nullable_subselect/sqlite/query.sql new file mode 100644 index 0000000000..3c0edf6ab9 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/query.sql @@ -0,0 +1,7 @@ +CREATE TABLE foo (a int not null, b int); + +-- name: SubqueryWithWhereClause :many +SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) FROM foo; + +-- name: SubqueryWithHavingClause :many +SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) FROM foo; diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/sqlc.json b/internal/endtoend/testdata/nullable_subselect/sqlite/sqlc.json new file mode 100644 index 0000000000..fcb288cb35 --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "sqlite", + "name": "querytest", + "schema": "query.sql", + "queries": "query.sql" + } + ] +} \ No newline at end of file diff --git a/internal/endtoend/testdata/select_nested_count/mysql/go/query.sql.go b/internal/endtoend/testdata/select_nested_count/mysql/go/query.sql.go index 1a0cf351e8..ff6ce3dba8 100644 --- a/internal/endtoend/testdata/select_nested_count/mysql/go/query.sql.go +++ b/internal/endtoend/testdata/select_nested_count/mysql/go/query.sql.go @@ -22,7 +22,7 @@ type GetAuthorsWithBooksCountRow struct { ID int64 Name string Bio sql.NullString - BooksCount int64 + BooksCount sql.NullInt64 } func (q *Queries) GetAuthorsWithBooksCount(ctx context.Context) ([]GetAuthorsWithBooksCountRow, error) { diff --git a/internal/endtoend/testdata/select_nested_count/sqlite/go/query.sql.go b/internal/endtoend/testdata/select_nested_count/sqlite/go/query.sql.go index 1a0cf351e8..ff6ce3dba8 100644 --- a/internal/endtoend/testdata/select_nested_count/sqlite/go/query.sql.go +++ b/internal/endtoend/testdata/select_nested_count/sqlite/go/query.sql.go @@ -22,7 +22,7 @@ type GetAuthorsWithBooksCountRow struct { ID int64 Name string Bio sql.NullString - BooksCount int64 + BooksCount sql.NullInt64 } func (q *Queries) GetAuthorsWithBooksCount(ctx context.Context) ([]GetAuthorsWithBooksCountRow, error) { From bc17be21d2b79de24e5afc48090dc37b8f6d3b34 Mon Sep 17 00:00:00 2001 From: ryu-ichiroh Date: Sun, 30 Jul 2023 22:57:45 +0900 Subject: [PATCH 2/4] regenerate test output with 1.19.1 --- .../endtoend/testdata/nullable_subselect/mysql/go/db.go | 2 +- .../testdata/nullable_subselect/mysql/go/models.go | 2 +- .../testdata/nullable_subselect/mysql/go/query.sql.go | 7 +++---- .../testdata/nullable_subselect/postgresql/pgx/v4/go/db.go | 2 +- .../nullable_subselect/postgresql/pgx/v4/go/models.go | 2 +- .../nullable_subselect/postgresql/pgx/v4/go/query.sql.go | 2 +- .../testdata/nullable_subselect/postgresql/pgx/v5/go/db.go | 2 +- .../nullable_subselect/postgresql/pgx/v5/go/models.go | 2 +- .../nullable_subselect/postgresql/pgx/v5/go/query.sql.go | 2 +- .../testdata/nullable_subselect/postgresql/stdlib/go/db.go | 2 +- .../nullable_subselect/postgresql/stdlib/go/models.go | 2 +- .../nullable_subselect/postgresql/stdlib/go/query.sql.go | 2 +- .../endtoend/testdata/nullable_subselect/sqlite/go/db.go | 2 +- .../testdata/nullable_subselect/sqlite/go/models.go | 2 +- .../testdata/nullable_subselect/sqlite/go/query.sql.go | 5 ++--- 15 files changed, 18 insertions(+), 20 deletions(-) diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/go/db.go b/internal/endtoend/testdata/nullable_subselect/mysql/go/db.go index 8c5b31f933..fb6ae669f6 100644 --- a/internal/endtoend/testdata/nullable_subselect/mysql/go/db.go +++ b/internal/endtoend/testdata/nullable_subselect/mysql/go/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/go/models.go b/internal/endtoend/testdata/nullable_subselect/mysql/go/models.go index 3b363b2288..b29372db24 100644 --- a/internal/endtoend/testdata/nullable_subselect/mysql/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/mysql/go/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go index a139cedbe4..19d9c71d93 100644 --- a/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go @@ -1,13 +1,12 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 // source: query.sql package querytest import ( "context" - "database/sql" ) const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many @@ -16,7 +15,7 @@ SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" type SubqueryWithHavingClauseRow struct { A int32 - Total sql.NullInt64 + Total int64 } func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { @@ -48,7 +47,7 @@ SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo type SubqueryWithWhereClauseRow struct { A int32 - Total sql.NullInt64 + Total int64 } func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go index 5a2cde8cda..f3f26ec6fb 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go index 3b363b2288..b29372db24 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go index 3964210ab3..c1ef865dad 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 // source: query.sql package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go index 7bc02a1d7d..4964d6b58c 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go index 99fdb18bf8..fd7cf619ba 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go index 3964210ab3..c1ef865dad 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 // source: query.sql package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go index 8c5b31f933..fb6ae669f6 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go index 3b363b2288..b29372db24 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go index 05981f2002..19d9c71d93 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 // source: query.sql package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go index 8c5b31f933..fb6ae669f6 100644 --- a/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go index c109517b0d..48867fc1af 100644 --- a/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go index 159db0c937..d6591d63ef 100644 --- a/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go @@ -1,13 +1,12 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.18.0 +// sqlc v1.19.1 // source: query.sql package querytest import ( "context" - "database/sql" ) const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many @@ -48,7 +47,7 @@ SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) FROM foo type SubqueryWithWhereClauseRow struct { A int64 - Count sql.NullInt64 + Count int64 } func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { From deac3f56c12c2ff6df973984b561ada9530df5f2 Mon Sep 17 00:00:00 2001 From: ryu-ichiroh Date: Thu, 3 Aug 2023 09:10:09 +0900 Subject: [PATCH 3/4] fixing the code to make the subselect nullable --- internal/compiler/output_columns.go | 26 ++--- internal/compiler/query.go | 1 + .../nullable_subselect/mysql/go/models.go | 5 + .../nullable_subselect/mysql/go/query.sql.go | 71 +++++++++---- .../nullable_subselect/mysql/query.sql | 13 ++- .../nullable_subselect/mysql/schema.sql | 7 ++ .../nullable_subselect/mysql/sqlc.json | 2 +- .../postgresql/pgx/v4/go/models.go | 5 + .../postgresql/pgx/v4/go/query.sql.go | 68 ++++++++---- .../postgresql/pgx/v4/query.sql | 13 ++- .../postgresql/pgx/v4/schema.sql | 7 ++ .../postgresql/pgx/v4/sqlc.json | 2 +- .../postgresql/pgx/v5/go/models.go | 5 + .../postgresql/pgx/v5/go/query.sql.go | 69 ++++++++---- .../postgresql/pgx/v5/query.sql | 13 ++- .../postgresql/pgx/v5/schema.sql | 7 ++ .../postgresql/pgx/v5/sqlc.json | 2 +- .../postgresql/stdlib/go/models.go | 5 + .../postgresql/stdlib/go/query.sql.go | 71 +++++++++---- .../postgresql/stdlib/query.sql | 13 ++- .../postgresql/stdlib/schema.sql | 7 ++ .../postgresql/stdlib/sqlc.json | 2 +- .../nullable_subselect/sqlite/go/models.go | 5 + .../nullable_subselect/sqlite/go/query.sql.go | 100 +++++++++++++++--- .../nullable_subselect/sqlite/query.sql | 17 ++- .../nullable_subselect/sqlite/schema.sql | 7 ++ .../nullable_subselect/sqlite/sqlc.json | 4 +- .../select_exists/sqlite/go/query.sql.go | 5 +- .../select_nested_count/mysql/go/query.sql.go | 2 +- .../sqlite/go/query.sql.go | 2 +- 30 files changed, 417 insertions(+), 139 deletions(-) create mode 100644 internal/endtoend/testdata/nullable_subselect/mysql/schema.sql create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/schema.sql create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/schema.sql create mode 100644 internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/schema.sql create mode 100644 internal/endtoend/testdata/nullable_subselect/sqlite/schema.sql diff --git a/internal/compiler/output_columns.go b/internal/compiler/output_columns.go index 0487eb45af..6f6232e79c 100644 --- a/internal/compiler/output_columns.go +++ b/internal/compiler/output_columns.go @@ -3,6 +3,7 @@ package compiler import ( "errors" "fmt" + "strings" "github.com/sqlc-dev/sqlc/internal/sql/ast" "github.com/sqlc-dev/sqlc/internal/sql/astutils" @@ -315,12 +316,14 @@ func (c *Compiler) outputColumns(qc *QueryCatalog, node ast.Node) ([]*Column, er DataType: dataType(fun.ReturnType), NotNull: !fun.ReturnTypeNullable, IsFuncCall: true, + FuncName: rel.Name, }) } else { cols = append(cols, &Column{ Name: name, DataType: "any", IsFuncCall: true, + FuncName: rel.Name, }) } @@ -341,6 +344,10 @@ func (c *Compiler) outputColumns(qc *QueryCatalog, node ast.Node) ([]*Column, er if res.Name != nil { first.Name = *res.Name } + if !(first.IsFuncCall && strings.EqualFold(first.FuncName, "count")) { + first.NotNull = false + } + cols = append(cols, first) default: cols = append(cols, &Column{Name: name, DataType: "any", NotNull: false}) @@ -377,8 +384,9 @@ func (c *Compiler) outputColumns(qc *QueryCatalog, node ast.Node) ([]*Column, er if res.Name != nil { first.Name = *res.Name } - - if hasWhereOrHavingClause(n) { + if !(first.IsFuncCall && + (strings.EqualFold(first.FuncName, "count") || + strings.EqualFold(first.FuncName, "total"))) { first.NotNull = false } @@ -769,17 +777,3 @@ func findColumnForRef(ref *ast.ColumnRef, tables []*Table, targetList *ast.List) return nil } - -// hasWhereOrHavingClause returns true if the statement contains WHERE or HAVING clause -func hasWhereOrHavingClause(node ast.Node) bool { - stmt := node.(*ast.SelectStmt) - - if _, isTODO := stmt.WhereClause.(*ast.TODO); stmt.WhereClause != nil && !isTODO { - return true - } - if _, isTODO := stmt.HavingClause.(*ast.TODO); stmt.HavingClause != nil && !isTODO { - return true - } - - return false -} diff --git a/internal/compiler/query.go b/internal/compiler/query.go index b3cf9d6154..068142803e 100644 --- a/internal/compiler/query.go +++ b/internal/compiler/query.go @@ -29,6 +29,7 @@ type Column struct { Length *int IsNamedParam bool IsFuncCall bool + FuncName string // XXX: Figure out what PostgreSQL calls `foo.id` Scope string diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/go/models.go b/internal/endtoend/testdata/nullable_subselect/mysql/go/models.go index b29372db24..56915dca09 100644 --- a/internal/endtoend/testdata/nullable_subselect/mysql/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/mysql/go/models.go @@ -8,6 +8,11 @@ import ( "database/sql" ) +type Empty struct { + A int32 + B sql.NullInt32 +} + type Foo struct { A int32 B sql.NullInt32 diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go index 19d9c71d93..d6d4ec0158 100644 --- a/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/mysql/go/query.sql.go @@ -7,27 +7,30 @@ package querytest import ( "context" + "database/sql" ) -const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many -SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo +const countRowsEmptyTable = `-- name: CountRowsEmptyTable :many +SELECT a, (SELECT count(a) FROM empty) as "count" FROM foo ` -type SubqueryWithHavingClauseRow struct { +type CountRowsEmptyTableRow struct { A int32 - Total int64 + Count int64 } -func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { - rows, err := q.db.QueryContext(ctx, subqueryWithHavingClause) +// In MySQL, only count() returns 0 for empty table. +// https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html +func (q *Queries) CountRowsEmptyTable(ctx context.Context) ([]CountRowsEmptyTableRow, error) { + rows, err := q.db.QueryContext(ctx, countRowsEmptyTable) if err != nil { return nil, err } defer rows.Close() - var items []SubqueryWithHavingClauseRow + var items []CountRowsEmptyTableRow for rows.Next() { - var i SubqueryWithHavingClauseRow - if err := rows.Scan(&i.A, &i.Total); err != nil { + var i CountRowsEmptyTableRow + if err := rows.Scan(&i.A, &i.Count); err != nil { return nil, err } items = append(items, i) @@ -41,25 +44,57 @@ func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithH return items, nil } -const subqueryWithWhereClause = `-- name: SubqueryWithWhereClause :many -SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo +const firstRowFromEmptyTable = `-- name: FirstRowFromEmptyTable :many +SELECT a, (SELECT a FROM empty limit 1) as "first" FROM foo ` -type SubqueryWithWhereClauseRow struct { +type FirstRowFromEmptyTableRow struct { A int32 - Total int64 + First sql.NullInt32 } -func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { - rows, err := q.db.QueryContext(ctx, subqueryWithWhereClause) +func (q *Queries) FirstRowFromEmptyTable(ctx context.Context) ([]FirstRowFromEmptyTableRow, error) { + rows, err := q.db.QueryContext(ctx, firstRowFromEmptyTable) if err != nil { return nil, err } defer rows.Close() - var items []SubqueryWithWhereClauseRow + var items []FirstRowFromEmptyTableRow for rows.Next() { - var i SubqueryWithWhereClauseRow - if err := rows.Scan(&i.A, &i.Total); err != nil { + var i FirstRowFromEmptyTableRow + if err := rows.Scan(&i.A, &i.First); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const firstRowFromFooTable = `-- name: FirstRowFromFooTable :many +SELECT a, (SELECT a FROM foo limit 1) as "first" FROM foo +` + +type FirstRowFromFooTableRow struct { + A int32 + First sql.NullInt32 +} + +func (q *Queries) FirstRowFromFooTable(ctx context.Context) ([]FirstRowFromFooTableRow, error) { + rows, err := q.db.QueryContext(ctx, firstRowFromFooTable) + if err != nil { + return nil, err + } + defer rows.Close() + var items []FirstRowFromFooTableRow + for rows.Next() { + var i FirstRowFromFooTableRow + if err := rows.Scan(&i.A, &i.First); err != nil { return nil, err } items = append(items, i) diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/query.sql b/internal/endtoend/testdata/nullable_subselect/mysql/query.sql index d68a4cb80d..9489d1abbb 100644 --- a/internal/endtoend/testdata/nullable_subselect/mysql/query.sql +++ b/internal/endtoend/testdata/nullable_subselect/mysql/query.sql @@ -1,7 +1,10 @@ -CREATE TABLE foo (a int not null, b int); +-- name: FirstRowFromFooTable :many +SELECT a, (SELECT a FROM foo limit 1) as "first" FROM foo; --- name: SubqueryWithWhereClause :many -SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo; +-- name: FirstRowFromEmptyTable :many +SELECT a, (SELECT a FROM empty limit 1) as "first" FROM foo; --- name: SubqueryWithHavingClause :many -SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo; +-- In MySQL, only count() returns 0 for empty table. +-- https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html +-- name: CountRowsEmptyTable :many +SELECT a, (SELECT count(a) FROM empty) as "count" FROM foo; diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/schema.sql b/internal/endtoend/testdata/nullable_subselect/mysql/schema.sql new file mode 100644 index 0000000000..1119555fdf --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/mysql/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE foo (a int not NULL, b int); + +INSERT INTO foo VALUES (1, 2); +INSERT INTO foo VALUES (3, NULL); +INSERT INTO foo VALUES (4, 5); + +CREATE TABLE empty (a int not NULL, b int); diff --git a/internal/endtoend/testdata/nullable_subselect/mysql/sqlc.json b/internal/endtoend/testdata/nullable_subselect/mysql/sqlc.json index 445bbd1589..e41c39e8b3 100644 --- a/internal/endtoend/testdata/nullable_subselect/mysql/sqlc.json +++ b/internal/endtoend/testdata/nullable_subselect/mysql/sqlc.json @@ -5,7 +5,7 @@ "path": "go", "engine": "mysql", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go index b29372db24..56915dca09 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go @@ -8,6 +8,11 @@ import ( "database/sql" ) +type Empty struct { + A int32 + B sql.NullInt32 +} + type Foo struct { A int32 B sql.NullInt32 diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go index c1ef865dad..7578328ecc 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go @@ -7,27 +7,30 @@ package querytest import ( "context" + "database/sql" ) -const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many -SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo +const countRowsEmptyTable = `-- name: CountRowsEmptyTable :many +SELECT a, (SELECT count(a) FROM empty) as "count" FROM foo ` -type SubqueryWithHavingClauseRow struct { +type CountRowsEmptyTableRow struct { A int32 - Total int64 + Count int64 } -func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { - rows, err := q.db.Query(ctx, subqueryWithHavingClause) +// In PostgreSQL, only count() returns 0 for empty table. +// https://www.postgresql.org/docs/15/functions-aggregate.html +func (q *Queries) CountRowsEmptyTable(ctx context.Context) ([]CountRowsEmptyTableRow, error) { + rows, err := q.db.Query(ctx, countRowsEmptyTable) if err != nil { return nil, err } defer rows.Close() - var items []SubqueryWithHavingClauseRow + var items []CountRowsEmptyTableRow for rows.Next() { - var i SubqueryWithHavingClauseRow - if err := rows.Scan(&i.A, &i.Total); err != nil { + var i CountRowsEmptyTableRow + if err := rows.Scan(&i.A, &i.Count); err != nil { return nil, err } items = append(items, i) @@ -38,25 +41,54 @@ func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithH return items, nil } -const subqueryWithWhereClause = `-- name: SubqueryWithWhereClause :many -SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo +const firstRowFromEmptyTable = `-- name: FirstRowFromEmptyTable :many +SELECT a, (SELECT a FROM empty limit 1) as "first" FROM foo ` -type SubqueryWithWhereClauseRow struct { +type FirstRowFromEmptyTableRow struct { A int32 - Total int64 + First sql.NullInt32 } -func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { - rows, err := q.db.Query(ctx, subqueryWithWhereClause) +func (q *Queries) FirstRowFromEmptyTable(ctx context.Context) ([]FirstRowFromEmptyTableRow, error) { + rows, err := q.db.Query(ctx, firstRowFromEmptyTable) if err != nil { return nil, err } defer rows.Close() - var items []SubqueryWithWhereClauseRow + var items []FirstRowFromEmptyTableRow for rows.Next() { - var i SubqueryWithWhereClauseRow - if err := rows.Scan(&i.A, &i.Total); err != nil { + var i FirstRowFromEmptyTableRow + if err := rows.Scan(&i.A, &i.First); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const firstRowFromFooTable = `-- name: FirstRowFromFooTable :many +SELECT a, (SELECT a FROM foo limit 1) as "first" FROM foo +` + +type FirstRowFromFooTableRow struct { + A int32 + First sql.NullInt32 +} + +func (q *Queries) FirstRowFromFooTable(ctx context.Context) ([]FirstRowFromFooTableRow, error) { + rows, err := q.db.Query(ctx, firstRowFromFooTable) + if err != nil { + return nil, err + } + defer rows.Close() + var items []FirstRowFromFooTableRow + for rows.Next() { + var i FirstRowFromFooTableRow + if err := rows.Scan(&i.A, &i.First); err != nil { return nil, err } items = append(items, i) diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/query.sql b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/query.sql index d68a4cb80d..ace2ad2d77 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/query.sql +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/query.sql @@ -1,7 +1,10 @@ -CREATE TABLE foo (a int not null, b int); +-- name: FirstRowFromFooTable :many +SELECT a, (SELECT a FROM foo limit 1) as "first" FROM foo; --- name: SubqueryWithWhereClause :many -SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo; +-- name: FirstRowFromEmptyTable :many +SELECT a, (SELECT a FROM empty limit 1) as "first" FROM foo; --- name: SubqueryWithHavingClause :many -SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo; +-- In PostgreSQL, only count() returns 0 for empty table. +-- https://www.postgresql.org/docs/15/functions-aggregate.html +-- name: CountRowsEmptyTable :many +SELECT a, (SELECT count(a) FROM empty) as "count" FROM foo; diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/schema.sql b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/schema.sql new file mode 100644 index 0000000000..1119555fdf --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE foo (a int not NULL, b int); + +INSERT INTO foo VALUES (1, 2); +INSERT INTO foo VALUES (3, NULL); +INSERT INTO foo VALUES (4, 5); + +CREATE TABLE empty (a int not NULL, b int); diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/sqlc.json b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/sqlc.json index 9403bd0279..d1244c9e7a 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/sqlc.json +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v4", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go index fd7cf619ba..37e9f1ac45 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go @@ -8,6 +8,11 @@ import ( "github.com/jackc/pgx/v5/pgtype" ) +type Empty struct { + A int32 + B pgtype.Int4 +} + type Foo struct { A int32 B pgtype.Int4 diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go index c1ef865dad..513abf58da 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go @@ -7,27 +7,60 @@ package querytest import ( "context" + + "github.com/jackc/pgx/v5/pgtype" ) -const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many -SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo +const countRowsEmptyTable = `-- name: CountRowsEmptyTable :many +SELECT a, (SELECT count(a) FROM empty) as "count" FROM foo +` + +type CountRowsEmptyTableRow struct { + A int32 + Count int64 +} + +// In PostgreSQL, only count() returns 0 for empty table. +// https://www.postgresql.org/docs/15/functions-aggregate.html +func (q *Queries) CountRowsEmptyTable(ctx context.Context) ([]CountRowsEmptyTableRow, error) { + rows, err := q.db.Query(ctx, countRowsEmptyTable) + if err != nil { + return nil, err + } + defer rows.Close() + var items []CountRowsEmptyTableRow + for rows.Next() { + var i CountRowsEmptyTableRow + if err := rows.Scan(&i.A, &i.Count); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const firstRowFromEmptyTable = `-- name: FirstRowFromEmptyTable :many +SELECT a, (SELECT a FROM empty limit 1) as "first" FROM foo ` -type SubqueryWithHavingClauseRow struct { +type FirstRowFromEmptyTableRow struct { A int32 - Total int64 + First pgtype.Int4 } -func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { - rows, err := q.db.Query(ctx, subqueryWithHavingClause) +func (q *Queries) FirstRowFromEmptyTable(ctx context.Context) ([]FirstRowFromEmptyTableRow, error) { + rows, err := q.db.Query(ctx, firstRowFromEmptyTable) if err != nil { return nil, err } defer rows.Close() - var items []SubqueryWithHavingClauseRow + var items []FirstRowFromEmptyTableRow for rows.Next() { - var i SubqueryWithHavingClauseRow - if err := rows.Scan(&i.A, &i.Total); err != nil { + var i FirstRowFromEmptyTableRow + if err := rows.Scan(&i.A, &i.First); err != nil { return nil, err } items = append(items, i) @@ -38,25 +71,25 @@ func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithH return items, nil } -const subqueryWithWhereClause = `-- name: SubqueryWithWhereClause :many -SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo +const firstRowFromFooTable = `-- name: FirstRowFromFooTable :many +SELECT a, (SELECT a FROM foo limit 1) as "first" FROM foo ` -type SubqueryWithWhereClauseRow struct { +type FirstRowFromFooTableRow struct { A int32 - Total int64 + First pgtype.Int4 } -func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { - rows, err := q.db.Query(ctx, subqueryWithWhereClause) +func (q *Queries) FirstRowFromFooTable(ctx context.Context) ([]FirstRowFromFooTableRow, error) { + rows, err := q.db.Query(ctx, firstRowFromFooTable) if err != nil { return nil, err } defer rows.Close() - var items []SubqueryWithWhereClauseRow + var items []FirstRowFromFooTableRow for rows.Next() { - var i SubqueryWithWhereClauseRow - if err := rows.Scan(&i.A, &i.Total); err != nil { + var i FirstRowFromFooTableRow + if err := rows.Scan(&i.A, &i.First); err != nil { return nil, err } items = append(items, i) diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/query.sql index d68a4cb80d..ace2ad2d77 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/query.sql +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/query.sql @@ -1,7 +1,10 @@ -CREATE TABLE foo (a int not null, b int); +-- name: FirstRowFromFooTable :many +SELECT a, (SELECT a FROM foo limit 1) as "first" FROM foo; --- name: SubqueryWithWhereClause :many -SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo; +-- name: FirstRowFromEmptyTable :many +SELECT a, (SELECT a FROM empty limit 1) as "first" FROM foo; --- name: SubqueryWithHavingClause :many -SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo; +-- In PostgreSQL, only count() returns 0 for empty table. +-- https://www.postgresql.org/docs/15/functions-aggregate.html +-- name: CountRowsEmptyTable :many +SELECT a, (SELECT count(a) FROM empty) as "count" FROM foo; diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/schema.sql b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/schema.sql new file mode 100644 index 0000000000..1119555fdf --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE foo (a int not NULL, b int); + +INSERT INTO foo VALUES (1, 2); +INSERT INTO foo VALUES (3, NULL); +INSERT INTO foo VALUES (4, 5); + +CREATE TABLE empty (a int not NULL, b int); diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/sqlc.json b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/sqlc.json index 6645ccbd1b..32ede07158 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/sqlc.json +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/sqlc.json @@ -6,7 +6,7 @@ "engine": "postgresql", "sql_package": "pgx/v5", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go index b29372db24..56915dca09 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go @@ -8,6 +8,11 @@ import ( "database/sql" ) +type Empty struct { + A int32 + B sql.NullInt32 +} + type Foo struct { A int32 B sql.NullInt32 diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go index 19d9c71d93..676be08441 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go @@ -7,27 +7,30 @@ package querytest import ( "context" + "database/sql" ) -const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many -SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo +const countRowsEmptyTable = `-- name: CountRowsEmptyTable :many +SELECT a, (SELECT count(a) FROM empty) as "count" FROM foo ` -type SubqueryWithHavingClauseRow struct { +type CountRowsEmptyTableRow struct { A int32 - Total int64 + Count int64 } -func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { - rows, err := q.db.QueryContext(ctx, subqueryWithHavingClause) +// In PostgreSQL, only count() returns 0 for empty table. +// https://www.postgresql.org/docs/15/functions-aggregate.html +func (q *Queries) CountRowsEmptyTable(ctx context.Context) ([]CountRowsEmptyTableRow, error) { + rows, err := q.db.QueryContext(ctx, countRowsEmptyTable) if err != nil { return nil, err } defer rows.Close() - var items []SubqueryWithHavingClauseRow + var items []CountRowsEmptyTableRow for rows.Next() { - var i SubqueryWithHavingClauseRow - if err := rows.Scan(&i.A, &i.Total); err != nil { + var i CountRowsEmptyTableRow + if err := rows.Scan(&i.A, &i.Count); err != nil { return nil, err } items = append(items, i) @@ -41,25 +44,57 @@ func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithH return items, nil } -const subqueryWithWhereClause = `-- name: SubqueryWithWhereClause :many -SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo +const firstRowFromEmptyTable = `-- name: FirstRowFromEmptyTable :many +SELECT a, (SELECT a FROM empty limit 1) as "first" FROM foo ` -type SubqueryWithWhereClauseRow struct { +type FirstRowFromEmptyTableRow struct { A int32 - Total int64 + First sql.NullInt32 } -func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { - rows, err := q.db.QueryContext(ctx, subqueryWithWhereClause) +func (q *Queries) FirstRowFromEmptyTable(ctx context.Context) ([]FirstRowFromEmptyTableRow, error) { + rows, err := q.db.QueryContext(ctx, firstRowFromEmptyTable) if err != nil { return nil, err } defer rows.Close() - var items []SubqueryWithWhereClauseRow + var items []FirstRowFromEmptyTableRow for rows.Next() { - var i SubqueryWithWhereClauseRow - if err := rows.Scan(&i.A, &i.Total); err != nil { + var i FirstRowFromEmptyTableRow + if err := rows.Scan(&i.A, &i.First); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const firstRowFromFooTable = `-- name: FirstRowFromFooTable :many +SELECT a, (SELECT a FROM foo limit 1) as "first" FROM foo +` + +type FirstRowFromFooTableRow struct { + A int32 + First sql.NullInt32 +} + +func (q *Queries) FirstRowFromFooTable(ctx context.Context) ([]FirstRowFromFooTableRow, error) { + rows, err := q.db.QueryContext(ctx, firstRowFromFooTable) + if err != nil { + return nil, err + } + defer rows.Close() + var items []FirstRowFromFooTableRow + for rows.Next() { + var i FirstRowFromFooTableRow + if err := rows.Scan(&i.A, &i.First); err != nil { return nil, err } items = append(items, i) diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/query.sql b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/query.sql index d68a4cb80d..ace2ad2d77 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/query.sql +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/query.sql @@ -1,7 +1,10 @@ -CREATE TABLE foo (a int not null, b int); +-- name: FirstRowFromFooTable :many +SELECT a, (SELECT a FROM foo limit 1) as "first" FROM foo; --- name: SubqueryWithWhereClause :many -SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) as "total" FROM foo; +-- name: FirstRowFromEmptyTable :many +SELECT a, (SELECT a FROM empty limit 1) as "first" FROM foo; --- name: SubqueryWithHavingClause :many -SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) as "total" FROM foo; +-- In PostgreSQL, only count() returns 0 for empty table. +-- https://www.postgresql.org/docs/15/functions-aggregate.html +-- name: CountRowsEmptyTable :many +SELECT a, (SELECT count(a) FROM empty) as "count" FROM foo; diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/schema.sql b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/schema.sql new file mode 100644 index 0000000000..1119555fdf --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE foo (a int not NULL, b int); + +INSERT INTO foo VALUES (1, 2); +INSERT INTO foo VALUES (3, NULL); +INSERT INTO foo VALUES (4, 5); + +CREATE TABLE empty (a int not NULL, b int); diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/sqlc.json b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/sqlc.json index c72b6132d5..f717ca2e66 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/sqlc.json +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/sqlc.json @@ -5,7 +5,7 @@ "path": "go", "engine": "postgresql", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go index 48867fc1af..2f12b94418 100644 --- a/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go @@ -8,6 +8,11 @@ import ( "database/sql" ) +type Empty struct { + A int64 + B sql.NullInt64 +} + type Foo struct { A int64 B sql.NullInt64 diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go index d6591d63ef..2fc2360220 100644 --- a/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go @@ -7,26 +7,30 @@ package querytest import ( "context" + "database/sql" ) -const subqueryWithHavingClause = `-- name: SubqueryWithHavingClause :many -SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) FROM foo +const countRowsEmptyTable = `-- name: CountRowsEmptyTable :many + +SELECT a, (SELECT count(a) FROM empty) as "count" FROM foo ` -type SubqueryWithHavingClauseRow struct { +type CountRowsEmptyTableRow struct { A int64 Count int64 } -func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithHavingClauseRow, error) { - rows, err := q.db.QueryContext(ctx, subqueryWithHavingClause) +// In SQLite, count() and total() return 0 for empty table. +// https://www.sqlite.org/lang_aggfunc.html +func (q *Queries) CountRowsEmptyTable(ctx context.Context) ([]CountRowsEmptyTableRow, error) { + rows, err := q.db.QueryContext(ctx, countRowsEmptyTable) if err != nil { return nil, err } defer rows.Close() - var items []SubqueryWithHavingClauseRow + var items []CountRowsEmptyTableRow for rows.Next() { - var i SubqueryWithHavingClauseRow + var i CountRowsEmptyTableRow if err := rows.Scan(&i.A, &i.Count); err != nil { return nil, err } @@ -41,25 +45,89 @@ func (q *Queries) SubqueryWithHavingClause(ctx context.Context) ([]SubqueryWithH return items, nil } -const subqueryWithWhereClause = `-- name: SubqueryWithWhereClause :many -SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) FROM foo +const firstRowFromEmptyTable = `-- name: FirstRowFromEmptyTable :many +SELECT a, (SELECT a FROM empty limit 1) as "first" FROM foo ` -type SubqueryWithWhereClauseRow struct { +type FirstRowFromEmptyTableRow struct { A int64 - Count int64 + First sql.NullInt64 } -func (q *Queries) SubqueryWithWhereClause(ctx context.Context) ([]SubqueryWithWhereClauseRow, error) { - rows, err := q.db.QueryContext(ctx, subqueryWithWhereClause) +func (q *Queries) FirstRowFromEmptyTable(ctx context.Context) ([]FirstRowFromEmptyTableRow, error) { + rows, err := q.db.QueryContext(ctx, firstRowFromEmptyTable) if err != nil { return nil, err } defer rows.Close() - var items []SubqueryWithWhereClauseRow + var items []FirstRowFromEmptyTableRow for rows.Next() { - var i SubqueryWithWhereClauseRow - if err := rows.Scan(&i.A, &i.Count); err != nil { + var i FirstRowFromEmptyTableRow + if err := rows.Scan(&i.A, &i.First); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const firstRowFromFooTable = `-- name: FirstRowFromFooTable :many +SELECT a, (SELECT a FROM foo limit 1) as "first" FROM foo +` + +type FirstRowFromFooTableRow struct { + A int64 + First sql.NullInt64 +} + +func (q *Queries) FirstRowFromFooTable(ctx context.Context) ([]FirstRowFromFooTableRow, error) { + rows, err := q.db.QueryContext(ctx, firstRowFromFooTable) + if err != nil { + return nil, err + } + defer rows.Close() + var items []FirstRowFromFooTableRow + for rows.Next() { + var i FirstRowFromFooTableRow + if err := rows.Scan(&i.A, &i.First); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const totalEmptyTable = `-- name: TotalEmptyTable :many +SELECT a, (SELECT total(a) FROM empty) as "total" FROM foo +` + +type TotalEmptyTableRow struct { + A int64 + Total float64 +} + +func (q *Queries) TotalEmptyTable(ctx context.Context) ([]TotalEmptyTableRow, error) { + rows, err := q.db.QueryContext(ctx, totalEmptyTable) + if err != nil { + return nil, err + } + defer rows.Close() + var items []TotalEmptyTableRow + for rows.Next() { + var i TotalEmptyTableRow + if err := rows.Scan(&i.A, &i.Total); err != nil { return nil, err } items = append(items, i) diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/query.sql b/internal/endtoend/testdata/nullable_subselect/sqlite/query.sql index 3c0edf6ab9..b378a40440 100644 --- a/internal/endtoend/testdata/nullable_subselect/sqlite/query.sql +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/query.sql @@ -1,7 +1,14 @@ -CREATE TABLE foo (a int not null, b int); +-- name: FirstRowFromFooTable :many +SELECT a, (SELECT a FROM foo limit 1) as "first" FROM foo; --- name: SubqueryWithWhereClause :many -SELECT a, (SELECT COUNT(a) FROM foo WHERE a > 10) FROM foo; +-- name: FirstRowFromEmptyTable :many +SELECT a, (SELECT a FROM empty limit 1) as "first" FROM foo; --- name: SubqueryWithHavingClause :many -SELECT a, (SELECT COUNT(a) FROM foo GROUP BY b HAVING COUNT(a) > 10) FROM foo; +-- In SQLite, count() and total() return 0 for empty table. +-- https://www.sqlite.org/lang_aggfunc.html + +-- name: CountRowsEmptyTable :many +SELECT a, (SELECT count(a) FROM empty) as "count" FROM foo; + +-- name: TotalEmptyTable :many +SELECT a, (SELECT total(a) FROM empty) as "total" FROM foo; diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/schema.sql b/internal/endtoend/testdata/nullable_subselect/sqlite/schema.sql new file mode 100644 index 0000000000..1119555fdf --- /dev/null +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE foo (a int not NULL, b int); + +INSERT INTO foo VALUES (1, 2); +INSERT INTO foo VALUES (3, NULL); +INSERT INTO foo VALUES (4, 5); + +CREATE TABLE empty (a int not NULL, b int); diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/sqlc.json b/internal/endtoend/testdata/nullable_subselect/sqlite/sqlc.json index fcb288cb35..cd66df063b 100644 --- a/internal/endtoend/testdata/nullable_subselect/sqlite/sqlc.json +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/sqlc.json @@ -5,8 +5,8 @@ "path": "go", "engine": "sqlite", "name": "querytest", - "schema": "query.sql", + "schema": "schema.sql", "queries": "query.sql" } ] -} \ No newline at end of file +} diff --git a/internal/endtoend/testdata/select_exists/sqlite/go/query.sql.go b/internal/endtoend/testdata/select_exists/sqlite/go/query.sql.go index b4f00584ec..cba10d3a55 100644 --- a/internal/endtoend/testdata/select_exists/sqlite/go/query.sql.go +++ b/internal/endtoend/testdata/select_exists/sqlite/go/query.sql.go @@ -7,6 +7,7 @@ package querytest import ( "context" + "database/sql" ) const barExists = `-- name: BarExists :one @@ -21,9 +22,9 @@ SELECT ) ` -func (q *Queries) BarExists(ctx context.Context, id int64) (int64, error) { +func (q *Queries) BarExists(ctx context.Context, id int64) (sql.NullInt64, error) { row := q.db.QueryRowContext(ctx, barExists, id) - var column_1 int64 + var column_1 sql.NullInt64 err := row.Scan(&column_1) return column_1, err } diff --git a/internal/endtoend/testdata/select_nested_count/mysql/go/query.sql.go b/internal/endtoend/testdata/select_nested_count/mysql/go/query.sql.go index ff6ce3dba8..1a0cf351e8 100644 --- a/internal/endtoend/testdata/select_nested_count/mysql/go/query.sql.go +++ b/internal/endtoend/testdata/select_nested_count/mysql/go/query.sql.go @@ -22,7 +22,7 @@ type GetAuthorsWithBooksCountRow struct { ID int64 Name string Bio sql.NullString - BooksCount sql.NullInt64 + BooksCount int64 } func (q *Queries) GetAuthorsWithBooksCount(ctx context.Context) ([]GetAuthorsWithBooksCountRow, error) { diff --git a/internal/endtoend/testdata/select_nested_count/sqlite/go/query.sql.go b/internal/endtoend/testdata/select_nested_count/sqlite/go/query.sql.go index ff6ce3dba8..1a0cf351e8 100644 --- a/internal/endtoend/testdata/select_nested_count/sqlite/go/query.sql.go +++ b/internal/endtoend/testdata/select_nested_count/sqlite/go/query.sql.go @@ -22,7 +22,7 @@ type GetAuthorsWithBooksCountRow struct { ID int64 Name string Bio sql.NullString - BooksCount sql.NullInt64 + BooksCount int64 } func (q *Queries) GetAuthorsWithBooksCount(ctx context.Context) ([]GetAuthorsWithBooksCountRow, error) { From bc23cccbc0c7fa36433a36fad56347df7b2838f4 Mon Sep 17 00:00:00 2001 From: ryu-ichiroh Date: Thu, 3 Aug 2023 09:38:58 +0900 Subject: [PATCH 4/4] regenerate test output with 1.20.0 --- .../testdata/nullable_subselect/postgresql/pgx/v4/go/db.go | 2 +- .../testdata/nullable_subselect/postgresql/pgx/v4/go/models.go | 2 +- .../nullable_subselect/postgresql/pgx/v4/go/query.sql.go | 2 +- .../testdata/nullable_subselect/postgresql/pgx/v5/go/db.go | 2 +- .../testdata/nullable_subselect/postgresql/pgx/v5/go/models.go | 2 +- .../nullable_subselect/postgresql/pgx/v5/go/query.sql.go | 2 +- .../testdata/nullable_subselect/postgresql/stdlib/go/db.go | 2 +- .../testdata/nullable_subselect/postgresql/stdlib/go/models.go | 2 +- .../nullable_subselect/postgresql/stdlib/go/query.sql.go | 2 +- internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go | 2 +- .../endtoend/testdata/nullable_subselect/sqlite/go/models.go | 2 +- .../endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go index f3f26ec6fb..f0ea7fd21a 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go index 56915dca09..852556161d 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go index 7578328ecc..a398b4f071 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v4/go/query.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 // source: query.sql package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go index 4964d6b58c..e715a0f400 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go index 37e9f1ac45..b51b97d52c 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go index 513abf58da..f878f4e192 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/pgx/v5/go/query.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 // source: query.sql package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go index fb6ae669f6..57406b68e8 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go index 56915dca09..852556161d 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go index 676be08441..13cc71504c 100644 --- a/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/postgresql/stdlib/go/query.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 // source: query.sql package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go index fb6ae669f6..57406b68e8 100644 --- a/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go index 2f12b94418..d5028ecbc0 100644 --- a/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 package querytest diff --git a/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go b/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go index 2fc2360220..33e5cd8cf4 100644 --- a/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go +++ b/internal/endtoend/testdata/nullable_subselect/sqlite/go/query.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.19.1 +// sqlc v1.20.0 // source: query.sql package querytest