Factor out functions responsible for caching I/O routines
authorPeter Eisentraut <peter_e@gmx.net>
Thu, 20 Jan 2011 19:23:27 +0000 (21:23 +0200)
committerPeter Eisentraut <peter_e@gmx.net>
Thu, 20 Jan 2011 19:23:27 +0000 (21:23 +0200)
This makes PLy_procedure_create a bit more manageable.

Jan UrbaƄski

src/pl/plpython/plpython.c

index d083c6e118ec5ff28022aff3091ac6d4ebba50e5..00e3b10ecec9d54dd828eb161c4aec5dfbe95ffc 100644 (file)
@@ -1385,6 +1385,136 @@ PLy_procedure_get(Oid fn_oid, bool is_trigger)
    return entry->proc;
 }
 
+/*
+ * Set up output conversion functions for a procedure
+ */
+static void
+PLy_procedure_output_conversion(PLyProcedure *proc, Form_pg_proc procStruct)
+{
+   HeapTuple   rvTypeTup;
+   Form_pg_type rvTypeStruct;
+
+   /* Get the return type */
+   rvTypeTup = SearchSysCache1(TYPEOID,
+                               ObjectIdGetDatum(procStruct->prorettype));
+   if (!HeapTupleIsValid(rvTypeTup))
+       elog(ERROR, "cache lookup failed for type %u",
+            procStruct->prorettype);
+   rvTypeStruct = (Form_pg_type) GETSTRUCT(rvTypeTup);
+
+   /* Disallow pseudotype result, except for void */
+   if (rvTypeStruct->typtype == TYPTYPE_PSEUDO &&
+       procStruct->prorettype != VOIDOID)
+   {
+       if (procStruct->prorettype == TRIGGEROID)
+           ereport(ERROR,
+                   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                    errmsg("trigger functions can only be called as triggers")));
+       else
+           ereport(ERROR,
+                   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                    errmsg("PL/Python functions cannot return type %s",
+                           format_type_be(procStruct->prorettype))));
+   }
+
+   if (rvTypeStruct->typtype == TYPTYPE_COMPOSITE)
+   {
+       /*
+        * Tuple: set up later, during first call to
+        * PLy_function_handler
+        */
+       proc->result.out.d.typoid = procStruct->prorettype;
+       proc->result.is_rowtype = 2;
+   }
+   else
+   {
+       /* Do the real work */
+       PLy_output_datum_func(&proc->result, rvTypeTup);
+   }
+
+   ReleaseSysCache(rvTypeTup);
+}
+
+/*
+ * Set up output conversion functions for a procedure
+ */
+static void
+PLy_procedure_input_conversion(PLyProcedure *proc, HeapTuple procTup,
+                              Form_pg_proc procStruct)
+{
+   Oid     *types;
+   char    **names,
+           *modes;
+   int     i,
+           pos,
+           total;
+
+   /* Extract argument type info from the pg_proc tuple */
+   total = get_func_arg_info(procTup, &types, &names, &modes);
+
+   /* Count number of in+inout args into proc->nargs */
+   if (modes == NULL)
+       proc->nargs = total;
+   else
+   {
+       /* proc->nargs was initialized to 0 above */
+       for (i = 0; i < total; i++)
+       {
+           if (modes[i] != PROARGMODE_OUT &&
+               modes[i] != PROARGMODE_TABLE)
+               (proc->nargs)++;
+       }
+   }
+
+   proc->argnames = (char **) PLy_malloc0(sizeof(char *) * proc->nargs);
+   for (i = pos = 0; i < total; i++)
+   {
+       HeapTuple   argTypeTup;
+       Form_pg_type argTypeStruct;
+
+       if (modes &&
+           (modes[i] == PROARGMODE_OUT ||
+            modes[i] == PROARGMODE_TABLE))
+           continue;   /* skip OUT arguments */
+
+       Assert(types[i] == procStruct->proargtypes.values[pos]);
+
+       argTypeTup = SearchSysCache1(TYPEOID,
+                                    ObjectIdGetDatum(types[i]));
+       if (!HeapTupleIsValid(argTypeTup))
+           elog(ERROR, "cache lookup failed for type %u", types[i]);
+       argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
+
+       /* Check argument type is OK, set up I/O function info */
+       switch (argTypeStruct->typtype)
+       {
+           case TYPTYPE_PSEUDO:
+               /* Disallow pseudotype argument */
+               ereport(ERROR,
+                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                        errmsg("PL/Python functions cannot accept type %s",
+                               format_type_be(types[i]))));
+               break;
+           case TYPTYPE_COMPOSITE:
+               /* We'll set IO funcs at first call */
+               proc->args[pos].is_rowtype = 2;
+               break;
+           default:
+               PLy_input_datum_func(&(proc->args[pos]),
+                                    types[i],
+                                    argTypeTup);
+               break;
+       }
+
+       /* Get argument name */
+       proc->argnames[pos] = names ? PLy_strdup(names[i]) : NULL;
+
+       ReleaseSysCache(argTypeTup);
+
+       pos++;
+   }
+}
+
 /*
  * Create a new PLyProcedure structure
  */
