diff --git a/pkg/sql/logictest/testdata/logic_test/refcursor b/pkg/sql/logictest/testdata/logic_test/refcursor index 56fd0750201c..52adcf422688 100644 --- a/pkg/sql/logictest/testdata/logic_test/refcursor +++ b/pkg/sql/logictest/testdata/logic_test/refcursor @@ -440,29 +440,77 @@ SELECT 'foo'::REFCURSOR >= 'foo'::TEXT; statement error pgcode 22023 pq: unsupported comparison operator SELECT 'foo'::REFCURSOR >= NULL; -# TODO(drewk): Postgres allows this case. -statement error pgcode 42883 pq: unsupported comparison operator -SELECT 'foo'::REFCURSOR IS NULL; - -statement error pgcode 42883 pq: unsupported comparison operator -SELECT 'foo'::REFCURSOR IS NOT NULL; - statement error pgcode 22023 pq: unsupported comparison operator SELECT 'foo'::REFCURSOR IS DISTINCT FROM 'foo'::REFCURSOR; statement error pgcode 22023 pq: unsupported comparison operator SELECT 'foo'::REFCURSOR IS DISTINCT FROM 'foo'::TEXT; -statement error pgcode 22023 pq: unsupported comparison operator -SELECT 'foo'::REFCURSOR IS DISTINCT FROM NULL; - statement error pgcode 22023 pq: unsupported comparison operator SELECT 'foo'::REFCURSOR IS NOT DISTINCT FROM 'foo'::REFCURSOR; statement error pgcode 22023 pq: unsupported comparison operator SELECT 'foo'::REFCURSOR IS NOT DISTINCT FROM 'foo'::TEXT; -statement error pgcode 22023 pq: unsupported comparison operator +# Regression test for #112010 - REFCURSOR should allow IS NULL and +# IS NOT NULL comparisons. +subtest is_null + +query B +SELECT 'foo'::REFCURSOR IS NULL; +---- +false + +query B +SELECT 'foo'::REFCURSOR IS NOT NULL; +---- +true + +query B +SELECT 'foo'::REFCURSOR IS DISTINCT FROM NULL; +---- +true + +query B SELECT 'foo'::REFCURSOR IS NOT DISTINCT FROM NULL; +---- +false + +# REFCURSOR columns are allowed. +query B rowsort +SELECT l IS NULL FROM implicit_types; +---- +true +true +true +true +true + +query B rowsort +SELECT l IS NOT NULL FROM implicit_types; +---- +false +false +false +false +false + +query B rowsort +SELECT l IS DISTINCT FROM NULL FROM implicit_types; +---- +false +false +false +false +false + +query B rowsort +SELECT l IS NOT DISTINCT FROM NULL FROM implicit_types; +---- +true +true +true +true +true subtest end diff --git a/pkg/sql/sem/tree/eval.go b/pkg/sql/sem/tree/eval.go index 6748453f51ed..e9784271e94f 100644 --- a/pkg/sql/sem/tree/eval.go +++ b/pkg/sql/sem/tree/eval.go @@ -1775,6 +1775,10 @@ var CmpOps = cmpOpFixups(map[treecmp.ComparisonOperatorSymbol]*CmpOpOverloads{ makeIsFn(types.Void, types.Unknown, volatility.Leakproof), makeIsFn(types.Unknown, types.Void, volatility.Leakproof), + // REFCURSOR cannot be compared with itself, but as a special case, it can + // be compared with NULL using IS NOT DISTINCT FROM. + makeIsFn(types.RefCursor, types.Unknown, volatility.Leakproof), + // Tuple comparison. { LeftType: types.AnyTuple, diff --git a/pkg/sql/sem/tree/type_check.go b/pkg/sql/sem/tree/type_check.go index abd896057bdf..cbef0101ba1b 100644 --- a/pkg/sql/sem/tree/type_check.go +++ b/pkg/sql/sem/tree/type_check.go @@ -941,14 +941,6 @@ func (expr *ComparisonExpr) TypeCheck( return nil, err } - // REFCURSOR does not support comparisons. - leftType, rightType := leftTyped.ResolvedType(), rightTyped.ResolvedType() - if leftType.Family() == types.RefCursorFamily || rightType.Family() == types.RefCursorFamily { - return nil, pgerror.Newf(pgcode.UndefinedFunction, - "unsupported comparison operator: <%s> %s <%s>", leftType, cmpOp, rightType, - ) - } - if alwaysNull { return DNull, nil } @@ -1471,12 +1463,6 @@ func (expr *IsNullExpr) TypeCheck( if err != nil { return nil, err } - // REFCURSOR does not support comparisons. - if exprTyped.ResolvedType().Family() == types.RefCursorFamily { - return nil, pgerror.New(pgcode.UndefinedFunction, - "unsupported comparison operator: refcursor IS unknown", - ) - } expr.Expr = exprTyped expr.typ = types.Bool return expr, nil @@ -1490,12 +1476,6 @@ func (expr *IsNotNullExpr) TypeCheck( if err != nil { return nil, err } - // REFCURSOR does not support comparisons. - if exprTyped.ResolvedType().Family() == types.RefCursorFamily { - return nil, pgerror.New(pgcode.UndefinedFunction, - "unsupported comparison operator: refcursor IS NOT unknown", - ) - } expr.Expr = exprTyped expr.typ = types.Bool return expr, nil