Convert enum_in() to report errors softly.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 25 Dec 2022 19:32:02 +0000 (14:32 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 25 Dec 2022 19:32:30 +0000 (14:32 -0500)
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
src/test/regress/expected/enum.out
src/test/regress/sql/enum.sql

index 0cc7a6d8ad0552bf51c4a2701b7f58fa254493bb..431a89c9ab2548d84aea0bbc908e2df442093314 100644 (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);
 
    /*
index 908f67efffb8a1bc285b222e49fef157669612dd..4b45fcf8f027978967cfc4d752ec1790ac5e039e 100644 (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
 --
index 6affd0d1ebec573a90428950b07ee3044a70551a..c87656589b1251ad3b2582fba34bb7b313de882f 100644 (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
 --