diff --git a/internal/codegen/golang/imports.go b/internal/codegen/golang/imports.go index 7a2c4a254a..2c38a3c48e 100644 --- a/internal/codegen/golang/imports.go +++ b/internal/codegen/golang/imports.go @@ -140,6 +140,7 @@ var pgtypeTypes = map[string]struct{}{ "pgtype.Int8range": {}, "pgtype.JSON": {}, "pgtype.JSONB": {}, + "pgtype.Hstore": {}, "pgtype.Macaddr": {}, "pgtype.Numeric": {}, "pgtype.Numrange": {}, diff --git a/internal/codegen/golang/postgresql_type.go b/internal/codegen/golang/postgresql_type.go index 130bad8961..2a46c24e30 100644 --- a/internal/codegen/golang/postgresql_type.go +++ b/internal/codegen/golang/postgresql_type.go @@ -220,6 +220,12 @@ func postgresType(r *compiler.Result, col *compiler.Column, settings config.Comb } return "interface{}" + case "hstore": + if driver == SQLDriverPGXV4 { + return "pgtype.Hstore" + } + return "interface{}" + case "void": // A void value can only be scanned into an empty interface. return "interface{}" diff --git a/internal/endtoend/testdata/hstore/pgx/go/db.go b/internal/endtoend/testdata/hstore/pgx/go/db.go new file mode 100644 index 0000000000..95557215a5 --- /dev/null +++ b/internal/endtoend/testdata/hstore/pgx/go/db.go @@ -0,0 +1,30 @@ +// Code generated by sqlc. DO NOT EDIT. + +package hstore + +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/hstore/pgx/go/hstore.sql.go b/internal/endtoend/testdata/hstore/pgx/go/hstore.sql.go new file mode 100644 index 0000000000..65a2eb71f5 --- /dev/null +++ b/internal/endtoend/testdata/hstore/pgx/go/hstore.sql.go @@ -0,0 +1,58 @@ +// Code generated by sqlc. DO NOT EDIT. +// source: hstore.sql + +package hstore + +import ( + "context" + + "github.com/jackc/pgtype" +) + +const listBar = `-- name: ListBar :many +SELECT bar FROM foo +` + +func (q *Queries) ListBar(ctx context.Context) ([]pgtype.Hstore, error) { + rows, err := q.db.Query(ctx, listBar) + if err != nil { + return nil, err + } + defer rows.Close() + var items []pgtype.Hstore + for rows.Next() { + var bar pgtype.Hstore + if err := rows.Scan(&bar); err != nil { + return nil, err + } + items = append(items, bar) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listBaz = `-- name: ListBaz :many +SELECT baz FROM foo +` + +func (q *Queries) ListBaz(ctx context.Context) ([]pgtype.Hstore, error) { + rows, err := q.db.Query(ctx, listBaz) + if err != nil { + return nil, err + } + defer rows.Close() + var items []pgtype.Hstore + for rows.Next() { + var baz pgtype.Hstore + if err := rows.Scan(&baz); err != nil { + return nil, err + } + items = append(items, baz) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/hstore/pgx/go/models.go b/internal/endtoend/testdata/hstore/pgx/go/models.go new file mode 100644 index 0000000000..de9de5838d --- /dev/null +++ b/internal/endtoend/testdata/hstore/pgx/go/models.go @@ -0,0 +1,12 @@ +// Code generated by sqlc. DO NOT EDIT. + +package hstore + +import ( + "github.com/jackc/pgtype" +) + +type Foo struct { + Bar pgtype.Hstore + Baz pgtype.Hstore +} diff --git a/internal/endtoend/testdata/hstore/pgx/hstore.sql b/internal/endtoend/testdata/hstore/pgx/hstore.sql new file mode 100644 index 0000000000..ff91ac0291 --- /dev/null +++ b/internal/endtoend/testdata/hstore/pgx/hstore.sql @@ -0,0 +1,12 @@ +CREATE TABLE foo ( + bar hstore NOT NULL, + baz hstore +); + +-- name: ListBar :many +SELECT bar FROM foo; + +-- name: ListBaz :many +SELECT baz FROM foo; + + diff --git a/internal/endtoend/testdata/hstore/pgx/sqlc.json b/internal/endtoend/testdata/hstore/pgx/sqlc.json new file mode 100644 index 0000000000..66b4ca8872 --- /dev/null +++ b/internal/endtoend/testdata/hstore/pgx/sqlc.json @@ -0,0 +1,13 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "sql_package": "pgx/v4", + "name": "hstore", + "schema": "hstore.sql", + "queries": "hstore.sql" + } + ] +} diff --git a/internal/endtoend/testdata/hstore/stdlib/go/db.go b/internal/endtoend/testdata/hstore/stdlib/go/db.go new file mode 100644 index 0000000000..34ea6ddfb7 --- /dev/null +++ b/internal/endtoend/testdata/hstore/stdlib/go/db.go @@ -0,0 +1,29 @@ +// Code generated by sqlc. DO NOT EDIT. + +package hstore + +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/hstore/stdlib/go/hstore.sql.go b/internal/endtoend/testdata/hstore/stdlib/go/hstore.sql.go new file mode 100644 index 0000000000..84afdb5c0c --- /dev/null +++ b/internal/endtoend/testdata/hstore/stdlib/go/hstore.sql.go @@ -0,0 +1,62 @@ +// Code generated by sqlc. DO NOT EDIT. +// source: hstore.sql + +package hstore + +import ( + "context" +) + +const listBar = `-- name: ListBar :many +SELECT bar FROM foo +` + +func (q *Queries) ListBar(ctx context.Context) ([]interface{}, error) { + rows, err := q.db.QueryContext(ctx, listBar) + if err != nil { + return nil, err + } + defer rows.Close() + var items []interface{} + for rows.Next() { + var bar interface{} + if err := rows.Scan(&bar); err != nil { + return nil, err + } + items = append(items, bar) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listBaz = `-- name: ListBaz :many +SELECT baz FROM foo +` + +func (q *Queries) ListBaz(ctx context.Context) ([]interface{}, error) { + rows, err := q.db.QueryContext(ctx, listBaz) + if err != nil { + return nil, err + } + defer rows.Close() + var items []interface{} + for rows.Next() { + var baz interface{} + if err := rows.Scan(&baz); err != nil { + return nil, err + } + items = append(items, baz) + } + 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/hstore/stdlib/go/models.go b/internal/endtoend/testdata/hstore/stdlib/go/models.go new file mode 100644 index 0000000000..3dea5999cd --- /dev/null +++ b/internal/endtoend/testdata/hstore/stdlib/go/models.go @@ -0,0 +1,10 @@ +// Code generated by sqlc. DO NOT EDIT. + +package hstore + +import () + +type Foo struct { + Bar interface{} + Baz interface{} +} diff --git a/internal/endtoend/testdata/hstore/stdlib/hstore.sql b/internal/endtoend/testdata/hstore/stdlib/hstore.sql new file mode 100644 index 0000000000..ff91ac0291 --- /dev/null +++ b/internal/endtoend/testdata/hstore/stdlib/hstore.sql @@ -0,0 +1,12 @@ +CREATE TABLE foo ( + bar hstore NOT NULL, + baz hstore +); + +-- name: ListBar :many +SELECT bar FROM foo; + +-- name: ListBaz :many +SELECT baz FROM foo; + + diff --git a/internal/endtoend/testdata/hstore/stdlib/sqlc.json b/internal/endtoend/testdata/hstore/stdlib/sqlc.json new file mode 100644 index 0000000000..d218312403 --- /dev/null +++ b/internal/endtoend/testdata/hstore/stdlib/sqlc.json @@ -0,0 +1,11 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "name": "hstore", + "schema": "hstore.sql", + "queries": "hstore.sql" + } + ] +}