Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Refactor routines for name lookups of procedures and operators
authorMichael Paquier <michael@paquier.xyz>
Mon, 6 Jul 2020 04:06:08 +0000 (13:06 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 6 Jul 2020 04:06:08 +0000 (13:06 +0900)
This introduces a new set of extended routines for procedure and
operator name lookups, with a flag bitmask argument that can modify the
result.  The following options are available:
- Force schema qualification, ignoring search_path.  This is similar to
the existing option for format_{operator|procedure}_qualified().
- Force NULL as result instead of a numeric OID for an undefined
object.  This option is new.

This is a refactoring similar to 1185c78, that will be used for a future
patch to improve the SQL functions providing information using object
addresses for 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/regproc.c
src/include/utils/regproc.h

index c800d797acc3049fea873e537dbf61c943d4932d..b41189db5c1c69294aae1528186f4e5e80ccce5a 100644 (file)
@@ -41,8 +41,6 @@
 #include "utils/syscache.h"
 #include "utils/varlena.h"
 
-static char *format_operator_internal(Oid operator_oid, bool force_qualify);
-static char *format_procedure_internal(Oid procedure_oid, bool force_qualify);
 static void parseNameAndArgTypes(const char *string, bool allowNone,
                                 List **names, int *nargs, Oid *argtypes);
 
@@ -323,24 +321,32 @@ to_regprocedure(PG_FUNCTION_ARGS)
 char *
 format_procedure(Oid procedure_oid)
 {
-   return format_procedure_internal(procedure_oid, false);
+   return format_procedure_extended(procedure_oid, 0);
 }
 
 char *
 format_procedure_qualified(Oid procedure_oid)
 {
-   return format_procedure_internal(procedure_oid, true);
+   return format_procedure_extended(procedure_oid, FORMAT_PROC_FORCE_QUALIFY);
 }
 
 /*
+ * format_procedure_extended - converts procedure OID to "pro_name(args)"
+ *
+ * This exports the useful functionality of regprocedureout for use
+ * in other backend modules.  The result is a palloc'd string, or NULL.
+ *
  * Routine to produce regprocedure names; see format_procedure above.
  *
- * force_qualify says whether to schema-qualify; if true, the name is always
- * qualified regardless of search_path visibility.  Otherwise the name is only
- * qualified if the function is not in path.
+ * The following bits in 'flags' modify the behavior:
+ * - FORMAT_PROC_INVALID_AS_NULL
+ *         if the procedure OID is invalid or unknown, return NULL instead
+ *         of the numeric OID.
+ * - FORMAT_PROC_FORCE_QUALIFY
+ *         always schema-qualify procedure names, regardless of search_path
  */
-static char *
-format_procedure_internal(Oid procedure_oid, bool force_qualify)
+char *
+format_procedure_extended(Oid procedure_oid, bits16 flags)
 {
    char       *result;
    HeapTuple   proctup;
@@ -365,7 +371,8 @@ format_procedure_internal(Oid procedure_oid, bool force_qualify)
         * Would this proc be found (given the right args) by regprocedurein?
         * If not, or if caller requests it, we need to qualify it.
         */
-       if (!force_qualify && FunctionIsVisible(procedure_oid))
+       if ((flags & FORMAT_PROC_FORCE_QUALIFY) == 0 &&
+           FunctionIsVisible(procedure_oid))
            nspname = NULL;
        else
            nspname = get_namespace_name(procform->pronamespace);
@@ -379,7 +386,7 @@ format_procedure_internal(Oid procedure_oid, bool force_qualify)
            if (i > 0)
                appendStringInfoChar(&buf, ',');
            appendStringInfoString(&buf,
-                                  force_qualify ?
+                                  (flags & FORMAT_PROC_FORCE_QUALIFY) != 0 ?
                                   format_type_be_qualified(thisargtype) :
                                   format_type_be(thisargtype));
        }
@@ -389,6 +396,11 @@ format_procedure_internal(Oid procedure_oid, bool force_qualify)
 
        ReleaseSysCache(proctup);
    }
