aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/cash.c
diff options
context:
space:
mode:
authorNathan Bossart <nathan@postgresql.org>2024-08-15 15:47:31 -0500
committerNathan Bossart <nathan@postgresql.org>2024-08-15 15:47:31 -0500
commit9e9a2b7031f64e49fcaf28f21a4e70eb1212165f (patch)
treee7abac509a29b705ad76d8d5123894fe3e1bf3ba /src/backend/utils/adt/cash.c
parentad89d71978429c61647ae57174a61deb192bd51c (diff)
downloadpostgresql-9e9a2b7031f64e49fcaf28f21a4e70eb1212165f.tar.gz
postgresql-9e9a2b7031f64e49fcaf28f21a4e70eb1212165f.zip
Remove dependence on -fwrapv semantics in a few places.
This commit attempts to update a few places, such as the money, numeric, and timestamp types, to no longer rely on signed integer wrapping for correctness. This is intended to move us closer towards removing -fwrapv, which may enable some compiler optimizations. However, there is presently no plan to actually remove that compiler option in the near future. Besides using some of the existing overflow-aware routines in int.h, this commit introduces and makes use of some new ones. Specifically, it adds functions that accept a signed integer and return its absolute value as an unsigned integer with the same width (e.g., pg_abs_s64()). It also adds functions that accept an unsigned integer, store the result of negating that integer in a signed integer with the same width, and return whether the negation overflowed (e.g., pg_neg_u64_overflow()). Finally, this commit adds a couple of tests for timestamps near POSTGRES_EPOCH_JDATE. Author: Joseph Koshakow Reviewed-by: Tom Lane, Heikki Linnakangas, Jian He Discussion: https://postgr.es/m/CAAvxfHdBPOyEGS7s%2Bxf4iaW0-cgiq25jpYdWBqQqvLtLe_t6tw%40mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/cash.c')
-rw-r--r--src/backend/utils/adt/cash.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c
index ec3c08acfc2..c1a743b2a6b 100644
--- a/src/backend/utils/adt/cash.c
+++ b/src/backend/utils/adt/cash.c
@@ -387,6 +387,7 @@ Datum
cash_out(PG_FUNCTION_ARGS)
{
Cash value = PG_GETARG_CASH(0);
+ uint64 uvalue;
char *result;
char buf[128];
char *bufptr;
@@ -429,8 +430,6 @@ cash_out(PG_FUNCTION_ARGS)
if (value < 0)
{
- /* make the amount positive for digit-reconstruction loop */
- value = -value;
/* set up formatting data */
signsymbol = (*lconvert->negative_sign != '\0') ? lconvert->negative_sign : "-";
sign_posn = lconvert->n_sign_posn;
@@ -445,6 +444,9 @@ cash_out(PG_FUNCTION_ARGS)
sep_by_space = lconvert->p_sep_by_space;
}
+ /* make the amount positive for digit-reconstruction loop */
+ uvalue = pg_abs_s64(value);
+
/* we build the digits+decimal-point+sep string right-to-left in buf[] */
bufptr = buf + sizeof(buf) - 1;
*bufptr = '\0';
@@ -470,10 +472,10 @@ cash_out(PG_FUNCTION_ARGS)
memcpy(bufptr, ssymbol, strlen(ssymbol));
}
- *(--bufptr) = ((uint64) value % 10) + '0';
- value = ((uint64) value) / 10;
+ *(--bufptr) = (uvalue % 10) + '0';
+ uvalue = uvalue / 10;
digit_pos--;
- } while (value || digit_pos >= 0);
+ } while (uvalue || digit_pos >= 0);
/*----------
* Now, attach currency symbol and sign symbol in the correct order.