Tom Lane wrote:
> {
> int32 arg1 = PG_GETARG_INT32(0);
> int32 arg2 = PG_GETARG_INT32(1);
> + int32 result;
>
> ! result = arg1 * arg2;
> ! /*
> ! * Overflow check. We basically check to see if result / arg2 gives
> ! * arg1 again. There are two cases where this fails: arg2 = 0 (which
> ! * cannot overflow) and arg1 = INT_MIN, arg2 = -1 (where the division
> ! * itself will overflow and thus incorrectly match).
> ! *
> ! * Since the division is likely much more expensive than the actual
> ! * multiplication, we'd like to skip it where possible. The best
> ! * bang for the buck seems to be to check whether both inputs are in
> ! * the int16 range; if so, no overflow is possible.
> ! */
> ! if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
> ! arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
> ! arg2 != 0 &&
> ! (result/arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0)))
> ! ereport(ERROR,
> ! (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
> ! errmsg("integer out of range")));
> ! PG_RETURN_INT32(result);
> }
May be is a good idea postpone the division as second "OR" argument in order to hope to avoid
it.
Regards
Gaetano Mendola