Hi,

The attachment is the proposal patch for function numeric_exp in 
src/backend/utils/adt/numeric.c.


Young
From 0456192bbe03428247b9f55b261b24b4b890c680 Mon Sep 17 00:00:00 2001
From: Young_X <yang...@hotmail.com>
Date: Tue, 9 Oct 2018 10:59:22 +0800
Subject: [PATCH]     Add overflow test in function numeric_exp.     (see
 commit 18a02ad2a506e4425c6dd2ea235039cd5659467d)

Signed-off-by: Young_X <yang...@hotmail.com>
---
 src/backend/utils/adt/numeric.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 444e575..d8c5f54 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -2844,15 +2844,17 @@ numeric_exp(PG_FUNCTION_ARGS)
        /* convert input to float8, ignoring overflow */
        val = numericvar_to_double_no_overflow(&arg);
 
+       /* initial overflow test with fuzz factor */
+       if (Abs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
+               ereport(ERROR,
+                               (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+                               errmsg("value overflows numeric format")));
+
        /*
         * log10(result) = num * log10(e), so this is approximately the decimal
         * weight of the result:
         */
-       val *= 0.434294481903252;
-
-       /* limit to something that won't cause integer overflow */
-       val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
-       val = Min(val, NUMERIC_MAX_RESULT_SCALE);
+       val *= 0.434294481903252;       /* approximate decimal result weight */
 
        rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
        rscale = Max(rscale, arg.dscale);
-- 
2.7.4

Reply via email to