From c671eb6bf8b5d0b12dd9150ec68fd6291a1d23d0 Mon Sep 17 00:00:00 2001 From: Amul Sul Date: Wed, 14 Dec 2022 10:49:53 +0530 Subject: [PATCH v1 15/25] Change oidin and oidvectorin to allow non-throw error reporting --- src/backend/utils/adt/oid.c | 24 ++++++++------- src/test/regress/expected/oid.out | 49 +++++++++++++++++++++++++++++++ src/test/regress/sql/oid.sql | 11 +++++++ 3 files changed, 74 insertions(+), 10 deletions(-) diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c index b5af4223412..0bc2d662258 100644 --- a/src/backend/utils/adt/oid.c +++ b/src/backend/utils/adt/oid.c @@ -19,6 +19,7 @@ #include "catalog/pg_type.h" #include "libpq/pqformat.h" +#include "nodes/miscnodes.h" #include "nodes/value.h" #include "utils/array.h" #include "utils/builtins.h" @@ -32,14 +33,14 @@ *****************************************************************************/ static Oid -oidin_subr(const char *s, char **endloc) +oidin_subr(const char *s, char **endloc, Node *escontext) { unsigned long cvt; char *endptr; Oid result; if (*s == '\0') - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "oid", s))); @@ -53,19 +54,19 @@ oidin_subr(const char *s, char **endloc) * handled by the second "if" consistent across platforms. */ if (errno && errno != ERANGE && errno != EINVAL) - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "oid", s))); if (endptr == s && *s != '\0') - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "oid", s))); if (errno == ERANGE) - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value \"%s\" is out of range for type %s", s, "oid"))); @@ -81,7 +82,7 @@ oidin_subr(const char *s, char **endloc) while (*endptr && isspace((unsigned char) *endptr)) endptr++; if (*endptr) - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", "oid", s))); @@ -104,7 +105,7 @@ oidin_subr(const char *s, char **endloc) #if OID_MAX != ULONG_MAX if (cvt != (unsigned long) result && cvt != (unsigned long) ((int) result)) - ereport(ERROR, + ereturn(escontext, InvalidOid, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("value \"%s\" is out of range for type %s", s, "oid"))); @@ -119,7 +120,7 @@ oidin(PG_FUNCTION_ARGS) char *s = PG_GETARG_CSTRING(0); Oid result; - result = oidin_subr(s, NULL); + result = oidin_subr(s, NULL, fcinfo->context); PG_RETURN_OID(result); } @@ -194,6 +195,7 @@ Datum oidvectorin(PG_FUNCTION_ARGS) { char *oidString = PG_GETARG_CSTRING(0); + Node *escontext = fcinfo->context; oidvector *result; int n; @@ -205,7 +207,9 @@ oidvectorin(PG_FUNCTION_ARGS) oidString++; if (*oidString == '\0') break; - result->values[n] = oidin_subr(oidString, &oidString); + result->values[n] = oidin_subr(oidString, &oidString, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + PG_RETURN_NULL(); } while (*oidString && isspace((unsigned char) *oidString)) oidString++; @@ -324,7 +328,7 @@ oidparse(Node *node) * constants by the lexer. Accept these if they are valid OID * strings. */ - return oidin_subr(castNode(Float, node)->fval, NULL); + return oidin_subr(castNode(Float, node)->fval, NULL, NULL); default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); } diff --git a/src/test/regress/expected/oid.out b/src/test/regress/expected/oid.out index 89093734536..b9687aef00c 100644 --- a/src/test/regress/expected/oid.out +++ b/src/test/regress/expected/oid.out @@ -120,3 +120,52 @@ SELECT o.* FROM OID_TBL o WHERE o.f1 > '1234'; (3 rows) DROP TABLE OID_TBL; +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('01XYZ', 'oid'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('01XYZ', 'oid'); + pg_input_error_message +-------------------------------------------- + invalid input syntax for type oid: "01XYZ" +(1 row) + +SELECT pg_input_is_valid('9999999999', 'oid'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('9999999999', 'oid'); + pg_input_error_message +------------------------------------------------- + value "9999999999" is out of range for type oid +(1 row) + +SELECT pg_input_is_valid('01 01XYZ', 'oidvector'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('01 01XYZ', 'oidvector'); + pg_input_error_message +------------------------------------------ + invalid input syntax for type oid: "XYZ" +(1 row) + +SELECT pg_input_is_valid('01 9999999999', 'oidvector'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('01 9999999999', 'oidvector'); + pg_input_error_message +------------------------------------------------- + value "9999999999" is out of range for type oid +(1 row) + diff --git a/src/test/regress/sql/oid.sql b/src/test/regress/sql/oid.sql index 25b4b68a6a0..8c657908351 100644 --- a/src/test/regress/sql/oid.sql +++ b/src/test/regress/sql/oid.sql @@ -41,3 +41,14 @@ SELECT o.* FROM OID_TBL o WHERE o.f1 >= '1234'; SELECT o.* FROM OID_TBL o WHERE o.f1 > '1234'; DROP TABLE OID_TBL; + +-- test non-error-throwing API for some core types +SELECT pg_input_is_valid('01XYZ', 'oid'); +SELECT pg_input_error_message('01XYZ', 'oid'); +SELECT pg_input_is_valid('9999999999', 'oid'); +SELECT pg_input_error_message('9999999999', 'oid'); + +SELECT pg_input_is_valid('01 01XYZ', 'oidvector'); +SELECT pg_input_error_message('01 01XYZ', 'oidvector'); +SELECT pg_input_is_valid('01 9999999999', 'oidvector'); +SELECT pg_input_error_message('01 9999999999', 'oidvector'); -- 2.18.0