Skip to content
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

release-20.2: sql: ban renaming table to a new database unless both schemas are public #55723

Merged
merged 1 commit into from
Oct 20, 2020
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
56 changes: 56 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/rename_table
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,59 @@ query TTTI
SHOW TABLES
----
public kv table 0

# Test that tables can't be renamed to a different database unless both the
# old and new schemas are in the public schema.
subtest rename_table_across_dbs

statement ok
CREATE DATABASE olddb

statement ok
CREATE DATABASE newdb

statement ok
USE olddb

statement ok
CREATE SCHEMA oldsc

statement ok
USE newdb

statement ok
CREATE SCHEMA newsc

statement ok
CREATE TABLE olddb.public.tbl1();

statement ok
CREATE TABLE olddb.oldsc.tbl2();

statement error pgcode 42602 cannot change database of table
ALTER TABLE olddb.public.tbl1 RENAME TO newdb.newsc.tbl1

statement error pgcode 42602 cannot change database of table
ALTER TABLE olddb.oldsc.tbl2 RENAME TO newdb.public.tbl2

statement error pgcode 42602 cannot change database of table
ALTER TABLE olddb.oldsc.tbl2 RENAME TO newdb.newsc.tbl2

# Try different but equivalent names.

statement error pgcode 42602 cannot change database of table
ALTER TABLE olddb.tbl1 RENAME TO newdb.newsc.tbl1

statement error pgcode 42602 cannot change database of table
ALTER TABLE olddb.oldsc.tbl2 RENAME TO newdb.tbl2

# Using the public schemas should still work.

statement ok
ALTER TABLE olddb.public.tbl1 RENAME TO newdb.public.tbl1

statement ok
DROP DATABASE olddb CASCADE

statement ok
DROP DATABASE newdb CASCADE
13 changes: 13 additions & 0 deletions pkg/sql/rename_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,15 @@ func (n *renameTableNode) startExec(params runParams) error {
)
}

// Disable renaming objects between databases unless both the source and
// target schemas are the public schema. This preserves backward compatibility
// for the behavior prior to user-defined schemas.
if oldTn.Catalog() != newTn.Catalog() &&
(oldTn.Schema() != string(tree.PublicSchemaName) || newTn.Schema() != string(tree.PublicSchemaName)) {
return pgerror.Newf(pgcode.InvalidName,
"cannot change database of table unless both the old and new schemas are the public schema in each database")
}

// oldTn and newTn are already normalized, so we can compare directly here.
if oldTn.Catalog() == newTn.Catalog() &&
oldTn.Schema() == newTn.Schema() &&
Expand All @@ -167,6 +176,10 @@ func (n *renameTableNode) startExec(params runParams) error {
return err
}

// The parent schema ID is never modified here because changing the schema of
// a table within the same database is disallowed, and changing the database
// of a table is only allowed if both the source and target schemas are the
// public schema.
tableDesc.SetName(newTn.Table())
tableDesc.ParentID = targetDbDesc.GetID()

Expand Down