Skip to content

Commit fc74b99

Browse files
sql: handle companion array name conflicts in ALTER TYPE (#169343)
sql: handle companion array name conflicts in `ALTER TYPE `
2 parents e440b11 + 9231858 commit fc74b99

2 files changed

Lines changed: 87 additions & 6 deletions

File tree

pkg/sql/alter_type.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,8 @@ func (p *planner) setTypeSchema(ctx context.Context, n *alterTypeNode, schema st
356356
return err
357357
}
358358

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

370-
err = p.performRenameTypeDesc(
371-
ctx, typeDesc, typeDesc.Name, desiredSchemaID, tree.AsStringWithFQNames(n.n, p.Ann()),
372-
)
373-
372+
arrayDesc, err := p.Descriptors().MutableByID(p.txn).Type(ctx, n.desc.ArrayTypeID)
374373
if err != nil {
375374
return err
376375
}
377376

378-
arrayDesc, err := p.Descriptors().MutableByID(p.txn).Type(ctx, n.desc.ArrayTypeID)
379-
if err != nil {
377+
// The CheckObjectNameCollision checks that the companion array can be moved
378+
// without colliding with
379+
//
380+
// This is consistent with the PG behavior which itself is inconsistent:
381+
// `SET SCHEMA` errors on collision while `ALTER TYPE ... RENAME` auto-resolves
382+
// conflicts on companion array names.
383+
if err := descs.CheckObjectNameCollision(
384+
ctx,
385+
p.Descriptors(),
386+
p.txn,
387+
typeDesc.GetParentID(),
388+
desiredSchemaID,
389+
tree.NewUnqualifiedTypeName(arrayDesc.GetName()),
390+
); err != nil {
391+
return err
392+
}
393+
394+
if err := p.performRenameTypeDesc(
395+
ctx, typeDesc, typeDesc.Name, desiredSchemaID, tree.AsStringWithFQNames(n.n, p.Ann()),
396+
); err != nil {
380397
return err
381398
}
382399

pkg/sql/logictest/testdata/logic_test/set_schema

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,3 +590,67 @@ true
590590
user testuser
591591

592592
subtest end
593+
594+
subtest array_type_name_conflict
595+
596+
statement ok
597+
CREATE SCHEMA IF NOT EXISTS ocean
598+
599+
statement ok
600+
CREATE SCHEMA IF NOT EXISTS stream
601+
602+
statement ok
603+
CREATE TYPE ocean.salmon AS ENUM ('sockeye', 'king', 'atlantic');
604+
605+
statement ok
606+
CREATE TYPE stream."_salmon" AS ENUM ('steelhead', 'cherry');
607+
608+
# The companion array type "_salmon" collides.
609+
statement error pq: type "test.stream._salmon" already exists
610+
ALTER TYPE ocean.salmon SET SCHEMA stream
611+
612+
# Verify the source type and array are still usable in the original schema.
613+
statement ok
614+
SELECT 'sockeye'::ocean.salmon
615+
616+
statement ok
617+
SELECT ARRAY['sockeye']::ocean._salmon
618+
619+
# The target schema should not contain the primary type.
620+
query error pq: type "stream.salmon" does not exist
621+
SELECT NULL::stream.salmon
622+
623+
user testuser
624+
625+
subtest end
626+
627+
# Regression test: The companion array type collides with a table in the destination schema.
628+
subtest array_type_table_collision
629+
630+
user root
631+
632+
statement ok
633+
CREATE SCHEMA IF NOT EXISTS lake
634+
635+
statement ok
636+
CREATE SCHEMA IF NOT EXISTS pond
637+
638+
statement ok
639+
CREATE TYPE lake.trout AS ENUM ('brown', 'rainbow');
640+
641+
statement ok
642+
CREATE TABLE pond."_trout" (id INT PRIMARY KEY)
643+
644+
statement error pq: relation "test.pond._trout" already exists
645+
ALTER TYPE lake.trout SET SCHEMA pond
646+
647+
statement ok
648+
SELECT 'brown'::lake.trout
649+
650+
# The target schema should not contain the primary type.
651+
query error pq: type "pond.trout" does not exist
652+
SELECT NULL::pond.trout
653+
654+
user testuser
655+
656+
subtest end

0 commit comments

Comments
 (0)