Skip to content

Commit

Permalink
sql: fix internal error when planning void IS NULL or void is NOT NULL
Browse files Browse the repository at this point in the history
This commit adds support for comparisons between columns of type void
and NULL using col IS NULL or col IS NOT NULL, by adding an explicit
overload.

Fixes #93572

Release note (bug fix): Fixed an internal error that could occur
when comparing a column of type void to NULL using col IS NULL
or col IS NOT NULL.
  • Loading branch information
rytaft committed Dec 15, 2022
1 parent 9aca4bf commit d17382d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
2 changes: 2 additions & 0 deletions docs/generated/sql/operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,11 @@
<tr><td>tsvector <code>IS NOT DISTINCT FROM</code> tsvector</td><td><a href="bool.html">bool</a></td></tr>
<tr><td>tuple <code>IS NOT DISTINCT FROM</code> tuple</td><td><a href="bool.html">bool</a></td></tr>
<tr><td>unknown <code>IS NOT DISTINCT FROM</code> unknown</td><td><a href="bool.html">bool</a></td></tr>
<tr><td>unknown <code>IS NOT DISTINCT FROM</code> void</td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="uuid.html">uuid</a> <code>IS NOT DISTINCT FROM</code> <a href="uuid.html">uuid</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="uuid.html">uuid[]</a> <code>IS NOT DISTINCT FROM</code> <a href="uuid.html">uuid[]</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td>varbit <code>IS NOT DISTINCT FROM</code> varbit</td><td><a href="bool.html">bool</a></td></tr>
<tr><td>void <code>IS NOT DISTINCT FROM</code> unknown</td><td><a href="bool.html">bool</a></td></tr>
</tbody></table>
<table><thead>
<tr><td><code>LIKE</code></td><td>Return</td></tr>
Expand Down
34 changes: 30 additions & 4 deletions pkg/sql/logictest/testdata/logic_test/void
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,20 @@ SELECT crdb_internal.void_func()
----
·

# Regression test for #83754. Postgres does not error out, but is inconsistent
# Regression test for #83754. Note that Postgres is inconsistent
# in evaluation. For example, `SELECT ''::VOID IS DISTINCT FROM NULL::UNKNOWN;`
# errors out, but `SELECT ''::VOID IS DISTINCT FROM NULL;` does not.
# This is due to normalization into an IS NOT NULL op when one operand is NULL.
# The NULL with type cast is not recognized as NULL.
# We will stay consistent and have both cases error out to avoid different
# behavior between normalized and unnormalized expressions.
statement error pq: unsupported comparison operator: <void> IS DISTINCT FROM <unknown>
query B
SELECT ''::VOID IS DISTINCT FROM NULL
----
true

query B
SELECT ''::VOID IS DISTINCT FROM NULL::UNKNOWN
----
true

statement ok
SET vectorize=on
Expand Down Expand Up @@ -147,3 +152,24 @@ NULL

statement ok
RESET vectorize

# Regression test for #93572. This should not fail with an internal error.
query B
WITH tab(x) AS (VALUES ('':::VOID)) SELECT x IS NULL FROM tab
----
false

query B
WITH tab(x) AS (VALUES (NULL:::VOID)) SELECT x IS NULL FROM tab
----
true

query B
WITH tab(x) AS (VALUES ('':::VOID)) SELECT x IS NOT NULL FROM tab
----
true

query B
WITH tab(x) AS (VALUES (NULL:::VOID)) SELECT x IS NOT NULL FROM tab
----
false
9 changes: 9 additions & 0 deletions pkg/sql/sem/tree/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -1728,6 +1728,15 @@ var CmpOps = cmpOpFixups(map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads{
makeIsFn(types.Time, types.TimeTZ, volatility.Stable),
makeIsFn(types.TimeTZ, types.Time, volatility.Stable),

// Void is unique in that it is not equivalent with itself, so implicit
// equivalence with Unknown in function ArgTypes.MatchAt due to the check
// `(typ.Family() == types.UnknownFamily || a[i].Typ.Equivalent(typ))` does
// not occur. Therefore, to allow the comparison
// `''::VOID IS DISTINCT FROM NULL`, an explicit equivalence with Unknown is
// added:
makeIsFn(types.Void, types.Unknown, volatility.Stable),
makeIsFn(types.Unknown, types.Void, volatility.Stable),

// Tuple comparison.
{
LeftType: types.AnyTuple,
Expand Down

0 comments on commit d17382d

Please sign in to comment.