From 6517f55399b6ea0f46cc532bb88bae9f8da73ffd Mon Sep 17 00:00:00 2001 From: Rafi Shamim Date: Wed, 26 Aug 2020 19:04:32 -0400 Subject: [PATCH] sql: allow INT to compare to OID An OID is just an INT, so they should be comparable. Postgres allows this, and certain drivers create queries that attempt to compare INTs to OIDs, so this improves compatibility. Release justification: low-risk, high benefit change that improves compatibility with PGJDBC. Release note (sql change): A value of type OID can now be compared to a value of type INT. --- docs/generated/sql/operators.md | 8 +++++++ .../logictest/testdata/logic_test/pgoidtype | 21 +++++++++++++++++++ pkg/sql/sem/tree/datum.go | 16 ++++++++++---- pkg/sql/sem/tree/eval.go | 8 +++++++ pkg/sql/sem/tree/testdata/eval/oid | 15 +++++++++++++ 5 files changed, 64 insertions(+), 4 deletions(-) diff --git a/docs/generated/sql/operators.md b/docs/generated/sql/operators.md index 99c556edc5e0..04b3710bb2b8 100644 --- a/docs/generated/sql/operators.md +++ b/docs/generated/sql/operators.md @@ -176,10 +176,12 @@ int < decimalbool int < floatbool int < intbool +int < oidbool int[] < int[]bool interval < intervalbool interval[] < interval[]bool jsonb < jsonbbool +oid < intbool oid < oidbool string < stringbool string[] < string[]bool @@ -237,10 +239,12 @@ int <= decimalbool int <= floatbool int <= intbool +int <= oidbool int[] <= int[]bool interval <= intervalbool interval[] <= interval[]bool jsonb <= jsonbbool +oid <= intbool oid <= oidbool string <= stringbool string[] <= string[]bool @@ -297,10 +301,12 @@ int = decimalbool int = floatbool int = intbool +int = oidbool int[] = int[]bool interval = intervalbool interval[] = interval[]bool jsonb = jsonbbool +oid = intbool oid = oidbool string = stringbool string[] = string[]bool @@ -411,10 +417,12 @@ int IS NOT DISTINCT FROM decimalbool int IS NOT DISTINCT FROM floatbool int IS NOT DISTINCT FROM intbool +int IS NOT DISTINCT FROM oidbool int[] IS NOT DISTINCT FROM int[]bool interval IS NOT DISTINCT FROM intervalbool interval[] IS NOT DISTINCT FROM interval[]bool jsonb IS NOT DISTINCT FROM jsonbbool +oid IS NOT DISTINCT FROM intbool oid IS NOT DISTINCT FROM oidbool string IS NOT DISTINCT FROM stringbool string[] IS NOT DISTINCT FROM string[]bool diff --git a/pkg/sql/logictest/testdata/logic_test/pgoidtype b/pkg/sql/logictest/testdata/logic_test/pgoidtype index 1f7cf7ccb0b1..475df7ffc9ea 100644 --- a/pkg/sql/logictest/testdata/logic_test/pgoidtype +++ b/pkg/sql/logictest/testdata/logic_test/pgoidtype @@ -326,3 +326,24 @@ query TT SELECT 1::OID::TEXT, quote_literal(1::OID) ---- 1 '1' + +# Allow INT-OID comparison. Regression test for #53143. +statement ok +SELECT + c.oid, + a.attnum, + a.attname, + c.relname, + n.nspname, + a.attnotnull + OR (t.typtype = 'd' AND t.typnotnull), + pg_catalog.pg_get_expr(d.adbin, d.adrelid) LIKE '%nextval(%' +FROM + pg_catalog.pg_class AS c + JOIN pg_catalog.pg_namespace AS n ON (c.relnamespace = n.oid) + JOIN pg_catalog.pg_attribute AS a ON (c.oid = a.attrelid) + JOIN pg_catalog.pg_type AS t ON (a.atttypid = t.oid) + LEFT JOIN pg_catalog.pg_attrdef AS d ON + (d.adrelid = a.attrelid AND d.adnum = a.attnum) + JOIN (SELECT 1 AS oid, 1 AS attnum) AS vals ON + (c.oid = vals.oid AND a.attnum = vals.attnum); diff --git a/pkg/sql/sem/tree/datum.go b/pkg/sql/sem/tree/datum.go index e7bd91e0e895..ec8c2da0276f 100644 --- a/pkg/sql/sem/tree/datum.go +++ b/pkg/sql/sem/tree/datum.go @@ -684,6 +684,8 @@ func (d *DInt) Compare(ctx *EvalContext, other Datum) int { v = *t case *DFloat, *DDecimal: return -t.Compare(ctx, d) + case *DOid: + v = t.DInt default: panic(makeUnsupportedComparisonMessage(d, other)) } @@ -4235,14 +4237,20 @@ func (d *DOid) Compare(ctx *EvalContext, other Datum) int { // NULL is less than any non-NULL value. return 1 } - v, ok := UnwrapDatum(ctx, other).(*DOid) - if !ok { + var v DInt + switch t := UnwrapDatum(ctx, other).(type) { + case *DOid: + v = t.DInt + case *DInt: + v = *t + default: panic(makeUnsupportedComparisonMessage(d, other)) } - if d.DInt < v.DInt { + + if d.DInt < v { return -1 } - if d.DInt > v.DInt { + if d.DInt > v { return 1 } return 0 diff --git a/pkg/sql/sem/tree/eval.go b/pkg/sql/sem/tree/eval.go index 11e64fccdfb6..479ba7d14234 100644 --- a/pkg/sql/sem/tree/eval.go +++ b/pkg/sql/sem/tree/eval.go @@ -2083,6 +2083,8 @@ var CmpOps = cmpOpFixups(map[ComparisonOperator]cmpOpOverload{ makeEqFn(types.Float, types.Int, VolatilityLeakProof), makeEqFn(types.Int, types.Decimal, VolatilityLeakProof), makeEqFn(types.Int, types.Float, VolatilityLeakProof), + makeEqFn(types.Int, types.Oid, VolatilityLeakProof), + makeEqFn(types.Oid, types.Int, VolatilityLeakProof), makeEqFn(types.Timestamp, types.Date, VolatilityImmutable), makeEqFn(types.Timestamp, types.TimestampTZ, VolatilityStable), makeEqFn(types.TimestampTZ, types.Date, VolatilityStable), @@ -2137,6 +2139,8 @@ var CmpOps = cmpOpFixups(map[ComparisonOperator]cmpOpOverload{ makeLtFn(types.Float, types.Int, VolatilityLeakProof), makeLtFn(types.Int, types.Decimal, VolatilityLeakProof), makeLtFn(types.Int, types.Float, VolatilityLeakProof), + makeLtFn(types.Int, types.Oid, VolatilityLeakProof), + makeLtFn(types.Oid, types.Int, VolatilityLeakProof), makeLtFn(types.Timestamp, types.Date, VolatilityImmutable), makeLtFn(types.Timestamp, types.TimestampTZ, VolatilityStable), makeLtFn(types.TimestampTZ, types.Date, VolatilityStable), @@ -2191,6 +2195,8 @@ var CmpOps = cmpOpFixups(map[ComparisonOperator]cmpOpOverload{ makeLeFn(types.Float, types.Int, VolatilityLeakProof), makeLeFn(types.Int, types.Decimal, VolatilityLeakProof), makeLeFn(types.Int, types.Float, VolatilityLeakProof), + makeLeFn(types.Int, types.Oid, VolatilityLeakProof), + makeLeFn(types.Oid, types.Int, VolatilityLeakProof), makeLeFn(types.Timestamp, types.Date, VolatilityImmutable), makeLeFn(types.Timestamp, types.TimestampTZ, VolatilityStable), makeLeFn(types.TimestampTZ, types.Date, VolatilityStable), @@ -2255,6 +2261,8 @@ var CmpOps = cmpOpFixups(map[ComparisonOperator]cmpOpOverload{ makeIsFn(types.Float, types.Int, VolatilityLeakProof), makeIsFn(types.Int, types.Decimal, VolatilityLeakProof), makeIsFn(types.Int, types.Float, VolatilityLeakProof), + makeIsFn(types.Int, types.Oid, VolatilityLeakProof), + makeIsFn(types.Oid, types.Int, VolatilityLeakProof), makeIsFn(types.Timestamp, types.Date, VolatilityImmutable), makeIsFn(types.Timestamp, types.TimestampTZ, VolatilityStable), makeIsFn(types.TimestampTZ, types.Date, VolatilityStable), diff --git a/pkg/sql/sem/tree/testdata/eval/oid b/pkg/sql/sem/tree/testdata/eval/oid index 5bfc17f0139a..df7c630a7cb0 100644 --- a/pkg/sql/sem/tree/testdata/eval/oid +++ b/pkg/sql/sem/tree/testdata/eval/oid @@ -12,3 +12,18 @@ eval 3:::REGCLASS ---- 3 + +eval +1:::OID = 1:::INT +---- +true + +eval +1:::OID < 2:::INT2 +---- +true + +eval +1:::OID >= 3:::INT +---- +false