From 2d6f2fba960327d871b244a634e1b8a7c0094061 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Tue, 23 Jan 2018 23:20:02 -0800 Subject: [PATCH] WIP: deduplicate int/float overflow handling code. This is useful to reduce the amount of code generated uselessly when JIT inlining. Author: Andres Freund --- src/backend/utils/adt/float.c | 25 +++++--- src/backend/utils/adt/int8.c | 112 +++++++++++----------------------- 2 files changed, 52 insertions(+), 85 deletions(-) diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 6522c0816e..de2a2e1f54 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -44,20 +44,31 @@ static const uint32 nan[2] = {0xffffffff, 0x7fffffff}; #define NAN (*(const double *) nan) #endif +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) diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index e6bae6860d..a1c058f26d 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. * @@ -521,9 +529,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); } @@ -544,9 +550,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); } @@ -558,9 +562,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); } @@ -572,9 +574,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); } @@ -603,9 +603,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); } @@ -627,9 +625,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); } @@ -682,9 +678,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); } @@ -696,9 +690,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); } @@ -720,9 +712,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 @@ -733,9 +723,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); } @@ -802,9 +790,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); } @@ -816,9 +802,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); } @@ -830,9 +814,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); } @@ -861,9 +843,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); } @@ -883,9 +863,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); } @@ -897,9 +875,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); } @@ -911,9 +887,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); } @@ -944,9 +918,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); } @@ -958,9 +930,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); } @@ -972,9 +942,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); } @@ -1003,9 +971,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); } @@ -1025,9 +991,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); } @@ -1039,9 +1003,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); } @@ -1053,9 +1015,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); } @@ -1213,9 +1173,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; @@ -1248,9 +1206,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); } -- 2.39.5