diff --git a/internal/compiler/output_columns.go b/internal/compiler/output_columns.go index 8dfca0c5d3..6ced89ae23 100644 --- a/internal/compiler/output_columns.go +++ b/internal/compiler/output_columns.go @@ -608,6 +608,9 @@ func (c *Compiler) sourceTables(qc *QueryCatalog, node ast.Node) ([]*Table, erro if err != nil { return nil, err } + if qc == nil { + return nil, fmt.Errorf("query catalog is empty") + } table, cerr := qc.GetTable(fqn) if cerr != nil { // TODO: Update error location diff --git a/internal/compiler/resolve.go b/internal/compiler/resolve.go index 4624c5a45d..508c5600f6 100644 --- a/internal/compiler/resolve.go +++ b/internal/compiler/resolve.go @@ -63,7 +63,10 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar, } table, err := c.GetTable(fqn) if err != nil { - // If the table name doesn't exist, fisrt check if it's a CTE + if qc == nil { + continue + } + // If the table name doesn't exist, first check if it's a CTE if _, qcerr := qc.GetTable(fqn); qcerr != nil { return nil, err } diff --git a/internal/endtoend/testdata/cte_update/issue.md b/internal/endtoend/testdata/cte_update/issue.md new file mode 100644 index 0000000000..5f1a5921ed --- /dev/null +++ b/internal/endtoend/testdata/cte_update/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1515 diff --git a/internal/endtoend/testdata/cte_update/postgresql/pgx/exec.json b/internal/endtoend/testdata/cte_update/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/cte_update/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/cte_update/postgresql/pgx/go/db.go b/internal/endtoend/testdata/cte_update/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/cte_update/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.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/cte_update/postgresql/pgx/go/models.go b/internal/endtoend/testdata/cte_update/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..9e014185ee --- /dev/null +++ b/internal/endtoend/testdata/cte_update/postgresql/pgx/go/models.go @@ -0,0 +1,18 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () + +type Attribute struct { + ID int64 + Name string +} + +type AttributeValue struct { + ID int64 + Val string + Attribute int64 +} diff --git a/internal/endtoend/testdata/cte_update/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/cte_update/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..4bcad215ec --- /dev/null +++ b/internal/endtoend/testdata/cte_update/postgresql/pgx/go/query.sql.go @@ -0,0 +1,42 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const updateAttribute = `-- name: UpdateAttribute :one +with updated_attribute as (UPDATE attribute_value + SET + val = CASE WHEN $1::bool THEN $2 ELSE val END + WHERE attribute_value.id = $3 + RETURNING id,attribute,val) +select updated_attribute.id, val, name +from updated_attribute + left join attribute on updated_attribute.attribute = attribute.id +` + +type UpdateAttributeParams struct { + FilterValue pgtype.Bool + Value pgtype.Text + ID pgtype.Int8 +} + +type UpdateAttributeRow struct { + ID int64 + Val string + Name pgtype.Text +} + +func (q *Queries) UpdateAttribute(ctx context.Context, arg UpdateAttributeParams) (UpdateAttributeRow, error) { + row := q.db.QueryRow(ctx, updateAttribute, arg.FilterValue, arg.Value, arg.ID) + var i UpdateAttributeRow + err := row.Scan(&i.ID, &i.Val, &i.Name) + return i, err +} diff --git a/internal/endtoend/testdata/cte_update/postgresql/pgx/query.sql b/internal/endtoend/testdata/cte_update/postgresql/pgx/query.sql new file mode 100644 index 0000000000..6ba9aa4e7a --- /dev/null +++ b/internal/endtoend/testdata/cte_update/postgresql/pgx/query.sql @@ -0,0 +1,9 @@ +-- name: UpdateAttribute :one +with updated_attribute as (UPDATE attribute_value + SET + val = CASE WHEN @filter_value::bool THEN @value ELSE val END + WHERE attribute_value.id = @id + RETURNING id,attribute,val) +select updated_attribute.id, val, name +from updated_attribute + left join attribute on updated_attribute.attribute = attribute.id; diff --git a/internal/endtoend/testdata/cte_update/postgresql/pgx/schema.sql b/internal/endtoend/testdata/cte_update/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..6273c9a7e0 --- /dev/null +++ b/internal/endtoend/testdata/cte_update/postgresql/pgx/schema.sql @@ -0,0 +1,12 @@ +create table attribute_value +( + id bigserial not null, + val text not null, + attribute bigint not null +); + +create table attribute +( + id bigserial not null, + name text not null +); diff --git a/internal/endtoend/testdata/cte_update/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/cte_update/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..5dc63e3f91 --- /dev/null +++ b/internal/endtoend/testdata/cte_update/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" diff --git a/internal/endtoend/testdata/func_return_table/issue.md b/internal/endtoend/testdata/func_return_table/issue.md new file mode 100644 index 0000000000..119a3cd987 --- /dev/null +++ b/internal/endtoend/testdata/func_return_table/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1322 diff --git a/internal/endtoend/testdata/func_return_table/postgresql/pgx/exec.json b/internal/endtoend/testdata/func_return_table/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/func_return_table/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/func_return_table/postgresql/pgx/go/db.go b/internal/endtoend/testdata/func_return_table/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/func_return_table/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.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/func_return_table/postgresql/pgx/go/models.go b/internal/endtoend/testdata/func_return_table/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..2b46ef0083 --- /dev/null +++ b/internal/endtoend/testdata/func_return_table/postgresql/pgx/go/models.go @@ -0,0 +1,13 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () + +type Account struct { + ID int32 + Username string + Password string +} diff --git a/internal/endtoend/testdata/func_return_table/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/func_return_table/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..04ee7b02f2 --- /dev/null +++ b/internal/endtoend/testdata/func_return_table/postgresql/pgx/go/query.sql.go @@ -0,0 +1,23 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const foo = `-- name: Foo :one +SELECT register_account FROM register_account('a', 'b') +` + +func (q *Queries) Foo(ctx context.Context) (pgtype.Int4, error) { + row := q.db.QueryRow(ctx, foo) + var register_account pgtype.Int4 + err := row.Scan(®ister_account) + return register_account, err +} diff --git a/internal/endtoend/testdata/func_return_table/postgresql/pgx/query.sql b/internal/endtoend/testdata/func_return_table/postgresql/pgx/query.sql new file mode 100644 index 0000000000..8a3db0f6d8 --- /dev/null +++ b/internal/endtoend/testdata/func_return_table/postgresql/pgx/query.sql @@ -0,0 +1,2 @@ +-- name: Foo :one +SELECT * FROM register_account('a', 'b'); diff --git a/internal/endtoend/testdata/func_return_table/postgresql/pgx/schema.sql b/internal/endtoend/testdata/func_return_table/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..e9ebf5e423 --- /dev/null +++ b/internal/endtoend/testdata/func_return_table/postgresql/pgx/schema.sql @@ -0,0 +1,27 @@ +CREATE TABLE accounts ( + id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, + username TEXT NOT NULL UNIQUE, + password TEXT NOT NULL +); + +-- this is a useless and horrifying function cause we don't hash +-- the password, this is just to repro the bug in sqlc +CREATE OR REPLACE FUNCTION register_account( + _username TEXT, + _password VARCHAR(70) +) +RETURNS TABLE ( + account_id INTEGER +) +AS $$ +BEGIN + INSERT INTO accounts (username, password) + VALUES ( + _username, + _password + ) + RETURNING id INTO account_id; + + RETURN NEXT; +END; +$$ LANGUAGE plpgsql; diff --git a/internal/endtoend/testdata/func_return_table/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/func_return_table/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..5dc63e3f91 --- /dev/null +++ b/internal/endtoend/testdata/func_return_table/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5" diff --git a/internal/endtoend/testdata/join_using/issue.md b/internal/endtoend/testdata/join_using/issue.md new file mode 100644 index 0000000000..29861d9662 --- /dev/null +++ b/internal/endtoend/testdata/join_using/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/1425 diff --git a/internal/endtoend/testdata/join_using/postgresql/pgx/exec.json b/internal/endtoend/testdata/join_using/postgresql/pgx/exec.json new file mode 100644 index 0000000000..ee1b7ecd9e --- /dev/null +++ b/internal/endtoend/testdata/join_using/postgresql/pgx/exec.json @@ -0,0 +1,3 @@ +{ + "contexts": ["managed-db"] +} diff --git a/internal/endtoend/testdata/join_using/postgresql/pgx/go/db.go b/internal/endtoend/testdata/join_using/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..8a010ccc48 --- /dev/null +++ b/internal/endtoend/testdata/join_using/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.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/join_using/postgresql/pgx/go/models.go b/internal/endtoend/testdata/join_using/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..4e0fc50bf7 --- /dev/null +++ b/internal/endtoend/testdata/join_using/postgresql/pgx/go/models.go @@ -0,0 +1,15 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 + +package querytest + +import () + +type T1 struct { + Fk int32 +} + +type T2 struct { + Fk int32 +} diff --git a/internal/endtoend/testdata/join_using/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/join_using/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..1d32bfe901 --- /dev/null +++ b/internal/endtoend/testdata/join_using/postgresql/pgx/go/query.sql.go @@ -0,0 +1,41 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.22.0 +// source: query.sql + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const selectJoinUsing = `-- name: SelectJoinUsing :many +select t1.fk, sum(t2.fk) from t1 join t2 using (fk) group by fk +` + +type SelectJoinUsingRow struct { + Fk int32 + Sum pgtype.Int8 +} + +func (q *Queries) SelectJoinUsing(ctx context.Context) ([]SelectJoinUsingRow, error) { + rows, err := q.db.Query(ctx, selectJoinUsing) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SelectJoinUsingRow + for rows.Next() { + var i SelectJoinUsingRow + if err := rows.Scan(&i.Fk, &i.Sum); 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/join_using/postgresql/pgx/query.sql b/internal/endtoend/testdata/join_using/postgresql/pgx/query.sql new file mode 100644 index 0000000000..67a732e02e --- /dev/null +++ b/internal/endtoend/testdata/join_using/postgresql/pgx/query.sql @@ -0,0 +1,2 @@ +-- name: SelectJoinUsing :many +select t1.fk, sum(t2.fk) from t1 join t2 using (fk) group by fk; diff --git a/internal/endtoend/testdata/join_using/postgresql/pgx/schema.sql b/internal/endtoend/testdata/join_using/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..1e7b5a851d --- /dev/null +++ b/internal/endtoend/testdata/join_using/postgresql/pgx/schema.sql @@ -0,0 +1,6 @@ +create table t1 ( + fk integer not null unique +); +create table t2 ( + fk integer not null references t1(fk) +); diff --git a/internal/endtoend/testdata/join_using/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/join_using/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..5dc63e3f91 --- /dev/null +++ b/internal/endtoend/testdata/join_using/postgresql/pgx/sqlc.yaml @@ -0,0 +1,10 @@ +version: "2" +sql: + - engine: "postgresql" + schema: "schema.sql" + queries: "query.sql" + gen: + go: + package: "querytest" + out: "go" + sql_package: "pgx/v5"