diff --git a/pkg/sql/opt/norm/fold_constants_funcs.go b/pkg/sql/opt/norm/fold_constants_funcs.go index f7c055eda55f..1926bb479c1b 100644 --- a/pkg/sql/opt/norm/fold_constants_funcs.go +++ b/pkg/sql/opt/norm/fold_constants_funcs.go @@ -88,9 +88,10 @@ func (c *CustomFuncs) HasNullElement(input opt.ScalarExpr) bool { } // HasAllNullElements returns true if the input tuple has only constant, null -// elements. Note that it only returns true if all elements are known to be -// null. For example, given the tuple (NULL, x), it will return false because x -// is not guaranteed to be null. +// elements, or if the tuple is empty (has 0 elements). Note that it only +// returns true if all elements are known to be null. For example, given the +// tuple (NULL, x), it will return false because x is not guaranteed to be +// null. func (c *CustomFuncs) HasAllNullElements(input opt.ScalarExpr) bool { tup := input.(*memo.TupleExpr) for _, e := range tup.Elems { @@ -122,9 +123,10 @@ func (c *CustomFuncs) HasNonNullElement(input opt.ScalarExpr) bool { } // HasAllNonNullElements returns true if the input tuple has all constant, -// non-null elements. Note that it only returns true if all elements are known -// to be non-null. For example, given the tuple (1, x), it will return false -// because x is not guaranteed to be non-null. +// non-null elements, or if the tuple is empty (has 0 elements). Note that it +// only returns true if all elements are known to be non-null. For example, +// given the tuple (1, x), it will return false because x is not guaranteed to +// be non-null. func (c *CustomFuncs) HasAllNonNullElements(input opt.ScalarExpr) bool { tup := input.(*memo.TupleExpr) for _, e := range tup.Elems { diff --git a/pkg/sql/opt/norm/testdata/rules/comp b/pkg/sql/opt/norm/testdata/rules/comp index de9932ac148a..ca24a10975f2 100644 --- a/pkg/sql/opt/norm/testdata/rules/comp +++ b/pkg/sql/opt/norm/testdata/rules/comp @@ -363,6 +363,16 @@ values ├── fd: ()-->(1) └── (true,) +norm expect=FoldNullTupleIsTupleNull +SELECT () IS NULL AS r +---- +values + ├── columns: r:1!null + ├── cardinality: [1 - 1] + ├── key: () + ├── fd: ()-->(1) + └── (true,) + norm expect-not=FoldNullTupleIsTupleNull SELECT (k, NULL) IS NULL FROM a ---- @@ -535,6 +545,16 @@ values ├── fd: ()-->(1) └── (true,) +norm expect=FoldNonNullTupleIsTupleNotNull +SELECT () IS NOT NULL AS r +---- +values + ├── columns: r:1!null + ├── cardinality: [1 - 1] + ├── key: () + ├── fd: ()-->(1) + └── (true,) + norm expect-not=FoldNonNullTupleIsTupleNotNull SELECT (1, k) IS NOT NULL FROM a ---- diff --git a/pkg/sql/sem/tree/testdata/eval/is b/pkg/sql/sem/tree/testdata/eval/is index 93343c072250..878de7202e27 100644 --- a/pkg/sql/sem/tree/testdata/eval/is +++ b/pkg/sql/sem/tree/testdata/eval/is @@ -524,3 +524,15 @@ eval NOT ((NULL, NULL) IS DISTINCT FROM NULL) ---- false + +# Empty tuples. + +eval +() IS NULL +---- +true + +eval +() IS NOT NULL +---- +true