diff --git a/pkg/sql/colexec/colbuilder/execplan.go b/pkg/sql/colexec/colbuilder/execplan.go index 2d6b8b34f267..8ba8120f54a6 100644 --- a/pkg/sql/colexec/colbuilder/execplan.go +++ b/pkg/sql/colexec/colbuilder/execplan.go @@ -2727,6 +2727,7 @@ func planProjectionExpr( resultIdx = len(typs) // The projection result will be outputted to a new column which is // appended to the input batch. + // TODO(#127814): We may need to handle the case when the left is DNull. op, err = colexecprojconst.GetProjectionLConstOperator( allocator, typs, left.ResolvedType(), outputType, projOp, input, rightIdx, lConstArg, resultIdx, evalCtx, binOp, cmpExpr, calledOnNullInput, @@ -2769,7 +2770,12 @@ func planProjectionExpr( // The projection result will be outputted to a new column which is // appended to the input batch. resultIdx = len(typs) - if isCmpProjOp { + if !calledOnNullInput && right == tree.DNull { + // If the right is NULL and the operator is not called on NULL, + // simply project NULL. + op = colexecbase.NewConstNullOp(allocator, input, resultIdx) + } else if isCmpProjOp { + // Use optimized operators for special cases. switch cmpProjOp.Symbol { case treecmp.Like, treecmp.NotLike, treecmp.ILike, treecmp.NotILike: negate, caseInsensitive := examineLikeOp(cmpProjOp) diff --git a/pkg/sql/logictest/testdata/logic_test/subquery b/pkg/sql/logictest/testdata/logic_test/subquery index a08d12fd75ad..460f426f1a2b 100644 --- a/pkg/sql/logictest/testdata/logic_test/subquery +++ b/pkg/sql/logictest/testdata/logic_test/subquery @@ -1039,4 +1039,18 @@ LEFT JOIN LATERAL ( row-1 row-1 {row-1} 1 row-2 row-2 {row-2} 1 -subtest end +# Regression test for #127814. The vectorized engine should correctly project +# expressions operating on NULL. +statement ok +CREATE TABLE t127814_empty (i INT) + +statement ok +CREATE TABLE t127814 (o OID) + +statement ok +INSERT INTO t127814 VALUES (0) + +query B +SELECT o NOT IN ((SELECT NULL FROM t127814_empty),) FROM t127814 +---- +NULL