Skip to content

Commit

Permalink
cmd/atlas/internal/sqlparse/pgparse: column rename detection should i…
Browse files Browse the repository at this point in the history
…gnore side effects on views (#3215)
  • Loading branch information
a8m authored Nov 6, 2024
1 parent cf161f2 commit 3868e28
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
31 changes: 23 additions & 8 deletions cmd/atlas/internal/sqlparse/pgparse/pgparse.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (p *Parser) FixChange(_ migrate.Driver, s string, changes schema.Changes) (
switch stmt := stmt.GetStmt(); {
case stmt.GetRenameStmt() != nil &&
stmt.GetRenameStmt().GetRenameType() == pgquery.ObjectType_OBJECT_COLUMN:
modify, err := expectModify(changes)
modify, err := expectHaveModify(changes)
if err != nil {
return nil, err
}
Expand All @@ -104,7 +104,7 @@ func (p *Parser) FixChange(_ migrate.Driver, s string, changes schema.Changes) (
})
case stmt.GetRenameStmt() != nil &&
stmt.GetRenameStmt().GetRenameType() == pgquery.ObjectType_OBJECT_INDEX:
modify, err := expectModify(changes)
modify, err := expectOneModify(changes)
if err != nil {
return nil, err
}
Expand All @@ -122,7 +122,7 @@ func (p *Parser) FixChange(_ migrate.Driver, s string, changes schema.Changes) (
})
case stmt.GetIndexStmt() != nil &&
stmt.GetIndexStmt().GetConcurrent():
modify, err := expectModify(changes)
modify, err := expectOneModify(changes)
if err != nil {
return nil, err
}
Expand All @@ -139,7 +139,7 @@ func (p *Parser) FixChange(_ migrate.Driver, s string, changes schema.Changes) (
add.Extra = append(add.Extra, &postgres.Concurrently{})
}
case stmt.GetDropStmt() != nil && stmt.GetDropStmt().GetConcurrent():
modify, err := expectModify(changes)
modify, err := expectOneModify(changes)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -179,17 +179,32 @@ func (p *Parser) FixChange(_ migrate.Driver, s string, changes schema.Changes) (
return changes, nil
}

func expectModify(changes schema.Changes) (*schema.ModifyTable, error) {
if len(changes) != 1 {
return nil, fmt.Errorf("unexpected number fo changes: %d", len(changes))
}
func expectOneModify(changes schema.Changes) (*schema.ModifyTable, error) {
modify, ok := changes[0].(*schema.ModifyTable)
if !ok {
return nil, fmt.Errorf("expected modify-table change for alter-table statement, but got: %T", changes[0])
}
return modify, nil
}

func expectHaveModify(changes schema.Changes) (*schema.ModifyTable, error) {
var modify []*schema.ModifyTable
for _, c := range changes {
switch c := c.(type) {
case *schema.ModifyTable:
modify = append(modify, c)
// The column might be used in the view.
case *schema.ModifyView:
default:
return nil, fmt.Errorf("unexpected change for alter-table statement: %#v", c)
}
}
if len(modify) != 1 {
return nil, fmt.Errorf("expected one modify-table change for alter-table statement, but got: %d", len(modify))
}
return modify[0], nil
}

// tableUpdated checks if the table was updated in the statement.
func matchTable(n *pgquery.RangeVar, t *schema.Table) bool {
return n.GetRelname() == t.Name && (n.GetSchemaname() == "" || n.GetSchemaname() == t.Schema.Name)
Expand Down
33 changes: 33 additions & 0 deletions cmd/atlas/internal/sqlparse/pgparse/pgparse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,39 @@ func TestFixChange_RenameColumns(t *testing.T) {
},
changes,
)

changes, err = p.FixChange(
nil,
"ALTER TABLE t RENAME COLUMN c1 TO c2",
schema.Changes{
&schema.ModifyTable{
Changes: schema.Changes{
&schema.DropColumn{C: schema.NewColumn("c1")},
&schema.AddColumn{C: schema.NewColumn("c2")},
},
},
&schema.ModifyView{
From: &schema.View{Name: "t", Def: "select c1 from t"},
To: &schema.View{Name: "t", Def: "select c2 from t"},
},
},
)
require.NoError(t, err)
require.Equal(
t,
schema.Changes{
&schema.ModifyTable{
Changes: schema.Changes{
&schema.RenameColumn{From: schema.NewColumn("c1"), To: schema.NewColumn("c2")},
},
},
&schema.ModifyView{
From: &schema.View{Name: "t", Def: "select c1 from t"},
To: &schema.View{Name: "t", Def: "select c2 from t"},
},
},
changes,
)
}

func TestFixChange_RenameIndexes(t *testing.T) {
Expand Down

0 comments on commit 3868e28

Please sign in to comment.