Skip to content

Commit f9aa66a

Browse files
committed
sql/inspect: skip REFCURSOR stored columns in consistency check
REFCURSOR values cannot be compared for equality, which breaks the `INSPECT` command when an index stores a column of this type. During a consistency check, INSPECT attempts to compare stored column payloads between the primary and secondary indexes. This fails for REFCURSOR values because the column type cannot be used in an equality comparison. This change skips REFCURSOR stored columns during the primary/secondary comparison. Informs: #155676 Epic: CRDB-55075 Release note (bug fix): INSPECT can now be run on tables with indexes that store REFCURSOR-typed columns.
1 parent 5fdc01e commit f9aa66a

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

pkg/sql/inspect/index_consistency_check.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
2626
"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
2727
"github.com/cockroachdb/cockroach/pkg/sql/spanutils"
28+
"github.com/cockroachdb/cockroach/pkg/sql/types"
2829
"github.com/cockroachdb/cockroach/pkg/util/hlc"
2930
"github.com/cockroachdb/errors"
3031
"github.com/cockroachdb/redact"
@@ -106,6 +107,8 @@ func (c *indexConsistencyCheck) Start(
106107
colToIdx.Set(colID, -1)
107108
}
108109

110+
joinColumns := append([]catalog.Column(nil), pkColumns...)
111+
109112
// Collect all of the columns we are fetching from the index. This
110113
// includes the columns involved in the index: columns, extra columns,
111114
// and store columns.
@@ -120,6 +123,12 @@ func (c *indexConsistencyCheck) Start(
120123
}
121124
col := c.tableDesc.PublicColumns()[pos]
122125
otherColumns = append(otherColumns, col)
126+
if col.GetType().Family() == types.RefCursorFamily {
127+
// Refcursor values do not support equality comparison, so we cannot use
128+
// them in the join predicates that detect inconsistencies.
129+
return
130+
}
131+
joinColumns = append(joinColumns, col)
123132
})
124133

125134
c.columns = append(pkColumns, otherColumns...)
@@ -203,7 +212,8 @@ func (c *indexConsistencyCheck) Start(
203212
}
204213

205214
checkQuery := c.createIndexCheckQuery(
206-
colNames(pkColumns), colNames(otherColumns), c.tableDesc.GetID(), c.secIndex, c.priIndex.GetID(), predicate,
215+
colNames(pkColumns), colNames(otherColumns), colNames(joinColumns),
216+
c.tableDesc.GetID(), c.secIndex, c.priIndex.GetID(), predicate,
207217
)
208218

209219
// Wrap the query with AS OF SYSTEM TIME to ensure it uses the specified timestamp
@@ -451,7 +461,7 @@ func (c *indexConsistencyCheck) loadCatalogInfo(ctx context.Context) error {
451461
// - Rows in primary index missing from secondary index
452462
// - Rows in secondary index missing from primary index
453463
func (c *indexConsistencyCheck) createIndexCheckQuery(
454-
pkColumns, otherColumns []string,
464+
pkColumns, otherColumns, lookupColumns []string,
455465
tableID descpb.ID,
456466
index catalog.Index,
457467
primaryIndexID descpb.IndexID,
@@ -460,9 +470,9 @@ func (c *indexConsistencyCheck) createIndexCheckQuery(
460470
allColumns := append(pkColumns, otherColumns...)
461471

462472
// Build join conditions using helper function
463-
lookupClause := buildJoinConditions(allColumns, "pri", "sec")
473+
lookupClause := buildJoinConditions(lookupColumns, "pri", "sec")
464474
mergeClause := buildJoinConditions(pkColumns, "pri", "sec")
465-
reverseLookupClause := buildJoinConditions(allColumns, "sec", "pri")
475+
reverseLookupClause := buildJoinConditions(lookupColumns, "sec", "pri")
466476
reverseMergeClause := buildJoinConditions(pkColumns, "sec", "pri")
467477

468478
// If there are no non-primary-key columns, we don't need to split by NULL/non-NULL

pkg/sql/logictest/testdata/logic_test/inspect

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,32 @@ statement ok
349349
DROP DATABASE dbfoo;
350350

351351
subtest end
352+
353+
subtest refcursor_stored_column
354+
355+
statement ok
356+
CREATE TABLE refcursor_tbl (id INT PRIMARY KEY, a INT, c REFCURSOR);
357+
358+
statement ok
359+
INSERT INTO refcursor_tbl VALUES (1, 10, 'cursor1'), (2, 20, 'cursor2');
360+
361+
# Verify that we cannot index the refcursor. They can only be included
362+
# in an index as stored columns.
363+
statement error pq: unimplemented: column c has type refcursor, which is not indexable
364+
CREATE INDEX idx_refcursor ON refcursor_tbl (c);
365+
366+
statement ok
367+
CREATE INDEX idx_refcursor ON refcursor_tbl (a) STORING (c);
368+
369+
statement ok
370+
INSPECT TABLE refcursor_tbl WITH OPTIONS INDEX ALL;
371+
372+
query TI
373+
SELECT * FROM last_inspect_job;
374+
----
375+
succeeded 1
376+
377+
statement ok
378+
DROP TABLE refcursor_tbl;
379+
380+
subtest end

0 commit comments

Comments
 (0)