summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund2018-01-24 07:20:02 +0000
committerAndres Freund2018-01-29 09:44:57 +0000
commit33a3e51d3d1b887ca61aebd40544ee9f795c0bb0 (patch)
tree541bc2db03812120c725b85c22b70008be72bd5d
parent355d8df19883f1ba79ad4c1b776bce8d11f86e16 (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.c26
-rw-r--r--src/backend/utils/adt/int8.c112
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);
}