Hide internal error for pg_collation_actual_version(<bad OID>).
authorThomas Munro <tmunro@postgresql.org>
Mon, 22 Feb 2021 10:01:20 +0000 (23:01 +1300)
committerThomas Munro <tmunro@postgresql.org>
Mon, 22 Feb 2021 10:01:20 +0000 (23:01 +1300)
Instead of an unsightly internal "cache lookup failed" message, just
return NULL for bad OIDs, as is the convention for other similar things.

Reported-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/20210117215940.GE8560%40telsasoft.com

src/backend/catalog/index.c
src/backend/catalog/pg_depend.c
src/backend/commands/collationcmds.c
src/backend/utils/adt/pg_locale.c
src/include/utils/pg_locale.h
src/test/regress/expected/collate.icu.utf8.out
src/test/regress/sql/collate.icu.utf8.sql

index ea22256819c29cbfe1199fcbf806f35a05f666bd..4ef61b5efd533d2b5cca66e8762f26a96013ab12 100644 (file)
@@ -1290,7 +1290,8 @@ do_collation_version_check(const ObjectAddress *otherObject,
        return false;
 
    /* Ask the provider for the current version.  Give up if unsupported. */
-   current_version = get_collation_version_for_oid(otherObject->objectId);
+   current_version = get_collation_version_for_oid(otherObject->objectId,
+                                                   false);
    if (!current_version)
        return false;
 
@@ -1369,7 +1370,7 @@ do_collation_version_update(const ObjectAddress *otherObject,
    if (OidIsValid(*coll) && otherObject->objectId != *coll)
        return false;
 
-   *new_version = get_collation_version_for_oid(otherObject->objectId);
+   *new_version = get_collation_version_for_oid(otherObject->objectId, false);
 
    return true;
 }
index 63da24322d911b002bc78335ff770961db269ac2..362db7fe913b7f40e2244a19dd4e27af486820f5 100644 (file)
@@ -116,7 +116,8 @@ recordMultipleDependencies(const ObjectAddress *depender,
                    referenced->objectId == POSIX_COLLATION_OID)
                    continue;
 
-               version = get_collation_version_for_oid(referenced->objectId);
+               version = get_collation_version_for_oid(referenced->objectId,
+                                                       false);
 
                /*
                 * Default collation is pinned, so we need to force recording
index 9634ae6809dab4d7c5fca23d69b285d32ed90a22..a7ee452e192eb9968181e89fde12eda21f260d6c 100644 (file)
@@ -273,7 +273,7 @@ pg_collation_actual_version(PG_FUNCTION_ARGS)
    Oid         collid = PG_GETARG_OID(0);
    char       *version;
 
-   version = get_collation_version_for_oid(collid);
+   version = get_collation_version_for_oid(collid, true);
 
    if (version)
        PG_RETURN_TEXT_P(cstring_to_text(version));
index e9c1231f9baeaac51dae1c920ffb85261fefe85d..34b82b9335c65ce7ff0c68b8cfe7db357b0539f1 100644 (file)
@@ -1726,10 +1726,11 @@ get_collation_actual_version(char collprovider, const char *collcollate)
 /*
  * Get provider-specific collation version string for a given collation OID.
  * Return NULL if the provider doesn't support versions, or the collation is
- * unversioned (for example "C").
+ * unversioned (for example "C").  Unknown OIDs result in NULL if missing_ok is
+ * true.
  */
 char *
-get_collation_version_for_oid(Oid oid)
+get_collation_version_for_oid(Oid oid, bool missing_ok)
 {
    HeapTuple   tp;
    char       *version;
@@ -1751,7 +1752,11 @@ get_collation_version_for_oid(Oid oid)
 
        tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(oid));
        if (!HeapTupleIsValid(tp))
+       {
+           if (missing_ok)
+               return NULL;
            elog(ERROR, "cache lookup failed for collation %u", oid);
+       }
        collform = (Form_pg_collation) GETSTRUCT(tp);
        version = get_collation_actual_version(collform->collprovider,
                                               NameStr(collform->collcollate));
index 34dff74bd11b1c71c9194759de9ffe33da19746e..5a37caefbe47a6a56939a05ce00e9d00550c43a7 100644 (file)
@@ -103,7 +103,7 @@ typedef struct pg_locale_struct *pg_locale_t;
 
 extern pg_locale_t pg_newlocale_from_collation(Oid collid);
 
-extern char *get_collation_version_for_oid(Oid collid);
+extern char *get_collation_version_for_oid(Oid collid, bool missing_ok);
 
 #ifdef USE_ICU
 extern int32_t icu_to_uchar(UChar **buff_uchar, const char *buff, size_t nbytes);
index bc3752e92369ca7d40b8645c318a3ccfa32ea9dd..de70cb121274d6a1a9c63f13512c01580c1a8713 100644 (file)
@@ -2155,3 +2155,17 @@ DROP SCHEMA collate_tests CASCADE;
 RESET client_min_messages;
 -- leave a collation for pg_upgrade test
 CREATE COLLATION coll_icu_upgrade FROM "und-x-icu";
+-- Test user-visible function for inspecting versions
+SELECT pg_collation_actual_version('"en-x-icu"'::regcollation) is not null;
+ ?column? 
+----------
+ t
+(1 row)
+
+-- Invalid OIDs are silently ignored
+SELECT pg_collation_actual_version(0) is null;
+ ?column? 
+----------
+ t
+(1 row)
+
index 0de2ed8d8565629e6b2d404fa1862241b1279d12..dd5d208854747bef463fd4db5641832671671da6 100644 (file)
@@ -883,3 +883,8 @@ RESET client_min_messages;
 
 -- leave a collation for pg_upgrade test
 CREATE COLLATION coll_icu_upgrade FROM "und-x-icu";
+
+-- Test user-visible function for inspecting versions
+SELECT pg_collation_actual_version('"en-x-icu"'::regcollation) is not null;
+-- Invalid OIDs are silently ignored
+SELECT pg_collation_actual_version(0) is null;