On Fri, Jan 29, 2016 at 3:40 PM, Fabien COELHO <[email protected]> wrote:
>
> I would as well suggest fixing first the (INT64_MAX / -1) crash on HEAD
>> and back-branches with something like the patch attached, inspired from
>> int8.c.
>>
>
> I think it is overkill, but do as you feel.
>
Perhaps we could have Robert decide on this one first? That's a bug after
all that had better be backpatched.
> Note that it must also handle modulo, but the code you suggest cannot be
> used for that.
>
> #include <stdint.h>
> int main(int argc, char* argv[])
> {
> int64_t l = INT64_MIN;
> int64_t r = -1;
> int64_t d = l % r;
> return 0;
> }
> // => Floating point exception (core dumped)
>
Right, forgot this one, we just need to check if rval is -1 here, and
return 0 as result. I am updating the fix as attached.
--
Michael
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index d5f242c..25b349d 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -967,7 +967,28 @@ evaluateExpr(CState *st, PgBenchExpr *expr, int64 *retval)
fprintf(stderr, "division by zero\n");
return false;
}
- *retval = lval / rval;
+ /*
+ * INT64_MIN / -1 is problematic, since the result
+ * can't be represented on a two's-complement
+ * machine. Some machines produce INT64_MIN, some
+ * produce zero, some throw an exception. We can
+ * dodge the problem by recognizing that division
+ * by -1 is the same as negation.
+ */
+ if (rval == -1)
+ {
+ *retval = -lval;
+
+ /* overflow check (needed for INT64_MIN) */
+ if (lval != 0 && (*retval < 0 == lval < 0))
+ {
+ fprintf(stderr, "bigint out of range\n");
+ return false;
+ }
+ }
+ else
+ *retval = lval / rval;
+
return true;
case '%':
@@ -976,7 +997,15 @@ evaluateExpr(CState *st, PgBenchExpr *expr, int64 *retval)
fprintf(stderr, "division by zero\n");
return false;
}
- *retval = lval % rval;
+ /*
+ * Some machines throw a floating-point exception
+ * for INT64_MIN % -1, the correct answer being
+ * zero in any case.
+ */
+ if (rval == -1)
+ *retval = 0;
+ else
+ *retval = lval % rval;
return true;
}
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers