Skip to content

feat(sql/catalog): Support ALTER TABLE IF EXISTS #2542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- name: Placeholder :exec
SELECT 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ALTER TABLE IF EXISTS foo ADD COLUMN bar integer;
ALTER TABLE IF EXISTS bar RENAME COLUMN bar TO baz;
ALTER TABLE IF EXISTS bat RENAME CONSTRAINT bar TO baz;
ALTER TABLE IF EXISTS baz RENAME TO bar;
ALTER TABLE IF EXISTS goo SET SCHEMA bar;
ALTER TABLE IF EXISTS gob ATTACH PARTITION partition_name DEFAULT;
ALTER TABLE IF EXISTS doo DETACH PARTITION partition_name;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "1",
"packages": [
{
"path": "go",
"engine": "postgresql",
"sql_package": "pgx/v4",
"name": "querytest",
"schema": "schema.sql",
"queries": "query.sql"
}
]
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- name: Placeholder :exec
SELECT 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ALTER TABLE IF EXISTS foo ADD COLUMN bar integer;
ALTER TABLE IF EXISTS bar RENAME COLUMN bar TO baz;
ALTER TABLE IF EXISTS bat RENAME CONSTRAINT bar TO baz;
ALTER TABLE IF EXISTS baz RENAME TO bar;
ALTER TABLE IF EXISTS goo SET SCHEMA bar;
ALTER TABLE IF EXISTS gob ATTACH PARTITION partition_name DEFAULT;
ALTER TABLE IF EXISTS doo DETACH PARTITION partition_name;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "1",
"packages": [
{
"path": "go",
"engine": "postgresql",
"sql_package": "pgx/v5",
"name": "querytest",
"schema": "schema.sql",
"queries": "query.sql"
}
]
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- name: Placeholder :exec
SELECT 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ALTER TABLE IF EXISTS foo ADD COLUMN bar integer;
ALTER TABLE IF EXISTS bar RENAME COLUMN bar TO baz;
ALTER TABLE IF EXISTS bat RENAME CONSTRAINT bar TO baz;
ALTER TABLE IF EXISTS baz RENAME TO bar;
ALTER TABLE IF EXISTS goo SET SCHEMA bar;
ALTER TABLE IF EXISTS gob ATTACH PARTITION partition_name DEFAULT;
ALTER TABLE IF EXISTS doo DETACH PARTITION partition_name;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "1",
"packages": [
{
"path": "go",
"engine": "postgresql",
"name": "querytest",
"schema": "schema.sql",
"queries": "query.sql"
}
]
}
18 changes: 11 additions & 7 deletions internal/engine/postgresql/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ func translate(node *nodes.Node) (ast.Node, error) {
return &ast.AlterTableSetSchemaStmt{
Table: rel.TableName(),
NewSchema: makeString(n.Newschema),
MissingOk: n.MissingOk,
}, nil

case nodes.ObjectType_OBJECT_TYPE:
Expand All @@ -259,8 +260,9 @@ func translate(node *nodes.Node) (ast.Node, error) {
n := inner.AlterTableStmt
rel := parseRelationFromRangeVar(n.Relation)
at := &ast.AlterTableStmt{
Table: rel.TableName(),
Cmds: &ast.List{},
Table: rel.TableName(),
Cmds: &ast.List{},
MissingOk: n.MissingOk,
}
for _, cmd := range n.Cmds {
switch cmdOneOf := cmd.Node.(type) {
Expand Down Expand Up @@ -600,16 +602,18 @@ func translate(node *nodes.Node) (ast.Node, error) {
case nodes.ObjectType_OBJECT_COLUMN:
rel := parseRelationFromRangeVar(n.Relation)
return &ast.RenameColumnStmt{
Table: rel.TableName(),
Col: &ast.ColumnRef{Name: n.Subname},
NewName: makeString(n.Newname),
Table: rel.TableName(),
Col: &ast.ColumnRef{Name: n.Subname},
NewName: makeString(n.Newname),
MissingOk: n.MissingOk,
}, nil

case nodes.ObjectType_OBJECT_TABLE:
rel := parseRelationFromRangeVar(n.Relation)
return &ast.RenameTableStmt{
Table: rel.TableName(),
NewName: makeString(n.Newname),
Table: rel.TableName(),
NewName: makeString(n.Newname),
MissingOk: n.MissingOk,
}, nil

case nodes.ObjectType_OBJECT_TYPE:
Expand Down
1 change: 1 addition & 0 deletions internal/sql/ast/alter_table_set_schema_stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ast
type AlterTableSetSchemaStmt struct {
Table *TableName
NewSchema *string
MissingOk bool
}

func (n *AlterTableSetSchemaStmt) Pos() int {
Expand Down
7 changes: 4 additions & 3 deletions internal/sql/ast/rename_column_stmt.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package ast

type RenameColumnStmt struct {
Table *TableName
Col *ColumnRef
NewName *string
Table *TableName
Col *ColumnRef
NewName *string
MissingOk bool
}

func (n *RenameColumnStmt) Pos() int {
Expand Down
5 changes: 3 additions & 2 deletions internal/sql/ast/rename_table_stmt.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package ast

type RenameTableStmt struct {
Table *TableName
NewName *string
Table *TableName
NewName *string
MissingOk bool
}

func (n *RenameTableStmt) Pos() int {
Expand Down
20 changes: 15 additions & 5 deletions internal/sql/catalog/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ type Table struct {
Comment string
}

func checkMissing(err error, missingOK bool) error {
var serr *sqlerr.Error
if errors.As(err, &serr) {
if serr.Err == sqlerr.NotFound && missingOK {
return nil
}
}
return err
}

func (table *Table) isExistColumn(cmd *ast.AlterTableCmd) (int, error) {
for i, c := range table.Columns {
if c.Name == *cmd.Name {
Expand Down Expand Up @@ -167,7 +177,7 @@ func (c *Catalog) alterTable(stmt *ast.AlterTableStmt) error {
}
_, table, err := c.getTable(stmt.Table)
if err != nil {
return err
return checkMissing(err, stmt.MissingOk)
}
for _, item := range stmt.Cmds.Items {
switch cmd := item.(type) {
Expand Down Expand Up @@ -206,11 +216,11 @@ func (c *Catalog) alterTableSetSchema(stmt *ast.AlterTableSetSchemaStmt) error {
}
oldSchema, err := c.getSchema(ns)
if err != nil {
return err
return checkMissing(err, stmt.MissingOk)
}
tbl, idx, err := oldSchema.getTable(stmt.Table)
if err != nil {
return err
return checkMissing(err, stmt.MissingOk)
}
tbl.Rel.Schema = *stmt.NewSchema
newSchema, err := c.getSchema(*stmt.NewSchema)
Expand Down Expand Up @@ -354,7 +364,7 @@ func (c *Catalog) dropTable(stmt *ast.DropTableStmt) error {
func (c *Catalog) renameColumn(stmt *ast.RenameColumnStmt) error {
_, tbl, err := c.getTable(stmt.Table)
if err != nil {
return err
return checkMissing(err, stmt.MissingOk)
}
idx := -1
for i := range tbl.Columns {
Expand All @@ -375,7 +385,7 @@ func (c *Catalog) renameColumn(stmt *ast.RenameColumnStmt) error {
func (c *Catalog) renameTable(stmt *ast.RenameTableStmt) error {
sch, tbl, err := c.getTable(stmt.Table)
if err != nil {
return err
return checkMissing(err, stmt.MissingOk)
}
if _, _, err := sch.getTable(&ast.TableName{Name: *stmt.NewName}); err == nil {
return sqlerr.RelationExists(*stmt.NewName)
Expand Down