diff options
author | Andres Freund | 2018-01-24 07:20:02 +0000 |
---|---|---|
committer | Andres Freund | 2018-01-29 09:44:57 +0000 |
commit | 33a3e51d3d1b887ca61aebd40544ee9f795c0bb0 (patch) | |
tree | 541bc2db03812120c725b85c22b70008be72bd5d | |
parent | 355d8df19883f1ba79ad4c1b776bce8d11f86e16 (diff) |
WIP: deduplicate int/float overflow handling code.
This is useful to reduce the amount of code generated uselessly when
JIT inlining.
Author: Andres Freund
-rw-r--r-- | src/backend/utils/adt/float.c | 26 | ||||
-rw-r--r-- | src/backend/utils/adt/int8.c | 112 |
2 files changed, 53 insertions, 85 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index bc6a3e09b5..d2169c9f68 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -48,20 +48,31 @@ static const uint32 nan[2] = {0xffffffff, 0x7fffffff}; #define MAXFLOATWIDTH 64 #define MAXDOUBLEWIDTH 128 +static void +floaterr(bool is_overflow) +{ + if (is_overflow) + ereport(ERROR, \ + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \ + errmsg("value out of range: overflow"))); \ + else + ereport(ERROR, \ + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \ + errmsg("value out of range: underflow"))); \ +} + +#undef isinf +#define isinf __builtin_isinf + /* * check to see if a float4/8 val has underflowed or overflowed */ #define CHECKFLOATVAL(val, inf_is_valid, zero_is_valid) \ do { \ if (isinf(val) && !(inf_is_valid)) \ - ereport(ERROR, \ - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \ - errmsg("value out of range: overflow"))); \ - \ + floaterr(true); \ if ((val) == 0.0 && !(zero_is_valid)) \ - ereport(ERROR, \ - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \ - errmsg("value out of range: underflow"))); \ + floaterr(false); \ } while(0) @@ -904,6 +915,7 @@ float8mul(PG_FUNCTION_ARGS) CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0 || arg2 == 0); + PG_RETURN_FLOAT8(result); } diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index ae6a4683d4..4f16c10561 100644 --- a/src/backend/utils/adt/int8.c +++ b/src/backend/utils/adt/int8.c @@ -45,6 +45,14 @@ typedef struct * Formatting and conversion routines. *---------------------------------------------------------*/ +static pg_noinline void +overflowerr(void) +{ + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("bigint out of range"))); +} + /* * scanint8 --- try to parse a string into an int8. * @@ -481,9 +489,7 @@ int8um(PG_FUNCTION_ARGS) int64 result; if (unlikely(arg == PG_INT64_MIN)) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); result = -arg; PG_RETURN_INT64(result); } @@ -504,9 +510,7 @@ int8pl(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_add_s64_overflow(arg1, arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -518,9 +522,7 @@ int8mi(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_sub_s64_overflow(arg1, arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -532,9 +534,7 @@ int8mul(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_mul_s64_overflow(arg1, arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -563,9 +563,7 @@ int8div(PG_FUNCTION_ARGS) if (arg2 == -1) { if (unlikely(arg1 == PG_INT64_MIN)) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); result = -arg1; PG_RETURN_INT64(result); } @@ -587,9 +585,7 @@ int8abs(PG_FUNCTION_ARGS) int64 result; if (unlikely(arg1 == PG_INT64_MIN)) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); result = (arg1 < 0) ? -arg1 : arg1; PG_RETURN_INT64(result); } @@ -642,9 +638,7 @@ int8inc(PG_FUNCTION_ARGS) int64 *arg = (int64 *) PG_GETARG_POINTER(0); if (unlikely(pg_add_s64_overflow(*arg, 1, arg))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_POINTER(arg); } @@ -656,9 +650,7 @@ int8inc(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_add_s64_overflow(arg, 1, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -680,9 +672,7 @@ int8dec(PG_FUNCTION_ARGS) int64 *arg = (int64 *) PG_GETARG_POINTER(0); if (unlikely(pg_sub_s64_overflow(*arg, 1, arg))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_POINTER(arg); } else @@ -693,9 +683,7 @@ int8dec(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_sub_s64_overflow(arg, 1, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -762,9 +750,7 @@ int84pl(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_add_s64_overflow(arg1, (int64) arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -776,9 +762,7 @@ int84mi(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_sub_s64_overflow(arg1, (int64) arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -790,9 +774,7 @@ int84mul(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_mul_s64_overflow(arg1, (int64) arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -821,9 +803,7 @@ int84div(PG_FUNCTION_ARGS) if (arg2 == -1) { if (unlikely(arg1 == PG_INT64_MIN)) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); result = -arg1; PG_RETURN_INT64(result); } @@ -843,9 +823,7 @@ int48pl(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_add_s64_overflow((int64) arg1, arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -857,9 +835,7 @@ int48mi(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_sub_s64_overflow((int64) arg1, arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -871,9 +847,7 @@ int48mul(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_mul_s64_overflow((int64) arg1, arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -904,9 +878,7 @@ int82pl(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_add_s64_overflow(arg1, (int64) arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -918,9 +890,7 @@ int82mi(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_sub_s64_overflow(arg1, (int64) arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -932,9 +902,7 @@ int82mul(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_mul_s64_overflow(arg1, (int64) arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -963,9 +931,7 @@ int82div(PG_FUNCTION_ARGS) if (arg2 == -1) { if (unlikely(arg1 == PG_INT64_MIN)) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); result = -arg1; PG_RETURN_INT64(result); } @@ -985,9 +951,7 @@ int28pl(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_add_s64_overflow((int64) arg1, arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -999,9 +963,7 @@ int28mi(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_sub_s64_overflow((int64) arg1, arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -1013,9 +975,7 @@ int28mul(PG_FUNCTION_ARGS) int64 result; if (unlikely(pg_mul_s64_overflow((int64) arg1, arg2, &result))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64(result); } @@ -1173,9 +1133,7 @@ dtoi8(PG_FUNCTION_ARGS) if (unlikely(arg < (double) PG_INT64_MIN) || unlikely(arg > (double) PG_INT64_MAX) || unlikely(isnan(arg))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); result = (int64) arg; @@ -1208,9 +1166,7 @@ ftoi8(PG_FUNCTION_ARGS) if (unlikely(arg < (float4) PG_INT64_MIN) || unlikely(arg > (float4) PG_INT64_MAX) || unlikely(isnan(arg))) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); + overflowerr(); PG_RETURN_INT64((int64) darg); } |