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
This commit is contained in:
Tom Lane 2022-12-25 14:32:02 -05:00
parent 361ec4368b
commit 442e25d248
3 changed files with 40 additions and 3 deletions

View File

@ -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);
/*

View File

@ -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
--

View File

@ -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
--