Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release-21.1: sql: fix ColumnAccessExpr.Eval with NULL inner expression #79527

Merged
merged 2 commits into from Apr 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 32 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/tuple
Expand Up @@ -978,3 +978,35 @@ CREATE TABLE t74729 AS SELECT g % 2 = 1 AS _bool FROM generate_series(1, 5) AS g

statement ok
SELECT CASE WHEN _bool THEN (1, ('a', 2)) ELSE (3, NULL) END FROM t74729

# Regression test for #78159. Column access of NULL should not cause an internal
# error.
subtest 78159

statement ok
CREATE TABLE t78159 (b BOOL)

statement ok
INSERT INTO t78159 VALUES (false)

query B
SELECT (CASE WHEN b THEN ((ROW(1) AS a)) ELSE NULL END).a from t78159
----
NULL

# Regression test for #78515. Propagate tuple labels when type-checking
# expressions with multiple matching tuple types.
subtest 78515

statement ok
SELECT (CASE WHEN false THEN (ROW(1) AS a) ELSE (ROW(2) AS a) END).a;

# The label of the first tuple is used in the type of the CASE expression. This
# is similar to Postgres, but not exactly the same - Postgres uses the labels of
# the last tuple. This difference should be addressed in the future when we try
# to adhere more closely to Postgres's type conversion behavior (see #75101).
statement ok
SELECT (CASE WHEN false THEN (ROW(1) AS a) ELSE (ROW(2) AS b) END).a;

statement error could not identify column \"b\" in tuple{int AS a}
SELECT (CASE WHEN false THEN (ROW(1) AS a) ELSE (ROW(2) AS b) END).b;
3 changes: 3 additions & 0 deletions pkg/sql/sem/tree/eval.go
Expand Up @@ -3927,6 +3927,9 @@ func (expr *ColumnAccessExpr) Eval(ctx *EvalContext) (Datum, error) {
if err != nil {
return nil, err
}
if d == DNull {
return d, nil
}
return d.(*DTuple).D[expr.ColIndex], nil
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/sem/tree/type_check.go
Expand Up @@ -2397,7 +2397,7 @@ func typeCheckSameTypedTupleExprs(
}

// All expressions within tuples at the same indexes must be the same type.
resTypes := types.MakeTuple(make([]*types.T, firstLen))
resTypes := types.MakeLabeledTuple(make([]*types.T, firstLen), first.Labels)
sameTypeExprs := make([]Expr, 0, len(exprs))
// We will be skipping nulls, so we need to keep track at which indices in
// exprs are the non-null tuples.
Expand Down