From b80feacf584d0b61638526d372649de63c2ef70c Mon Sep 17 00:00:00 2001 From: "craig[bot]" Date: Mon, 20 Mar 2023 16:02:10 +0000 Subject: [PATCH] sql: check replace view columns earlier Before this change, we could encounter internal errors while attempting to add result columns during a `CREATE OR REPLACE VIEW` if the number of columns in the new view was less than the number of columns in the old view. This led to an inconsistency with postgres, which would only return the error `cannot drop columns from view`. This PR moves the check comparing the number of columns before and after the view replacement earlier so that the correct error returns. Co-authored-by: sirek@cockroachlabs.com Fixes: #99000 Epic: None Release note (bug fix): Fixes an internal error that can occur when `CREATE OR REPLACE VIEW` replaces a view with fewer columns and another entity depended on the view. --- pkg/sql/create_view.go | 5 +++++ pkg/sql/logictest/testdata/logic_test/views | 22 +++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/pkg/sql/create_view.go b/pkg/sql/create_view.go index 5d05bb17af59..2812b820e6e4 100644 --- a/pkg/sql/create_view.go +++ b/pkg/sql/create_view.go @@ -596,6 +596,11 @@ func (p *planner) replaceViewDesc( toReplace.ViewQuery = updatedQuery } + // Check that the new view has at least as many columns as the old view before + // adding result columns. + if len(n.columns) < len(toReplace.ClusterVersion().Columns) { + return nil, pgerror.Newf(pgcode.InvalidTableDefinition, "cannot drop columns from view") + } // Reset the columns to add the new result columns onto. toReplace.Columns = make([]descpb.ColumnDescriptor, 0, len(n.columns)) toReplace.NextColumnID = 0 diff --git a/pkg/sql/logictest/testdata/logic_test/views b/pkg/sql/logictest/testdata/logic_test/views index e70879165ce8..0aec342b2e4b 100644 --- a/pkg/sql/logictest/testdata/logic_test/views +++ b/pkg/sql/logictest/testdata/logic_test/views @@ -1813,3 +1813,25 @@ SELECT * FROM v; statement ok SET DATABASE = test; + +# When replacing a view with fewer columns, an error about dropping columns from +# views preempts any errors about dependencies. +subtest regression_99000 + +statement ok +CREATE TABLE films (id int PRIMARY KEY, title text, kind text, classification CHAR(1)); + +statement ok +CREATE VIEW comedies AS + SELECT * + FROM films + WHERE kind = 'Comedy'; + +statement ok +CREATE VIEW pg_comedies AS + SELECT * + FROM comedies + WHERE classification = 'PG'; + +statement error pq: cannot drop columns from view +CREATE OR REPLACE VIEW comedies AS SELECT ARRAY[films.*]::string FROM films;