Skip to content

Commit 6dd2e30

Browse files
committed
colexec: fix projections with constant NULL values
This commit fixes a bug in the vectorized engine that caused internal errors when projections operated on constant NULL values. The proj_const_right_ops operators do not correctly handle NULL inputs. So, we avoid these code paths when operator does not operate on NULL values and the LHS or RHS of an operator is NULL by simply projecting NULLs. This is similar to the change made in #128123 and addresses a TODO added in that PR. This code path is unlikely to hit (maybe impossible) without generic query plans. In an optimized cusotm plan, the optimizer will fold expressions with `NULL` values at optimization time, and the execution engine will never see expressions of this form. Fixes #152771 Release note (bug fix): A bug has been fixed that could cause internal errors for queries using generic query plans with `NULL` placeholder values.
1 parent e59b548 commit 6dd2e30

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

pkg/sql/colexec/colbuilder/execplan.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,11 +2828,16 @@ func planProjectionExpr(
28282828
resultIdx = len(typs)
28292829
// The projection result will be outputted to a new column which is
28302830
// appended to the input batch.
2831-
// TODO(#127814): We may need to handle the case when the left is DNull.
2832-
op, err = colexecprojconst.GetProjectionLConstOperator(
2833-
allocator, typs, left.ResolvedType(), outputType, projOp, input,
2834-
rightIdx, lConstArg, resultIdx, evalCtx, binOp, cmpExpr, calledOnNullInput,
2835-
)
2831+
if !calledOnNullInput && (left == tree.DNull || right == tree.DNull) {
2832+
// If the left or right is NULL and the operator is not called on
2833+
// NULL, simply project NULL.
2834+
op = colexecbase.NewConstNullOp(allocator, outputType, input, resultIdx)
2835+
} else {
2836+
op, err = colexecprojconst.GetProjectionLConstOperator(
2837+
allocator, typs, left.ResolvedType(), outputType, projOp, input,
2838+
rightIdx, lConstArg, resultIdx, evalCtx, binOp, cmpExpr, calledOnNullInput,
2839+
)
2840+
}
28362841
} else {
28372842
var leftIdx int
28382843
input, leftIdx, typs, err = planProjectionOperators(

pkg/sql/logictest/testdata/logic_test/vectorize

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,3 +1343,26 @@ statement ok
13431343
RESET vectorize
13441344

13451345
subtest end
1346+
1347+
# Regression test for #152771. Gracefully plan operators that cannot handle NULL
1348+
# inputs.
1349+
statement ok
1350+
CREATE TABLE t152771 (i INT)
1351+
1352+
statement ok
1353+
INSERT INTO t152771 VALUES (0)
1354+
1355+
statement ok
1356+
SET plan_cache_mode = force_generic_plan
1357+
1358+
statement ok
1359+
PREPARE p(INT, INT, INT, INT) AS UPDATE t152771 SET i=($1-$2)+($3-$4)
1360+
1361+
statement ok
1362+
EXECUTE p(NULL, 3, 33, NULL)
1363+
1364+
statement ok
1365+
DEALLOCATE p
1366+
1367+
statement ok
1368+
RESET plan_cache_mode

0 commit comments

Comments
 (0)