Skip to content

Commit

Permalink
colexec: cfetcher errors on setup when indexed column contains unhand…
Browse files Browse the repository at this point in the history
…led type

Fixes cockroachdb#42994.

Indexed columns are always decoded by the fetcher, even if they are unneeded.
This PR adds the check to cfetcher initialization to error out if an indexed
column is of an unneeded type.

Release note (bug fix): Fixed a bug where scanning an index of an unsupported
type with the vectorized engine would lead to an internal error.
  • Loading branch information
rohany committed Dec 5, 2019
1 parent 2736003 commit 5b8932b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 10 deletions.
35 changes: 25 additions & 10 deletions pkg/sql/colexec/cfetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,30 +268,45 @@ func (rf *cFetcher) Init(
}
sort.Sort(m)
colDescriptors := tableArgs.Cols
typs := make([]coltypes.T, len(colDescriptors))
for i := range typs {
typs[i] = typeconv.FromColumnType(&colDescriptors[i].Type)
if typs[i] == coltypes.Unhandled && tableArgs.ValNeededForCol.Contains(i) {
// Only return an error if the type is unhandled and needed. If not needed,
// a placeholder Vec will be created.
return errors.Errorf("unhandled type %+v", &colDescriptors[i].Type)
}
}
table := cTableInfo{
spans: tableArgs.Spans,
desc: tableArgs.Desc,
colIdxMap: m,
index: tableArgs.Index,
isSecondaryIndex: tableArgs.IsSecondaryIndex,
cols: colDescriptors,
typs: typs,

// These slice fields might get re-allocated below, so reslice them from
// the old table here in case they've got enough capacity already.
indexColOrdinals: oldTable.indexColOrdinals[:0],
extraValColOrdinals: oldTable.extraValColOrdinals[:0],
allExtraValColOrdinals: oldTable.allExtraValColOrdinals[:0],
}

// All columns that are part of the index key will be decoded when reading a key. Since some types
// are not supported by the vectorized engine, we should error out during setup if some needed columns
// or columns we decode always will be attempted to be decoded.
typs := make([]coltypes.T, len(colDescriptors))
for i := range typs {
typs[i] = typeconv.FromColumnType(&colDescriptors[i].Type)
}
var indexedCols util.FastIntSet
for _, colID := range tableArgs.Index.ColumnIDs {
indexedCols.Add(int(colID))
}
if cHasExtraCols(&table) {
for _, colID := range tableArgs.Index.ExtraColumnIDs {
indexedCols.Add(int(colID))
}
}
for i := range typs {
if typs[i] == coltypes.Unhandled && (tableArgs.ValNeededForCol.Contains(i) || indexedCols.Contains(int(colDescriptors[i].ID))) {
// Only return an error if the type is unhandled and needed. If not needed,
// a placeholder Vec will be created.
return errors.Errorf("unhandled type %+v", &colDescriptors[i].Type)
}
}
table.typs = typs
rf.machine.batch = allocator.NewMemBatch(typs)
rf.machine.colvecs = rf.machine.batch.ColVecs()

Expand Down
10 changes: 10 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/vectorize
Original file line number Diff line number Diff line change
Expand Up @@ -1006,3 +1006,13 @@ SELECT * FROM t_42816 ORDER BY a OFFSET 1020 LIMIT 10
1023
1024
1025

# Regression test for #42994
statement ok
CREATE TABLE t42994 (a int primary key, b bit, index i (a, b));
INSERT INTO t42994 VALUES (1, 1::BIT);

query I
SELECT a FROM t42994@i
----
1

0 comments on commit 5b8932b

Please sign in to comment.