Skip to content

Commit 547a6fd

Browse files
craig[bot]fqazi
andcommitted
Merge #153986
153986: sql/schemachanger: detect secondary and pk index name collisions r=fqazi a=fqazi Previously, the declarative schema changer did not properly check if secondary index names and primary index names collided. This meant that instead of getting a query at statement time, one could be hit at runtime instead. To address this, this patch checks if either secondary or primary indexes with the same name exist when creating a new secondary index. Fixes: #153702 Release note (bug fix): Addressed a runtime error that could be hit if a new secondary index had a name collision with a primary index. Co-authored-by: Faizan Qazi <[email protected]>
2 parents 26353d3 + fa81033 commit 547a6fd

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

pkg/sql/logictest/testdata/logic_test/create_index

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,3 +694,14 @@ tbl_with_collate CREATE TABLE public.tbl_with_collate (
694694
) WITH (schema_locked = true);
695695

696696
subtest end
697+
698+
699+
subtest index_name_conflicts_with_primary_key
700+
701+
statement ok
702+
CREATE TABLE t_index_name_conflicts_with_primary_key (a INT PRIMARY KEY, b INT);
703+
704+
statement error pgcode 42P07 index with name \"t_index_name_conflicts_with_primary_key_pkey\" already exists
705+
CREATE INDEX t_index_name_conflicts_with_primary_key_pkey ON t_index_name_conflicts_with_primary_key (a);
706+
707+
subtest end

pkg/sql/schemachanger/scbuild/internal/scbuildstmt/create_index.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,34 @@ func CreateIndex(b BuildCtx, n *tree.CreateIndex) {
119119
"%q is not a table or materialized view", n.Table.ObjectName))
120120
}
121121
// Resolve the index name and make sure it doesn't exist yet.
122-
{
122+
if len(n.Name) > 0 {
123123
indexElements := b.ResolveIndex(idxSpec.secondary.TableID, n.Name, ResolveParams{
124124
IsExistenceOptional: true,
125125
RequiredPrivilege: privilege.CREATE,
126126
})
127-
if _, target, sec := scpb.FindSecondaryIndex(indexElements); sec != nil {
127+
skipCreation := false
128+
indexElements.ForEach(func(_ scpb.Status, target scpb.TargetStatus, e scpb.Element) {
129+
switch e.(type) {
130+
// Names can conflict on either primary or secondary indexes.
131+
case *scpb.PrimaryIndex:
132+
case *scpb.SecondaryIndex:
133+
default:
134+
// No index element that we care about.
135+
return
136+
}
128137
if n.IfNotExists {
138+
skipCreation = true
129139
return
130140
}
131141
if target == scpb.ToAbsent {
132142
panic(pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
133143
"index %q being dropped, try again later", n.Name.String()))
134144
}
135145
panic(pgerror.Newf(pgcode.DuplicateRelation, "index with name %q already exists", n.Name))
146+
})
147+
if skipCreation {
148+
return
149+
136150
}
137151
}
138152
if _, _, tbl := scpb.FindTable(relationElements); tbl != nil {

0 commit comments

Comments
 (0)