Skip to content
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
29 changes: 23 additions & 6 deletions pkg/sql/alter_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ func (p *planner) setTypeSchema(ctx context.Context, n *alterTypeNode, schema st
return err
}

// The prepareSetSchema checks the primary type's name. The name of the
// companion array is collision checked below.
desiredSchemaID, err := p.prepareSetSchema(ctx, n.prefix.Database, typeDesc, schema)
if err != nil {
return err
Expand All @@ -367,16 +369,31 @@ func (p *planner) setTypeSchema(ctx context.Context, n *alterTypeNode, schema st
return nil
}

err = p.performRenameTypeDesc(
ctx, typeDesc, typeDesc.Name, desiredSchemaID, tree.AsStringWithFQNames(n.n, p.Ann()),
)

arrayDesc, err := p.Descriptors().MutableByID(p.txn).Type(ctx, n.desc.ArrayTypeID)
if err != nil {
return err
}

arrayDesc, err := p.Descriptors().MutableByID(p.txn).Type(ctx, n.desc.ArrayTypeID)
if err != nil {
// The CheckObjectNameCollision checks that the companion array can be moved
// without colliding with
//
// This is consistent with the PG behavior which itself is inconsistent:
// `SET SCHEMA` errors on collision while `ALTER TYPE ... RENAME` auto-resolves
// conflicts on companion array names.
if err := descs.CheckObjectNameCollision(
ctx,
p.Descriptors(),
p.txn,
typeDesc.GetParentID(),
desiredSchemaID,
tree.NewUnqualifiedTypeName(arrayDesc.GetName()),
); err != nil {
return err
}

if err := p.performRenameTypeDesc(
ctx, typeDesc, typeDesc.Name, desiredSchemaID, tree.AsStringWithFQNames(n.n, p.Ann()),
); err != nil {
return err
}

Expand Down
64 changes: 64 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/set_schema
Original file line number Diff line number Diff line change
Expand Up @@ -590,3 +590,67 @@ true
user testuser

subtest end

subtest array_type_name_conflict

statement ok
CREATE SCHEMA IF NOT EXISTS ocean

statement ok
CREATE SCHEMA IF NOT EXISTS stream

statement ok
CREATE TYPE ocean.salmon AS ENUM ('sockeye', 'king', 'atlantic');

statement ok
CREATE TYPE stream."_salmon" AS ENUM ('steelhead', 'cherry');

# The companion array type "_salmon" collides.
statement error pq: type "test.stream._salmon" already exists
ALTER TYPE ocean.salmon SET SCHEMA stream

# Verify the source type and array are still usable in the original schema.
statement ok
SELECT 'sockeye'::ocean.salmon

statement ok
SELECT ARRAY['sockeye']::ocean._salmon

# The target schema should not contain the primary type.
query error pq: type "stream.salmon" does not exist
SELECT NULL::stream.salmon

user testuser

subtest end

# Regression test: The companion array type collides with a table in the destination schema.
subtest array_type_table_collision

user root

statement ok
CREATE SCHEMA IF NOT EXISTS lake

statement ok
CREATE SCHEMA IF NOT EXISTS pond

statement ok
CREATE TYPE lake.trout AS ENUM ('brown', 'rainbow');

statement ok
CREATE TABLE pond."_trout" (id INT PRIMARY KEY)

statement error pq: relation "test.pond._trout" already exists
ALTER TYPE lake.trout SET SCHEMA pond

statement ok
SELECT 'brown'::lake.trout

# The target schema should not contain the primary type.
query error pq: type "pond.trout" does not exist
SELECT NULL::pond.trout

user testuser

subtest end
Loading