Skip to content
Open
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
99 changes: 99 additions & 0 deletions internal/migration_acceptance_tests/view_cases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,105 @@ var viewAcceptanceTestCases = []acceptanceTestCase{
`,
},
},
{
name: "Recreate view due to dependent column type change",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
id INT PRIMARY KEY,
foo VARCHAR(255),
price NUMERIC(10,2)
);

CREATE VIEW foobar_view AS
SELECT id, foo, price
FROM foobar;
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
id INT PRIMARY KEY,
foo VARCHAR(255),
price INTEGER
);

CREATE VIEW foobar_view AS
SELECT id, foo, price
FROM foobar;
`,
},
expectedHazardTypes: []diff.MigrationHazardType{
diff.MigrationHazardTypeAcquiresAccessExclusiveLock,
diff.MigrationHazardTypeImpactsDatabasePerformance,
},
},
{
name: "Recreate view due to multiple dependent column type changes",
oldSchemaDDL: []string{
`
CREATE TABLE plans(
id INT PRIMARY KEY,
annual_fee NUMERIC(10,2),
monthly_fee NUMERIC(10,2)
);

CREATE VIEW plans_view AS
SELECT id, annual_fee, monthly_fee
FROM plans;
`,
},
newSchemaDDL: []string{
`
CREATE TABLE plans(
id INT PRIMARY KEY,
annual_fee INTEGER,
monthly_fee INTEGER
);

CREATE VIEW plans_view AS
SELECT id, annual_fee, monthly_fee
FROM plans;
`,
},
expectedHazardTypes: []diff.MigrationHazardType{
diff.MigrationHazardTypeAcquiresAccessExclusiveLock,
diff.MigrationHazardTypeImpactsDatabasePerformance,
},
},
{
name: "No view recreate when non-dependent column type changes",
oldSchemaDDL: []string{
`
CREATE TABLE foobar(
id INT PRIMARY KEY,
foo VARCHAR(255),
bar NUMERIC(10,2)
);

CREATE VIEW foobar_view AS
SELECT id, foo
FROM foobar;
`,
},
newSchemaDDL: []string{
`
CREATE TABLE foobar(
id INT PRIMARY KEY,
foo VARCHAR(255),
bar INTEGER
);

CREATE VIEW foobar_view AS
SELECT id, foo
FROM foobar;
`,
},
expectedHazardTypes: []diff.MigrationHazardType{
diff.MigrationHazardTypeAcquiresAccessExclusiveLock,
diff.MigrationHazardTypeImpactsDatabasePerformance,
},
},
}

func TestViewTestCases(t *testing.T) {
Expand Down
11 changes: 11 additions & 0 deletions pkg/diff/view_sql_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ func buildViewDiff(
return viewDiff{}, true, nil
}
}
// Also recreate if a dependent column's type is being changed.
// ALTER TABLE ... ALTER COLUMN ... SET DATA TYPE fails when a view depends
// on that column; the view must be dropped first and recreated after.
alteredColumnDiffsByName := buildDiffByNameMap[schema.Column, columnDiff](td.columnsDiff.alters)
for _, c := range t.Columns {
if colDiff, ok := alteredColumnDiffsByName[c]; ok {
if !strings.EqualFold(colDiff.old.Type, colDiff.new.Type) {
return viewDiff{}, true, nil
}
}
}
}

// Recreate if the view SQL generator cannot alter the view.
Expand Down