Skip to content

Commit 3a9b119

Browse files
committed
schemachanger: check dependents when dropping hash-sharded index
Release note (bug fix): Fixed a bug where DROP INDEX on a hash-sharded index did not properly detect dependencies from functions and procedures on the shard column. This bug would cause the DROP INDEX statement to fail with an internal validation error. Now, the statement returns a correct error message, and using DROP INDEX ... CASCADE works as expected by dropping the dependent function/procedure.
1 parent ea40e7e commit 3a9b119

File tree

4 files changed

+86
-10
lines changed

4 files changed

+86
-10
lines changed

pkg/sql/drop_index.go

+12-6
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ func (n *dropIndexNode) startExec(params runParams) error {
174174
// Only drop this shard column if it's not a physical column (as is the case for all hash-sharded index in 22.1
175175
// and after), or, CASCADE is set.
176176
if shardColDesc.IsVirtual() || n.n.DropBehavior == tree.DropCascade {
177-
ok, err := n.maybeQueueDropShardColumn(tableDesc, shardColDesc)
177+
ok, err := n.maybeQueueDropShardColumn(params, index.tn, tableDesc, shardColDesc)
178178
if err != nil {
179179
return err
180180
}
@@ -222,7 +222,7 @@ func (n *dropIndexNode) queueDropColumn(tableDesc *tabledesc.Mutable, col catalo
222222
//
223223
// Assumes that the given index is sharded.
224224
func (n *dropIndexNode) maybeQueueDropShardColumn(
225-
tableDesc *tabledesc.Mutable, shardColDesc catalog.Column,
225+
params runParams, tn *tree.TableName, tableDesc *tabledesc.Mutable, shardColDesc catalog.Column,
226226
) (bool, error) {
227227
if catalog.FindNonDropIndex(tableDesc, func(otherIdx catalog.Index) bool {
228228
colIDs := otherIdx.CollectKeyColumnIDs()
@@ -234,7 +234,7 @@ func (n *dropIndexNode) maybeQueueDropShardColumn(
234234
}) != nil {
235235
return false, nil
236236
}
237-
if err := n.dropShardColumnAndConstraint(tableDesc, shardColDesc); err != nil {
237+
if err := n.dropShardColumnAndConstraint(params, tn, tableDesc, shardColDesc); err != nil {
238238
return false, err
239239
}
240240
return true, nil
@@ -243,7 +243,7 @@ func (n *dropIndexNode) maybeQueueDropShardColumn(
243243
// dropShardColumnAndConstraint drops the given shard column and its associated check
244244
// constraint.
245245
func (n *dropIndexNode) dropShardColumnAndConstraint(
246-
tableDesc *tabledesc.Mutable, shardCol catalog.Column,
246+
params runParams, tn *tree.TableName, tableDesc *tabledesc.Mutable, shardCol catalog.Column,
247247
) error {
248248
validChecks := tableDesc.Checks[:0]
249249
for _, check := range tableDesc.CheckConstraints() {
@@ -260,8 +260,14 @@ func (n *dropIndexNode) dropShardColumnAndConstraint(
260260
if len(validChecks) != len(tableDesc.Checks) {
261261
tableDesc.Checks = validChecks
262262
}
263-
264-
n.queueDropColumn(tableDesc, shardCol)
263+
if _, err := dropColumnImpl(
264+
params, tn, tableDesc, tableDesc.GetRowLevelTTL(),
265+
&tree.AlterTableDropColumn{
266+
Column: shardCol.ColName(),
267+
DropBehavior: n.n.DropBehavior},
268+
); err != nil {
269+
return err
270+
}
265271
return nil
266272
}
267273

pkg/sql/logictest/testdata/logic_test/drop_index

+56
Original file line numberDiff line numberDiff line change
@@ -505,3 +505,59 @@ SELECT constraint_name from [SHOW CONSTRAINTS FROM fk_ref_dst];
505505
fk_ref_dst_pkey
506506
j_fk
507507
m_fk
508+
509+
subtest drop_hash_sharded_index_depended_on_by_procedure
510+
511+
statement ok
512+
CREATE TABLE tab_145100 (
513+
id UUID PRIMARY KEY,
514+
i INT NOT NULL,
515+
j int not null,
516+
INDEX (i ASC) USING HASH,
517+
FAMILY (id, i, j)
518+
)
519+
520+
statement ok
521+
CREATE PROCEDURE proc_insert_145100(in_id UUID, in_i INT) LANGUAGE SQL AS $$
522+
INSERT INTO tab_145100 (id, i) VALUES (in_id, in_i);
523+
$$;
524+
525+
# Note: Due to https://github.com/cockroachdb/cockroach/issues/145098, the
526+
# procedure has a dependency on the shard column. When that issue is resolved,
527+
# this DROP statement should succeed.
528+
statement error cannot drop column "crdb_internal_i_shard_16" because function "proc_insert_145100" depends on it
529+
DROP INDEX tab_145100@tab_145100_i_idx
530+
531+
statement ok
532+
DROP PROCEDURE proc_insert_145100
533+
534+
statement ok
535+
CREATE PROCEDURE proc_select_145100() LANGUAGE SQL AS $$
536+
SELECT *, crdb_internal_i_shard_16 FROM tab_145100;
537+
$$;
538+
539+
statement error cannot drop column "crdb_internal_i_shard_16" because function "proc_select_145100" depends on it
540+
DROP INDEX tab_145100@tab_145100_i_idx
541+
542+
statement ok
543+
DROP INDEX tab_145100@tab_145100_i_idx CASCADE
544+
545+
query T
546+
SELECT create_statement FROM [SHOW CREATE TABLE tab_145100]
547+
----
548+
CREATE TABLE public.tab_145100 (
549+
id UUID NOT NULL,
550+
i INT8 NOT NULL,
551+
j INT8 NOT NULL,
552+
CONSTRAINT tab_145100_pkey PRIMARY KEY (id ASC),
553+
FAMILY fam_0_id_i_j (id, i, j)
554+
)
555+
556+
# DROP INDEX ... CASCADE should have caused the procedure to be dropped.
557+
statement error procedure proc_select_145100 does not exist
558+
CALL proc_select_145100()
559+
560+
statement ok
561+
DROP TABLE tab_145100
562+
563+
subtest end

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ func dropColumn(
172172
if indexTargetStatus == scpb.ToAbsent {
173173
return
174174
}
175+
// If we entered this function because of a DROP INDEX statement (e.g. for
176+
// a hash-sharded index), avoid recursive calls to drop the index again.
177+
if _, isDropIndex := stmt.(*tree.DropIndex); isDropIndex {
178+
return
179+
}
175180
name := tree.TableIndexName{
176181
Table: *tn,
177182
Index: tree.UnrestrictedName(indexName.Name),
@@ -181,7 +186,7 @@ func dropColumn(
181186
indexName.Name,
182187
cn.Name,
183188
))
184-
dropSecondaryIndex(b, &name, behavior, e)
189+
dropSecondaryIndex(b, &name, behavior, e, stmt)
185190
case *scpb.View:
186191
if behavior != tree.DropCascade {
187192
_, _, ns := scpb.FindNamespace(b.QueryByID(col.TableID))

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

+12-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func maybeDropIndex(
105105
"use CASCADE if you really want to drop it.",
106106
))
107107
}
108-
dropSecondaryIndex(b, indexName, n.DropBehavior, sie)
108+
dropSecondaryIndex(b, indexName, n.DropBehavior, sie, n)
109109
return sie
110110
}
111111

@@ -116,6 +116,7 @@ func dropSecondaryIndex(
116116
indexName *tree.TableIndexName,
117117
dropBehavior tree.DropBehavior,
118118
sie *scpb.SecondaryIndex,
119+
stmt tree.Statement,
119120
) {
120121
{
121122
next := b.WithNewSourceElementID()
@@ -142,7 +143,9 @@ func dropSecondaryIndex(
142143

143144
// If shard index, also drop the shard column and all check constraints that
144145
// uses this shard column if no other index uses the shard column.
145-
maybeDropAdditionallyForShardedIndex(next, sie, indexName.Index.String(), dropBehavior)
146+
maybeDropAdditionallyForShardedIndex(
147+
next, sie, indexName.Index.String(), stmt, dropBehavior,
148+
)
146149

147150
// If expression index, also drop the expression column if no other index is
148151
// using the expression column.
@@ -209,7 +212,7 @@ func maybeDropDependentFunctions(
209212
if forwardRef.IndexID != toBeDroppedIndex.IndexID {
210213
continue
211214
}
212-
// This view depends on the to-be-dropped index;
215+
// This function depends on the to-be-dropped index.
213216
if dropBehavior != tree.DropCascade {
214217
// Get view name for the error message
215218
_, _, fnName := scpb.FindFunctionName(b.QueryByID(e.FunctionID))
@@ -293,6 +296,7 @@ func maybeDropAdditionallyForShardedIndex(
293296
b BuildCtx,
294297
toBeDroppedIndex *scpb.SecondaryIndex,
295298
toBeDroppedIndexName string,
299+
stmt tree.Statement,
296300
dropBehavior tree.DropBehavior,
297301
) {
298302
if toBeDroppedIndex.Sharding == nil || !toBeDroppedIndex.Sharding.IsSharded {
@@ -350,6 +354,11 @@ func maybeDropAdditionallyForShardedIndex(
350354
b.Drop(e)
351355
}
352356
})
357+
tbl := b.QueryByID(toBeDroppedIndex.TableID).FilterTable().MustGetOneElement()
358+
ns := b.QueryByID(toBeDroppedIndex.TableID).FilterNamespace().MustGetOneElement()
359+
tn := tree.MakeTableNameFromPrefix(b.NamePrefix(tbl), tree.Name(ns.Name))
360+
shardCol := shardColElms.FilterColumn().MustGetOneElement()
361+
dropColumn(b, &tn, tbl, stmt, stmt, shardCol, shardColElms, dropBehavior)
353362
}
354363

355364
// dropAdditionallyForExpressionIndex attempts to drop the additional

0 commit comments

Comments
 (0)