diff --git a/internal/codegen/golang/result.go b/internal/codegen/golang/result.go index ffd4ee90ad..1ab01b4de0 100644 --- a/internal/codegen/golang/result.go +++ b/internal/codegen/golang/result.go @@ -7,6 +7,7 @@ import ( "github.com/kyleconroy/sqlc/internal/codegen/sdk" "github.com/kyleconroy/sqlc/internal/inflection" + "github.com/kyleconroy/sqlc/internal/metadata" "github.com/kyleconroy/sqlc/internal/plugin" ) @@ -200,7 +201,7 @@ func buildQueries(req *plugin.CodeGenRequest, structs []Struct) ([]Query, error) Typ: goType(req, c), SQLPackage: sqlpkg, } - } else if len(query.Columns) > 1 { + } else if putOutColumns(query) { var gs *Struct var emit bool @@ -254,6 +255,18 @@ func buildQueries(req *plugin.CodeGenRequest, structs []Struct) ([]Query, error) return qs, nil } +func putOutColumns(query *plugin.Query) bool { + if len(query.Columns) > 0 { + return true + } + for _, allowed := range []string{metadata.CmdMany, metadata.CmdOne, metadata.CmdBatchMany} { + if query.Cmd == allowed { + return true + } + } + return false +} + // It's possible that this method will generate duplicate JSON tag values // // Columns: count, count, count_2 diff --git a/internal/codegen/golang/result_test.go b/internal/codegen/golang/result_test.go new file mode 100644 index 0000000000..b3b1fbb59f --- /dev/null +++ b/internal/codegen/golang/result_test.go @@ -0,0 +1,78 @@ +package golang + +import ( + "testing" + + "github.com/kyleconroy/sqlc/internal/metadata" + "github.com/kyleconroy/sqlc/internal/plugin" +) + +func TestPutOutColumns_ForZeroColumns(t *testing.T) { + tests := []struct { + cmd string + want bool + }{ + { + cmd: metadata.CmdExec, + want: false, + }, + { + cmd: metadata.CmdExecResult, + want: false, + }, + { + cmd: metadata.CmdExecRows, + want: false, + }, + { + cmd: metadata.CmdExecLastId, + want: false, + }, + { + cmd: metadata.CmdMany, + want: true, + }, + { + cmd: metadata.CmdOne, + want: true, + }, + { + cmd: metadata.CmdCopyFrom, + want: false, + }, + { + cmd: metadata.CmdBatchExec, + want: false, + }, + { + cmd: metadata.CmdBatchMany, + want: true, + }, + { + cmd: metadata.CmdBatchOne, + want: false, + }, + } + for _, tc := range tests { + t.Run(tc.cmd, func(t *testing.T) { + query := &plugin.Query{ + Cmd: tc.cmd, + Columns: []*plugin.Column{}, + } + got := putOutColumns(query) + if got != tc.want { + t.Errorf("putOutColumns failed. want %v, got %v", tc.want, got) + } + }) + } +} + +func TestPutOutColumns_AlwaysTrueWhenQueryHasColumns(t *testing.T) { + query := &plugin.Query{ + Cmd: metadata.CmdMany, + Columns: []*plugin.Column{{}}, + } + if putOutColumns(query) != true { + t.Error("should be true when we have columns") + } +} diff --git a/internal/endtoend/testdata/select_empty_column_list/mysql/query.sql b/internal/endtoend/testdata/select_empty_column_list/mysql/query.sql new file mode 100644 index 0000000000..81b6ff14a1 --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/mysql/query.sql @@ -0,0 +1,4 @@ +CREATE TABLE bar (name text); + +-- name: GetBars :many +SELECT FROM bar; \ No newline at end of file diff --git a/internal/endtoend/testdata/select_empty_column_list/mysql/sqlc.json b/internal/endtoend/testdata/select_empty_column_list/mysql/sqlc.json new file mode 100644 index 0000000000..445bbd1589 --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/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/select_empty_column_list/mysql/stderr.txt b/internal/endtoend/testdata/select_empty_column_list/mysql/stderr.txt new file mode 100644 index 0000000000..11aeb304b0 --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/mysql/stderr.txt @@ -0,0 +1,2 @@ +# package querytest +query.sql:4:12: syntax error near "FROM bar;" " diff --git a/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/go/db.go b/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..9d5f1c84a5 --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.15.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/select_empty_column_list/postgresql/pgx/go/models.go b/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..b36db8769a --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/go/models.go @@ -0,0 +1,14 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.15.0 + +package querytest + +import ( + "database/sql" +) + +type Bar struct { + ID int32 + Name sql.NullString +} diff --git a/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..f88b7ebb53 --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/go/query.sql.go @@ -0,0 +1,37 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.15.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const getBars = `-- name: GetBars :many +SELECT FROM bar LIMIT 5 +` + +type GetBarsRow struct { +} + +func (q *Queries) GetBars(ctx context.Context) ([]GetBarsRow, error) { + rows, err := q.db.Query(ctx, getBars) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetBarsRow + for rows.Next() { + var i GetBarsRow + if err := rows.Scan(); 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/select_empty_column_list/postgresql/pgx/query.sql b/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/query.sql new file mode 100644 index 0000000000..6853741cba --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/query.sql @@ -0,0 +1,4 @@ +CREATE TABLE bar (id serial not null, name text); + +-- name: GetBars :many +SELECT FROM bar LIMIT 5; \ No newline at end of file diff --git a/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/sqlc.json b/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/sqlc.json new file mode 100644 index 0000000000..9403bd0279 --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/postgresql/pgx/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/select_empty_column_list/postgresql/stdlib/go/db.go b/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/go/db.go new file mode 100644 index 0000000000..5f69347d4b --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/go/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.15.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/select_empty_column_list/postgresql/stdlib/go/models.go b/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/go/models.go new file mode 100644 index 0000000000..b36db8769a --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/go/models.go @@ -0,0 +1,14 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.15.0 + +package querytest + +import ( + "database/sql" +) + +type Bar struct { + ID int32 + Name sql.NullString +} diff --git a/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/go/query.sql.go b/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/go/query.sql.go new file mode 100644 index 0000000000..0ad0b2952f --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/go/query.sql.go @@ -0,0 +1,40 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.15.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const getBars = `-- name: GetBars :many +SELECT FROM bar LIMIT 5 +` + +type GetBarsRow struct { +} + +func (q *Queries) GetBars(ctx context.Context) ([]GetBarsRow, error) { + rows, err := q.db.QueryContext(ctx, getBars) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetBarsRow + for rows.Next() { + var i GetBarsRow + if err := rows.Scan(); 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/select_empty_column_list/postgresql/stdlib/query.sql b/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/query.sql new file mode 100644 index 0000000000..6853741cba --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/query.sql @@ -0,0 +1,4 @@ +CREATE TABLE bar (id serial not null, name text); + +-- name: GetBars :many +SELECT FROM bar LIMIT 5; \ No newline at end of file diff --git a/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/sqlc.json b/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/sqlc.json new file mode 100644 index 0000000000..c72b6132d5 --- /dev/null +++ b/internal/endtoend/testdata/select_empty_column_list/postgresql/stdlib/sqlc.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "name": "querytest", + "schema": "query.sql", + "queries": "query.sql" + } + ] +}