diff --git a/pkg/sql/rowexec/inverted_expr_evaluator.go b/pkg/sql/rowexec/inverted_expr_evaluator.go index 9a3ed45b81b3..b90abbcdd48a 100644 --- a/pkg/sql/rowexec/inverted_expr_evaluator.go +++ b/pkg/sql/rowexec/inverted_expr_evaluator.go @@ -288,7 +288,7 @@ type batchedInvertedExprEvaluator struct { nonInvertedPrefixes []roachpb.Key // Spans here are in sorted order and non-overlapping. fragmentedSpans []invertedSpanRoutingInfo - // The routing index computed by prepareAddIndexRow + // The routing index computed by prepareAddIndexRow. routingIndex int // Temporary state used during initialization. @@ -514,10 +514,18 @@ func (b *batchedInvertedExprEvaluator) prepareAddIndexRow( if encFull != nil { routingEnc = encFull } + // Find the first span that comes after the encoded routing value. i := sort.Search(len(b.fragmentedSpans), func(i int) bool { return bytes.Compare(b.fragmentedSpans[i].span.Start, routingEnc) > 0 }) + // Decrement by 1 so that now i tracks the index of the span that might + // contain the encoded routing value. i-- + if i < 0 { + // Negative index indicates that some assumptions are violated, return + // an assertion error in this case. + return false, errors.AssertionFailedf("unexpectedly negative routing index %d", i) + } b.routingIndex = i return b.prefilter(enc) } diff --git a/pkg/sql/rowexec/inverted_filterer.go b/pkg/sql/rowexec/inverted_filterer.go index f78fcbf12e8f..206cb7b6a8cb 100644 --- a/pkg/sql/rowexec/inverted_filterer.go +++ b/pkg/sql/rowexec/inverted_filterer.go @@ -39,9 +39,6 @@ const ( ifrEmittingRows ) -// TODO(sumeer): support pre-filtering, akin to the invertedJoiner, by passing -// relationship info and parameters in the spec and using it to construct a -// preFilterer. type invertedFilterer struct { execinfra.ProcessorBase runningState invertedFiltererState @@ -210,18 +207,7 @@ func (ifr *invertedFilterer) readInput() (invertedFiltererState, *execinfrapb.Pr row[i].Datum = tree.DNull } } - // Transform to keyRow. - copy(ifr.keyRow, row[:ifr.invertedColIdx]) - copy(ifr.keyRow[ifr.invertedColIdx:], row[ifr.invertedColIdx+1:]) - // Add the primary key in the row to the row container. The first column in - // the inverted index is the value that was indexed, and the remaining are - // the primary key columns. - keyIndex, err := ifr.rc.AddRow(ifr.Ctx, ifr.keyRow) - if err != nil { - ifr.MoveToDraining(err) - return ifrStateUnknown, ifr.DrainHelper() - } // Add to the evaluator. // // NB: Inverted columns are custom encoded in a manner that does not @@ -247,13 +233,26 @@ func (ifr *invertedFilterer) readInput() (invertedFiltererState, *execinfrapb.Pr } enc = []byte(*row[ifr.invertedColIdx].Datum.(*tree.DBytes)) } - if _, err = ifr.invertedEval.prepareAddIndexRow(enc, nil /* encFull */); err != nil { + shouldAdd, err := ifr.invertedEval.prepareAddIndexRow(enc, nil /* encFull */) + if err != nil { ifr.MoveToDraining(err) return ifrStateUnknown, ifr.DrainHelper() } - if err = ifr.invertedEval.addIndexRow(keyIndex); err != nil { - ifr.MoveToDraining(err) - return ifrStateUnknown, ifr.DrainHelper() + if shouldAdd { + // Transform to keyRow which is everything other than the inverted + // column and then add it to the row container and the inverted expr + // evaluator. + copy(ifr.keyRow, row[:ifr.invertedColIdx]) + copy(ifr.keyRow[ifr.invertedColIdx:], row[ifr.invertedColIdx+1:]) + keyIndex, err := ifr.rc.AddRow(ifr.Ctx, ifr.keyRow) + if err != nil { + ifr.MoveToDraining(err) + return ifrStateUnknown, ifr.DrainHelper() + } + if err = ifr.invertedEval.addIndexRow(keyIndex); err != nil { + ifr.MoveToDraining(err) + return ifrStateUnknown, ifr.DrainHelper() + } } return ifrReadingInput, nil }