From c1b9e1e56d8c11a00869766a02de537d349586cd Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 3 Jan 2024 10:05:35 +0100 Subject: [PATCH] Add numeric_int8_opt_error() to optionally suppress errors This matches the existing numeric_int4_opt_error() (see commit 16d489b0fe). It will be used by a future JSON-related patch, which wants to report errors in its own way and thus does not want the internal functions to throw any error. Author: Jeevan Chalke Discussion: https://www.postgresql.org/message-id/flat/CAM2+6=XjTyqrrqHAOj80r0wVQxJSxc0iyib9bPC55uFO9VKatg@mail.gmail.com --- src/backend/utils/adt/numeric.c | 73 ++++++++++++++++++++++----------- src/include/utils/numeric.h | 1 + 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index bf61fd7dbc0..2a296909492 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -4430,35 +4430,62 @@ int8_numeric(PG_FUNCTION_ARGS) PG_RETURN_NUMERIC(int64_to_numeric(val)); } +int64 +numeric_int8_opt_error(Numeric num, bool *have_error) +{ + NumericVar x; + int64 result; + + if (have_error) + *have_error = false; + + if (NUMERIC_IS_SPECIAL(num)) + { + if (have_error) + { + *have_error = true; + return 0; + } + else + { + if (NUMERIC_IS_NAN(num)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert NaN to %s", "bigint"))); + else + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert infinity to %s", "bigint"))); + } + } + + /* Convert to variable format, then convert to int8 */ + init_var_from_num(num, &x); + + if (!numericvar_to_int64(&x, &result)) + { + if (have_error) + { + *have_error = true; + return 0; + } + else + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("bigint out of range"))); + } + } + + return result; +} Datum numeric_int8(PG_FUNCTION_ARGS) { Numeric num = PG_GETARG_NUMERIC(0); - NumericVar x; - int64 result; - if (NUMERIC_IS_SPECIAL(num)) - { - if (NUMERIC_IS_NAN(num)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert NaN to %s", "bigint"))); - else - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert infinity to %s", "bigint"))); - } - - /* Convert to variable format and thence to int8 */ - init_var_from_num(num, &x); - - if (!numericvar_to_int64(&x, &result)) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("bigint out of range"))); - - PG_RETURN_INT64(result); + PG_RETURN_INT64(numeric_int8_opt_error(num, NULL)); } diff --git a/src/include/utils/numeric.h b/src/include/utils/numeric.h index 08e4f8c217d..0780b52094d 100644 --- a/src/include/utils/numeric.h +++ b/src/include/utils/numeric.h @@ -101,5 +101,6 @@ extern Numeric numeric_div_opt_error(Numeric num1, Numeric num2, extern Numeric numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error); extern int32 numeric_int4_opt_error(Numeric num, bool *have_error); +extern int64 numeric_int8_opt_error(Numeric num, bool *have_error); #endif /* _PG_NUMERIC_H_ */