@@ -1433,46 +1563,7 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
         * but only if this isn't a trigger.
         */
        if (!is_trigger)
-       {
-           HeapTuple   rvTypeTup;
-           Form_pg_type rvTypeStruct;
-
-           rvTypeTup = SearchSysCache1(TYPEOID,
-                                  ObjectIdGetDatum(procStruct->prorettype));
-           if (!HeapTupleIsValid(rvTypeTup))
-               elog(ERROR, "cache lookup failed for type %u",
-                    procStruct->prorettype);
-           rvTypeStruct = (Form_pg_type) GETSTRUCT(rvTypeTup);
-
-           /* Disallow pseudotype result, except for void */
-           if (rvTypeStruct->typtype == TYPTYPE_PSEUDO &&
-               procStruct->prorettype != VOIDOID)
-           {
-               if (procStruct->prorettype == TRIGGEROID)
-                   ereport(ERROR,
-                           (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                            errmsg("trigger functions can only be called as triggers")));
-               else
-                   ereport(ERROR,
-                           (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                         errmsg("PL/Python functions cannot return type %s",
-                                format_type_be(procStruct->prorettype))));
-           }
-
-           if (rvTypeStruct->typtype == TYPTYPE_COMPOSITE)
-           {
-               /*
-                * Tuple: set up later, during first call to
-                * PLy_function_handler
-                */
-               proc->result.out.d.typoid = procStruct->prorettype;
-               proc->result.is_rowtype = 2;
-           }
-           else
-               PLy_output_datum_func(&proc->result, rvTypeTup);
-
-           ReleaseSysCache(rvTypeTup);
-       }
+           PLy_procedure_output_conversion(proc, procStruct);
 
        /*
         * Now get information required for input conversion of the
@@ -1482,79 +1573,7 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
         * arguments.
         */
        if (procStruct->pronargs)
-       {
-           Oid        *types;
-           char      **names,
-                      *modes;
-           int         i,
-                       pos,
-                       total;
-
-           /* extract argument type info from the pg_proc tuple */
-           total = get_func_arg_info(procTup, &types, &names, &modes);
-
-           /* count number of in+inout args into proc->nargs */
-           if (modes == NULL)
-               proc->nargs = total;
-           else
-           {
-               /* proc->nargs was initialized to 0 above */
-               for (i = 0; i < total; i++)
-               {
-                   if (modes[i] != PROARGMODE_OUT &&
-                       modes[i] != PROARGMODE_TABLE)
-                       (proc->nargs)++;
-               }
-           }
-
-           proc->argnames = (char **) PLy_malloc0(sizeof(char *) * proc->nargs);
-           for (i = pos = 0; i < total; i++)
-           {
-               HeapTuple   argTypeTup;
-               Form_pg_type argTypeStruct;
-
-               if (modes &&
-                   (modes[i] == PROARGMODE_OUT ||
-                    modes[i] == PROARGMODE_TABLE))
-                   continue;   /* skip OUT arguments */
-
-               Assert(types[i] == procStruct->proargtypes.values[pos]);
-
-               argTypeTup = SearchSysCache1(TYPEOID,
-                                            ObjectIdGetDatum(types[i]));
-               if (!HeapTupleIsValid(argTypeTup))
-                   elog(ERROR, "cache lookup failed for type %u", types[i]);
-               argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
-
-               /* check argument type is OK, set up I/O function info */
-               switch (argTypeStruct->typtype)
-               {
-                   case TYPTYPE_PSEUDO:
-                       /* Disallow pseudotype argument */
-                       ereport(ERROR,
-                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                         errmsg("PL/Python functions cannot accept type %s",
-                                format_type_be(types[i]))));
-                       break;
-                   case TYPTYPE_COMPOSITE:
-                       /* we'll set IO funcs at first call */
-                       proc->args[pos].is_rowtype = 2;
-                       break;
-                   default:
-                       PLy_input_datum_func(&(proc->args[pos]),
-                                            types[i],
-                                            argTypeTup);
-                       break;
-               }
-
-               /* get argument name */
-               proc->argnames[pos] = names ? PLy_strdup(names[i]) : NULL;
-
-               ReleaseSysCache(argTypeTup);
-
-               pos++;
-           }
-       }
+           PLy_procedure_input_conversion(proc, procTup, procStruct);
 
        /*
         * get the text of the function.