On Fri, Jan 29, 2016 at 3:40 PM, Fabien COELHO <coe...@cri.ensmp.fr> 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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to