diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2022-12-09 10:14:53 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2022-12-09 10:14:53 -0500 |
commit | ccff2d20ed9622815df2a7deffce8a7b14830965 (patch) | |
tree | ef8439338d811e3c3b4fd6413f42662c128c70c2 /src/backend/utils/adt/numutils.c | |
parent | 1939d26282b27b4b264c6930830a7991ed83917a (diff) | |
download | postgresql-ccff2d20ed9622815df2a7deffce8a7b14830965.tar.gz postgresql-ccff2d20ed9622815df2a7deffce8a7b14830965.zip |
Convert a few datatype input functions to use "soft" error reporting.
This patch converts the input functions for bool, int2, int4, int8,
float4, float8, numeric, and contrib/cube to the new soft-error style.
array_in and record_in are also converted. There's lots more to do,
but this is enough to provide proof-of-concept that the soft-error
API is usable, as well as reference examples for how to convert
input functions.
This patch is mostly by me, but it owes very substantial debt to
earlier work by Nikita Glukhov, Andrew Dunstan, and Amul Sul.
Thanks to Andres Freund for review.
Discussion: https://postgr.es/m/3bbbb0df-7382-bf87-9737-340ba096e034@postgrespro.ru
Diffstat (limited to 'src/backend/utils/adt/numutils.c')
-rw-r--r-- | src/backend/utils/adt/numutils.c | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/src/backend/utils/adt/numutils.c b/src/backend/utils/adt/numutils.c index a64422c8d06..ab1564f22da 100644 --- a/src/backend/utils/adt/numutils.c +++ b/src/backend/utils/adt/numutils.c @@ -88,9 +88,12 @@ decimalLength64(const uint64 v) /* * Convert input string to a signed 16 bit integer. * - * Allows any number of leading or trailing whitespace characters. Will throw - * ereport() upon bad input format or overflow. + * Allows any number of leading or trailing whitespace characters. * + * pg_strtoint16() will throw ereport() upon bad input format or overflow; + * while pg_strtoint16_safe() instead returns such complaints in *escontext, + * if it's an ErrorSaveContext. +* * NB: Accumulate input as an unsigned number, to deal with two's complement * representation of the most negative number, which can't be represented as a * signed positive number. @@ -98,6 +101,12 @@ decimalLength64(const uint64 v) int16 pg_strtoint16(const char *s) { + return pg_strtoint16_safe(s, NULL); +} + +int16 +pg_strtoint16_safe(const char *s, Node *escontext) +{ const char *ptr = s; uint16 tmp = 0; bool neg = false; @@ -149,25 +158,26 @@ pg_strtoint16(const char *s) return (int16) tmp; out_of_range: - ereport(ERROR, + ereturn(escontext, 0, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value \"%s\" is out of range for type %s", s, "smallint"))); invalid_syntax: - ereport(ERROR, + ereturn(escontext, 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "smallint", s))); - - return 0; /* keep compiler quiet */ } /* * Convert input string to a signed 32 bit integer. * - * Allows any number of leading or trailing whitespace characters. Will throw - * ereport() upon bad input format or overflow. + * Allows any number of leading or trailing whitespace characters. + * + * pg_strtoint32() will throw ereport() upon bad input format or overflow; + * while pg_strtoint32_safe() instead returns such complaints in *escontext, + * if it's an ErrorSaveContext. * * NB: Accumulate input as an unsigned number, to deal with two's complement * representation of the most negative number, which can't be represented as a @@ -176,6 +186,12 @@ invalid_syntax: int32 pg_strtoint32(const char *s) { + return pg_strtoint32_safe(s, NULL); +} + +int32 +pg_strtoint32_safe(const char *s, Node *escontext) +{ const char *ptr = s; uint32 tmp = 0; bool neg = false; @@ -227,25 +243,26 @@ pg_strtoint32(const char *s) return (int32) tmp; out_of_range: - ereport(ERROR, + ereturn(escontext, 0, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value \"%s\" is out of range for type %s", s, "integer"))); invalid_syntax: - ereport(ERROR, + ereturn(escontext, 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "integer", s))); - - return 0; /* keep compiler quiet */ } /* * Convert input string to a signed 64 bit integer. * - * Allows any number of leading or trailing whitespace characters. Will throw - * ereport() upon bad input format or overflow. + * Allows any number of leading or trailing whitespace characters. + * + * pg_strtoint64() will throw ereport() upon bad input format or overflow; + * while pg_strtoint64_safe() instead returns such complaints in *escontext, + * if it's an ErrorSaveContext. * * NB: Accumulate input as an unsigned number, to deal with two's complement * representation of the most negative number, which can't be represented as a @@ -254,6 +271,12 @@ invalid_syntax: int64 pg_strtoint64(const char *s) { + return pg_strtoint64_safe(s, NULL); +} + +int64 +pg_strtoint64_safe(const char *s, Node *escontext) +{ const char *ptr = s; uint64 tmp = 0; bool neg = false; @@ -305,18 +328,16 @@ pg_strtoint64(const char *s) return (int64) tmp; out_of_range: - ereport(ERROR, + ereturn(escontext, 0, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value \"%s\" is out of range for type %s", s, "bigint"))); invalid_syntax: - ereport(ERROR, + ereturn(escontext, 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "bigint", s))); - - return 0; /* keep compiler quiet */ } /* |