Add new flag to format_type_extended() to get NULL for undefined type
authorMichael Paquier <michael@paquier.xyz>
Mon, 6 Jul 2020 03:12:11 +0000 (12:12 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 6 Jul 2020 03:12:11 +0000 (12:12 +0900)
If a type scanned is undefined, type format routines have two behaviors
depending on if FORMAT_TYPE_ALLOW_INVALID is used by the caller or not:
- Issue a cache lookup error
- Return an undefined type name "???", "???[]" or "-"

The current interface is not really helpful for callers willing to
format properly a type name, but still make sure that the type is
defined as there could be types matching the strings generated when
looking for an undefined type, even if that should not be a problem in
practice.  In order to counter that, add a new flag called
FORMAT_TYPE_INVALID_AS_NULL that returns a NULL result instead of "???
or "-" which does not generate an error.  This flag will be used in a
follow-up patch improving the set of SQL functions showing information
for object addresses when it comes to undefined objects.

Author: Michael Paquier
Reviewed-by: Aleksander Alekseev, Dmitry Dolgov, Daniel Gustafsson,
Álvaro Herrera
Discussion: https://postgr.es/m/CAB7nPqSZxrSmdHK-rny7z8mi=EAFXJ5J-0RbzDw6aus=wB5azQ@mail.gmail.com

src/backend/utils/adt/format_type.c
src/include/utils/builtins.h

index df0bdeb610bb8cdf800df752e6fd58d03f380f45..f2816e4f37f76911bd15ce3ca000cf2c572981df 100644 (file)
@@ -96,13 +96,16 @@ format_type(PG_FUNCTION_ARGS)
  * - FORMAT_TYPE_ALLOW_INVALID
  *         if the type OID is invalid or unknown, return ??? or such instead
  *         of failing
+ * - FORMAT_TYPE_INVALID_AS_NULL
+ *         if the type OID is invalid or unknown, return NULL instead of ???
+ *         or such
  * - FORMAT_TYPE_FORCE_QUALIFY
  *         always schema-qualify type names, regardless of search_path
  *
  * Note that TYPEMOD_GIVEN is not interchangeable with "typemod == -1";
  * see the comments above for format_type().
  *
- * Returns a palloc'd string.
+ * Returns a palloc'd string, or NULL.
  */
 char *
 format_type_extended(Oid type_oid, int32 typemod, bits16 flags)
@@ -114,13 +117,20 @@ format_type_extended(Oid type_oid, int32 typemod, bits16 flags)
    char       *buf;
    bool        with_typemod;
 
-   if (type_oid == InvalidOid && (flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
-       return pstrdup("-");
+   if (type_oid == InvalidOid)
+   {
+       if ((flags & FORMAT_TYPE_INVALID_AS_NULL) != 0)
+           return NULL;
+       else if ((flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
+           return pstrdup("-");
+   }
 
    tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid));
    if (!HeapTupleIsValid(tuple))
    {
-       if ((flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
+       if ((flags & FORMAT_TYPE_INVALID_AS_NULL) != 0)
+           return NULL;
+       else if ((flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
            return pstrdup("???");
        else
            elog(ERROR, "cache lookup failed for type %u", type_oid);
@@ -144,7 +154,9 @@ format_type_extended(Oid type_oid, int32 typemod, bits16 flags)
        tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(array_base_type));
        if (!HeapTupleIsValid(tuple))
        {
-           if ((flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
+           if ((flags & FORMAT_TYPE_INVALID_AS_NULL) != 0)
+               return NULL;
+           else if ((flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
                return pstrdup("???[]");
            else
                elog(ERROR, "cache lookup failed for type %u", type_oid);
index f8595642da9b7d8f5277ef63f8db62e97f397563..3ca5e938f8f82d759d64844134e6d415c66107df 100644 (file)
@@ -113,6 +113,7 @@ extern Datum numeric_float8_no_overflow(PG_FUNCTION_ARGS);
 #define FORMAT_TYPE_TYPEMOD_GIVEN  0x01    /* typemod defined by caller */
 #define FORMAT_TYPE_ALLOW_INVALID  0x02    /* allow invalid types */
 #define FORMAT_TYPE_FORCE_QUALIFY  0x04    /* force qualification of type */
+#define FORMAT_TYPE_INVALID_AS_NULL    0x08    /* NULL if undefined */
 extern char *format_type_extended(Oid type_oid, int32 typemod, bits16 flags);
 
 extern char *format_type_be(Oid type_oid);