From 7d7a23a761e4bdf8d7d6ca0bd3d9c8f08942d84d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 5 Oct 2008 23:18:37 +0000 Subject: [PATCH] Tweak the overflow checks in integer division functions to complain if the machine produces zero (rather than the more usual minimum-possible-integer) for the only possible overflow case. This has been seen to occur for at least some word widths on some hardware, and it's cheap enough to check for everywhere. Per Peter's analysis of buildfarm reports. This could be back-patched, but in the absence of any gripes from the field I doubt it's worth the trouble. --- src/backend/utils/adt/int.c | 15 +++++++++------ src/backend/utils/adt/int8.c | 15 +++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c index b8d78b783d..70c5e75db0 100644 --- a/src/backend/utils/adt/int.c +++ b/src/backend/utils/adt/int.c @@ -735,9 +735,10 @@ int4div(PG_FUNCTION_ARGS) /* * Overflow check. The only possible overflow case is for arg1 = INT_MIN, * arg2 = -1, where the correct result is -INT_MIN, which can't be - * represented on a two's-complement machine. + * represented on a two's-complement machine. Most machines produce + * INT_MIN but it seems some produce zero. */ - if (arg2 == -1 && arg1 < 0 && result < 0) + if (arg2 == -1 && arg1 < 0 && result <= 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); @@ -863,9 +864,10 @@ int2div(PG_FUNCTION_ARGS) /* * Overflow check. The only possible overflow case is for arg1 = * SHRT_MIN, arg2 = -1, where the correct result is -SHRT_MIN, which can't - * be represented on a two's-complement machine. + * be represented on a two's-complement machine. Most machines produce + * SHRT_MIN but it seems some produce zero. */ - if (arg2 == -1 && arg1 < 0 && result < 0) + if (arg2 == -1 && arg1 < 0 && result <= 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range"))); @@ -1041,9 +1043,10 @@ int42div(PG_FUNCTION_ARGS) /* * Overflow check. The only possible overflow case is for arg1 = INT_MIN, * arg2 = -1, where the correct result is -INT_MIN, which can't be - * represented on a two's-complement machine. + * represented on a two's-complement machine. Most machines produce + * INT_MIN but it seems some produce zero. */ - if (arg2 == -1 && arg1 < 0 && result < 0) + if (arg2 == -1 && arg1 < 0 && result <= 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index fa04a29b63..b77830f254 100644 --- a/src/backend/utils/adt/int8.c +++ b/src/backend/utils/adt/int8.c @@ -608,9 +608,10 @@ int8div(PG_FUNCTION_ARGS) /* * Overflow check. The only possible overflow case is for arg1 = * INT64_MIN, arg2 = -1, where the correct result is -INT64_MIN, which - * can't be represented on a two's-complement machine. + * can't be represented on a two's-complement machine. Most machines + * produce INT64_MIN but it seems some produce zero. */ - if (arg2 == -1 && arg1 < 0 && result < 0) + if (arg2 == -1 && arg1 < 0 && result <= 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); @@ -830,9 +831,10 @@ int84div(PG_FUNCTION_ARGS) /* * Overflow check. The only possible overflow case is for arg1 = * INT64_MIN, arg2 = -1, where the correct result is -INT64_MIN, which - * can't be represented on a two's-complement machine. + * can't be represented on a two's-complement machine. Most machines + * produce INT64_MIN but it seems some produce zero. */ - if (arg2 == -1 && arg1 < 0 && result < 0) + if (arg2 == -1 && arg1 < 0 && result <= 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); @@ -1008,9 +1010,10 @@ int82div(PG_FUNCTION_ARGS) /* * Overflow check. The only possible overflow case is for arg1 = * INT64_MIN, arg2 = -1, where the correct result is -INT64_MIN, which - * can't be represented on a two's-complement machine. + * can't be represented on a two's-complement machine. Most machines + * produce INT64_MIN but it seems some produce zero. */ - if (arg2 == -1 && arg1 < 0 && result < 0) + if (arg2 == -1 && arg1 < 0 && result <= 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); -- 2.39.5