From 442e25d2485b1ecf3357725acee995a1c349163d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 25 Dec 2022 14:32:02 -0500 Subject: [PATCH] Convert enum_in() to report errors softly. I missed this in my initial survey, probably because I examined the contents of pg_type in the postgres database, which lacks any enumerated types. Discussion: https://postgr.es/m/CAAJ_b97KeDWUdpTKGOaFYPv0OicjOu6EW+QYWj-Ywrgj_aEy1g@mail.gmail.com --- src/backend/utils/adt/enum.c | 12 +++++++++--- src/test/regress/expected/enum.out | 25 +++++++++++++++++++++++++ src/test/regress/sql/enum.sql | 6 ++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c index 0cc7a6d8ad..431a89c9ab 100644 --- a/src/backend/utils/adt/enum.c +++ b/src/backend/utils/adt/enum.c @@ -110,12 +110,13 @@ enum_in(PG_FUNCTION_ARGS) { char *name = PG_GETARG_CSTRING(0); Oid enumtypoid = PG_GETARG_OID(1); + Node *escontext = fcinfo->context; Oid enumoid; HeapTuple tup; /* must check length to prevent Assert failure within SearchSysCache */ if (strlen(name) >= NAMEDATALEN) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input value for enum %s: \"%s\"", format_type_be(enumtypoid), @@ -125,13 +126,18 @@ enum_in(PG_FUNCTION_ARGS) ObjectIdGetDatum(enumtypoid), CStringGetDatum(name)); if (!HeapTupleIsValid(tup)) - ereport(ERROR, + ereturn(escontext, (Datum) 0, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input value for enum %s: \"%s\"", format_type_be(enumtypoid), name))); - /* check it's safe to use in SQL */ + /* + * Check it's safe to use in SQL. Perhaps we should take the trouble to + * report "unsafe use" softly; but it's unclear that it's worth the + * trouble, or indeed that that is a legitimate bad-input case at all + * rather than an implementation shortcoming. + */ check_safe_enum_use(tup); /* diff --git a/src/test/regress/expected/enum.out b/src/test/regress/expected/enum.out index 908f67efff..4b45fcf8f0 100644 --- a/src/test/regress/expected/enum.out +++ b/src/test/regress/expected/enum.out @@ -24,6 +24,31 @@ SELECT 'mauve'::rainbow; ERROR: invalid input value for enum rainbow: "mauve" LINE 1: SELECT 'mauve'::rainbow; ^ +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('red', 'rainbow'); + pg_input_is_valid +------------------- + t +(1 row) + +SELECT pg_input_is_valid('mauve', 'rainbow'); + pg_input_is_valid +------------------- + f +(1 row) + +SELECT pg_input_error_message('mauve', 'rainbow'); + pg_input_error_message +----------------------------------------------- + invalid input value for enum rainbow: "mauve" +(1 row) + +SELECT pg_input_error_message(repeat('too_long', 32), 'rainbow'); + pg_input_error_message +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + invalid input value for enum rainbow: "too_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_longtoo_long" +(1 row) + -- -- adding new values -- diff --git a/src/test/regress/sql/enum.sql b/src/test/regress/sql/enum.sql index 6affd0d1eb..c87656589b 100644 --- a/src/test/regress/sql/enum.sql +++ b/src/test/regress/sql/enum.sql @@ -15,6 +15,12 @@ SELECT COUNT(*) FROM pg_enum WHERE enumtypid = 'rainbow'::regtype; SELECT 'red'::rainbow; SELECT 'mauve'::rainbow; +-- Also try it with non-error-throwing API +SELECT pg_input_is_valid('red', 'rainbow'); +SELECT pg_input_is_valid('mauve', 'rainbow'); +SELECT pg_input_error_message('mauve', 'rainbow'); +SELECT pg_input_error_message(repeat('too_long', 32), 'rainbow'); + -- -- adding new values --