+   else if ((flags & FORMAT_PROC_INVALID_AS_NULL) != 0)
+   {
+       /* If object is undefined, return NULL as wanted by caller */
+       result = NULL;
+   }
    else
    {
        /* If OID doesn't match any pg_proc entry, return it numerically */
@@ -747,13 +759,20 @@ to_regoperator(PG_FUNCTION_ARGS)
 }
 
 /*
- * format_operator     - converts operator OID to "opr_name(args)"
+ * format_operator_extended - converts operator OID to "opr_name(args)"
  *
  * This exports the useful functionality of regoperatorout for use
- * in other backend modules.  The result is a palloc'd string.
+ * in other backend modules.  The result is a palloc'd string, or NULL.
+ *
+ * The following bits in 'flags' modify the behavior:
+ * - FORMAT_OPERATOR_INVALID_AS_NULL
+ *         if the operator OID is invalid or unknown, return NULL instead
+ *         of the numeric OID.
+ * - FORMAT_OPERATOR_FORCE_QUALIFY
+ *         always schema-qualify operator names, regardless of search_path
  */
-static char *
-format_operator_internal(Oid operator_oid, bool force_qualify)
+char *
+format_operator_extended(Oid operator_oid, bits16 flags)
 {
    char       *result;
    HeapTuple   opertup;
@@ -776,7 +795,8 @@ format_operator_internal(Oid operator_oid, bool force_qualify)
         * Would this oper be found (given the right args) by regoperatorin?
         * If not, or if caller explicitly requests it, we need to qualify it.
         */
-       if (force_qualify || !OperatorIsVisible(operator_oid))
+       if ((flags & FORMAT_OPERATOR_FORCE_QUALIFY) != 0 ||
+           !OperatorIsVisible(operator_oid))
        {
            nspname = get_namespace_name(operform->oprnamespace);
            appendStringInfo(&buf, "%s.",
@@ -787,7 +807,7 @@ format_operator_internal(Oid operator_oid, bool force_qualify)
 
        if (operform->oprleft)
            appendStringInfo(&buf, "%s,",
-                            force_qualify ?
+                            (flags & FORMAT_OPERATOR_FORCE_QUALIFY) != 0 ?
                             format_type_be_qualified(operform->oprleft) :
                             format_type_be(operform->oprleft));
        else
@@ -795,7 +815,7 @@ format_operator_internal(Oid operator_oid, bool force_qualify)
 
        if (operform->oprright)
            appendStringInfo(&buf, "%s)",
-                            force_qualify ?
+                            (flags & FORMAT_OPERATOR_FORCE_QUALIFY) != 0 ?
                             format_type_be_qualified(operform->oprright) :
                             format_type_be(operform->oprright));
        else
@@ -805,6 +825,11 @@ format_operator_internal(Oid operator_oid, bool force_qualify)
 
        ReleaseSysCache(opertup);
    }
+   else if ((flags & FORMAT_OPERATOR_INVALID_AS_NULL) != 0)
+   {
+       /* If object is undefined, return NULL as wanted by caller */
+       result = NULL;
+   }
    else
    {
        /*
@@ -820,13 +845,14 @@ format_operator_internal(Oid operator_oid, bool force_qualify)
 char *
 format_operator(Oid operator_oid)
 {
-   return format_operator_internal(operator_oid, false);
+   return format_operator_extended(operator_oid, 0);
 }
 
 char *
 format_operator_qualified(Oid operator_oid)
 {
-   return format_operator_internal(operator_oid, true);
+   return format_operator_extended(operator_oid,
+                                   FORMAT_OPERATOR_FORCE_QUALIFY);
 }
 
 void
index 383dfe641e412f8de20e6af88a6a1822653db330..145452a5ad71cc86b99e7adcb7a35fef0bad3f38 100644 (file)
 
 #include "nodes/pg_list.h"
 
+/* Control flags for format_procedure_extended */
+#define FORMAT_PROC_INVALID_AS_NULL    0x01    /* NULL if undefined */
+#define FORMAT_PROC_FORCE_QUALIFY  0x02    /* force qualification */
+extern char *format_procedure_extended(Oid procedure_oid, bits16 flags);
+
+/* Control flags for format_operator_extended */
+#define FORMAT_OPERATOR_INVALID_AS_NULL    0x01    /* NULL if undefined */
+#define FORMAT_OPERATOR_FORCE_QUALIFY  0x02    /* force qualification */
+extern char *format_operator_extended(Oid operator_oid, bits16 flags);
+
 extern List *stringToQualifiedNameList(const char *string);
 extern char *format_procedure(Oid procedure_oid);
 extern char *format_procedure_qualified(Oid procedure_oid);