Skip to content

Commit

Permalink
colexec: fix IN operator with unsorted tuple
Browse files Browse the repository at this point in the history
The vectorized implementation of an `element IN tuple` expression
assumes that the contents of `tuple` are sorted by the optimizer. Based
on this assumption, it performs a binary search instead of a linear
search.

However, the assumption that the optimizer sorts all tuples is
incorrect. For example, there are cases where the contents of a tuple
are not known at planning-time, so the tuple cannot be sorted.
Performing a binary search with an unsorted tuple causes incorrect query
results.

Now, the vectorized engine sorts tuple contents if they are not already
sorted.

Fixes #68979

Release justification: This commit fixes a bug with the IN operator that
causes incorrect results.

Release note (bug fix): A bug has been fixed which caused incorrect
evaluation of the `IN` operator when the tuple on the right-hand-side
of the operator included a subquery, like
`a IN ('foo', (SELECT s FROM t), 'bar')`.
  • Loading branch information
mgartner committed Sep 1, 2021
1 parent e946415 commit c31480a
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 68 deletions.
4 changes: 2 additions & 2 deletions pkg/sql/colexec/colbuilder/execplan.go
Original file line number Diff line number Diff line change
Expand Up @@ -1976,7 +1976,7 @@ func planSelectionOperators(
if !ok || useDefaultCmpOpForIn(datumTuple) {
break
}
op, err = colexec.GetInOperator(lTyp, leftOp, leftIdx, datumTuple, negate)
op, err = colexec.GetInOperator(evalCtx, lTyp, leftOp, leftIdx, datumTuple, negate)
case tree.IsDistinctFrom, tree.IsNotDistinctFrom:
if constArg != tree.DNull {
// Optimized IsDistinctFrom and IsNotDistinctFrom are
Expand Down Expand Up @@ -2405,7 +2405,7 @@ func planProjectionExpr(
break
}
op, err = colexec.GetInProjectionOperator(
allocator, typs[leftIdx], input, leftIdx, resultIdx, datumTuple, negate,
evalCtx, allocator, typs[leftIdx], input, leftIdx, resultIdx, datumTuple, negate,
)
case tree.IsDistinctFrom, tree.IsNotDistinctFrom:
if right != tree.DNull {
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/colexec/execgen/cmd/execgen/select_in_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ func genSelectIn(inputFileContents string, wr io.Writer) error {
)
s := r.Replace(inputFileContents)

assignEq := makeFunctionRegex("_COMPARE", 5)
s = assignEq.ReplaceAllString(s, makeTemplateFunctionCall("Compare", 5))
compare := makeFunctionRegex("_COMPARE", 5)
s = compare.ReplaceAllString(s, makeTemplateFunctionCall("Compare", 5))

s = replaceManipulationFuncs(s)

Expand Down
Loading

0 comments on commit c31480a

Please sign in to comment.