diff --git a/internal/endtoend/testdata/ddl_create_table_like/issue.md b/internal/endtoend/testdata/ddl_create_table_like/issue.md new file mode 100644 index 0000000000..371a25581d --- /dev/null +++ b/internal/endtoend/testdata/ddl_create_table_like/issue.md @@ -0,0 +1 @@ +https://github.com/sqlc-dev/sqlc/issues/481 diff --git a/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/go/db.go b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/go/db.go new file mode 100644 index 0000000000..2568532b61 --- /dev/null +++ b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.23.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/ddl_create_table_like/postgresql/pgx/go/models.go b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/go/models.go new file mode 100644 index 0000000000..e39313798e --- /dev/null +++ b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/go/models.go @@ -0,0 +1,17 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.23.0 + +package querytest + +import () + +type Change struct { + Ranked int32 +} + +type ChangesRanked struct { + Ranked int32 + RankByEffectSize int32 + RankByAbsPercentChange int32 +} diff --git a/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/go/query.sql.go b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/go/query.sql.go new file mode 100644 index 0000000000..4e5f0215dd --- /dev/null +++ b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/go/query.sql.go @@ -0,0 +1,34 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.23.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const allRanked = `-- name: AllRanked :many +SELECT ranked, rank_by_effect_size, rank_by_abs_percent_change FROM changes_ranked +` + +func (q *Queries) AllRanked(ctx context.Context) ([]ChangesRanked, error) { + rows, err := q.db.Query(ctx, allRanked) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ChangesRanked + for rows.Next() { + var i ChangesRanked + if err := rows.Scan(&i.Ranked, &i.RankByEffectSize, &i.RankByAbsPercentChange); 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/ddl_create_table_like/postgresql/pgx/query.sql b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/query.sql new file mode 100644 index 0000000000..759ef862de --- /dev/null +++ b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/query.sql @@ -0,0 +1,2 @@ +-- name: AllRanked :many +SELECT * FROM changes_ranked; diff --git a/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/schema.sql b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/schema.sql new file mode 100644 index 0000000000..7365737bab --- /dev/null +++ b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/schema.sql @@ -0,0 +1,9 @@ +CREATE TABLE changes ( + ranked INT NOT NULL +); + +CREATE TABLE changes_ranked ( + LIKE changes INCLUDING ALL, + rank_by_effect_size INT NOT NULL, + rank_by_abs_percent_change INT NOT NULL +); diff --git a/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/sqlc.yaml b/internal/endtoend/testdata/ddl_create_table_like/postgresql/pgx/sqlc.yaml new file mode 100644 index 0000000000..5dc63e3f91 --- /dev/null +++ b/internal/endtoend/testdata/ddl_create_table_like/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/sql/catalog/table.go b/internal/sql/catalog/table.go index bfa2da027e..dc30acfa1e 100644 --- a/internal/sql/catalog/table.go +++ b/internal/sql/catalog/table.go @@ -289,10 +289,6 @@ func (c *Catalog) createTable(stmt *ast.CreateTableStmt) error { } } - if stmt.ReferTable != nil && len(stmt.Cols) != 0 { - return errors.New("create table node cannot have both a ReferTable and Cols") - } - if stmt.ReferTable != nil { _, original, err := c.getTable(stmt.ReferTable) if err != nil { @@ -302,23 +298,23 @@ func (c *Catalog) createTable(stmt *ast.CreateTableStmt) error { newCol := *col // make a copy, so changes to the ReferTable don't propagate tbl.Columns = append(tbl.Columns, &newCol) } - } else { - for _, col := range stmt.Cols { - if notNull, ok := seen[col.Colname]; ok { - seen[col.Colname] = notNull || col.IsNotNull - if a, ok := coltype[col.Colname]; ok { - if !sameType(&a, col.TypeName) { - return fmt.Errorf("column %q has a type conflict", col.Colname) - } + } + + for _, col := range stmt.Cols { + if notNull, ok := seen[col.Colname]; ok { + seen[col.Colname] = notNull || col.IsNotNull + if a, ok := coltype[col.Colname]; ok { + if !sameType(&a, col.TypeName) { + return fmt.Errorf("column %q has a type conflict", col.Colname) } - continue } - tc, err := c.defineColumn(stmt.Name, col) - if err != nil { - return err - } - tbl.Columns = append(tbl.Columns, tc) + continue + } + tc, err := c.defineColumn(stmt.Name, col) + if err != nil { + return err } + tbl.Columns = append(tbl.Columns, tc) } // If one of the merged columns was not null, mark the column as not null