aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/cash.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/cash.c')
-rw-r--r--src/backend/utils/adt/cash.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c
index 7bbc634bd2b..c787dd34191 100644
--- a/src/backend/utils/adt/cash.c
+++ b/src/backend/utils/adt/cash.c
@@ -22,6 +22,7 @@
#include <ctype.h>
#include <math.h>
+#include "common/int.h"
#include "libpq/pqformat.h"
#include "utils/builtins.h"
#include "utils/cash.h"
@@ -199,20 +200,21 @@ cash_in(PG_FUNCTION_ARGS)
for (; *s; s++)
{
- /* we look for digits as long as we have found less */
- /* than the required number of decimal places */
+ /*
+ * We look for digits as long as we have found less than the required
+ * number of decimal places.
+ */
if (isdigit((unsigned char) *s) && (!seen_dot || dec < fpoint))
{
- Cash newvalue = (value * 10) - (*s - '0');
+ int8 digit = *s - '0';
- if (newvalue / 10 != value)
+ if (pg_mul_s64_overflow(value, 10, &value) ||
+ pg_sub_s64_overflow(value, digit, &value))
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("value \"%s\" is out of range for type %s",
str, "money")));
- value = newvalue;
-
if (seen_dot)
dec++;
}
@@ -230,26 +232,23 @@ cash_in(PG_FUNCTION_ARGS)
/* round off if there's another digit */
if (isdigit((unsigned char) *s) && *s >= '5')
- value--; /* remember we build the value in the negative */
-
- if (value > 0)
- ereport(ERROR,
- (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
- errmsg("value \"%s\" is out of range for type %s",
- str, "money")));
+ {
+ /* remember we build the value in the negative */
+ if (pg_sub_s64_overflow(value, 1, &value))
+ ereport(ERROR,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("value \"%s\" is out of range for type %s",
+ str, "money")));
+ }
/* adjust for less than required decimal places */
for (; dec < fpoint; dec++)
{
- Cash newvalue = value * 10;
-
- if (newvalue / 10 != value)
+ if (pg_mul_s64_overflow(value, 10, &value))
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("value \"%s\" is out of range for type %s",
str, "money")));
-
- value = newvalue;
}
/*
@@ -285,12 +284,12 @@ cash_in(PG_FUNCTION_ARGS)
*/
if (sgn > 0)
{
- result = -value;
- if (result < 0)
+ if (value == PG_INT64_MIN)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("value \"%s\" is out of range for type %s",
str, "money")));
+ result = -value;
}
else
result = value;