aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2016-02-01 08:23:41 -0500
committerRobert Haas <rhaas@postgresql.org>2016-02-01 08:23:41 -0500
commit64f5edca2401f6c2f23564da9dd52e92d08b3a20 (patch)
tree15b5fa0c34d6b2d3bac61a0a5f61de1b70643a1a
parent89611c4dfa67630f7dcc25881c17cbd1b2e24ea1 (diff)
downloadpostgresql-64f5edca2401f6c2f23564da9dd52e92d08b3a20.tar.gz
postgresql-64f5edca2401f6c2f23564da9dd52e92d08b3a20.zip
pgbench: Install guards against obscure overflow conditions.
Dividing INT_MIN by -1 or taking INT_MIN modulo -1 can sometimes cause floating-point exceptions or otherwise misbehave. Fabien Coelho and Michael Paquier
-rw-r--r--src/bin/pgbench/pgbench.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 44da3d19c19..9bd822299b2 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -1047,7 +1047,29 @@ 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 == PG_INT64_MIN)
+ {
+ fprintf(stderr, "bigint out of range\n");
+ return false;
+ }
+ }
+ else
+ *retval = lval / rval;
+
return true;
case '%':
@@ -1056,7 +1078,17 @@ 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. Dodge that problem by noting that
+ * any value modulo -1 is 0.
+ */
+ if (rval == -1)
+ *retval = 0;
+ else
+ *retval = lval % rval;
+
return true;
}