Skip to content

Commit

Permalink
eval: show error when comparing OID to int out of range
Browse files Browse the repository at this point in the history
Release note (sql change): An error is now returned if an OID is
compared to an integer that is out of the allowable range of OID input
values, which is [MinInt32, MaxUint32].
  • Loading branch information
rafiss committed Jun 7, 2022
1 parent 7c19893 commit dde16a8
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 1 deletion.
37 changes: 37 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/pgoidtype
Original file line number Diff line number Diff line change
Expand Up @@ -525,3 +525,40 @@ regression_62205
# Check we error as appropriate if the OID type is not legit.
statement error pgcode 22P02 invalid input syntax for type oid: "regression_69907"
SELECT 'regression_69907'::oid

# 4294967295 is MaxUint32.
# -2147483648 is MinInt32.
query OIBB
SELECT o, i, o > i, i > o FROM (VALUES
(1::oid, 4294967295::int8),
(1::oid, -2147483648::int8),
((-1)::oid, 4294967295::int8),
((-1)::oid, -2147483648::int8),
((-2147483648)::oid, 4294967295::int8),
((-2147483648)::oid, -2147483648::int8),
(4294967295::oid, 4294967295::int8),
(4294967295::oid, -2147483648::int8)
) tbl(o, i)
----
1 4294967295 false true
1 -2147483648 false true
4294967295 4294967295 false false
4294967295 -2147483648 true false
2147483648 4294967295 false true
2147483648 -2147483648 false false
4294967295 4294967295 false false
4294967295 -2147483648 true false

# 4294967296 is (MaxUint32 + 1).
query error OID out of range: 4294967296
SELECT 1:::OID >= 4294967296:::INT8

query error OID out of range: 4294967296
SELECT 4294967296:::INT8 >= 1:::OID

# -2147483649 is (MinInt32 - 1).
query error OID out of range: -2147483649
SELECT 1:::OID >= -2147483649:::INT8

query error OID out of range: -2147483649
SELECT -2147483649:::INT8 >= 1:::OID
5 changes: 4 additions & 1 deletion pkg/sql/sem/eval/binary_op.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ func (e *evaluator) EvalCompareScalarOp(
return tree.DNull, nil
}
}
cmp := left.Compare(e.ctx(), right)
cmp, err := left.CompareError(e.ctx(), right)
if err != nil {
return nil, err
}
return boolFromCmp(cmp, op.ComparisonOperator), nil
}

Expand Down
44 changes: 44 additions & 0 deletions pkg/sql/sem/eval/testdata/eval/oid
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,47 @@ eval
1:::OID <= -3:::INT
----
true

# 4294967295 is MaxUint32.
eval
1:::OID >= 4294967295:::INT8
----
false

eval
4294967295:::INT8 >= 1:::OID
----
true

# 4294967296 is (MaxUint32 + 1).
eval
1:::OID >= 4294967296:::INT8
----
OID out of range: 4294967296

eval
4294967296:::INT8 >= 1:::OID
----
OID out of range: 4294967296

# -2147483648 is MinInt32.
eval
1:::OID >= -2147483648:::INT8
----
false

eval
-2147483648:::INT8 >= 1:::OID
----
true

# -2147483649 is (MinInt32 - 1).
eval
1:::OID >= -2147483649:::INT8
----
OID out of range: -2147483649

eval
-2147483649:::INT8 >= 1:::OID
----
OID out of range: -2147483649
6 changes: 6 additions & 0 deletions pkg/sql/sem/tree/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,9 @@ func (d *DInt) CompareError(ctx CompareContext, other Datum) (int, error) {
// OIDs are always unsigned 32-bit integers. Some languages, like Java,
// compare OIDs to signed 32-bit integers, so we implement the comparison
// by converting to a uint32 first. This matches Postgres behavior.
if thisInt > math.MaxUint32 || thisInt < math.MinInt32 {
return 0, pgerror.Newf(pgcode.NumericValueOutOfRange, "OID out of range: %d", thisInt)
}
thisInt = DInt(uint32(thisInt))
v = DInt(t.Oid)
default:
Expand Down Expand Up @@ -4963,6 +4966,9 @@ func (d *DOid) CompareError(ctx CompareContext, other Datum) (int, error) {
// OIDs are always unsigned 32-bit integers. Some languages, like Java,
// compare OIDs to signed 32-bit integers, so we implement the comparison
// by converting to a uint32 first. This matches Postgres behavior.
if *t > math.MaxUint32 || *t < math.MinInt32 {
return 0, pgerror.Newf(pgcode.NumericValueOutOfRange, "OID out of range: %d", *t)
}
v = oid.Oid(*t)
default:
return 0, makeUnsupportedComparisonMessage(d, other)
Expand Down

0 comments on commit dde16a8

Please sign in to comment.