Fix plperl validator to honor check_function_bodies: when that is OFF,
authorTom Lane
Wed, 28 Dec 2005 18:34:16 +0000 (18:34 +0000)
committerTom Lane
Wed, 28 Dec 2005 18:34:16 +0000 (18:34 +0000)
we want it to check the argument/result data types and no more.  In
particular, libperl shouldn't get initialized in this case.

src/pl/plperl/plperl.c

index 5cd286bf547e03c8d7f01d5701a080195a70e0e2..70c0ce493a491197f9349d2b0efc6ac0a346b4b3 100644 (file)
@@ -33,7 +33,7 @@
  *   ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.96 2005/11/22 18:17:33 momjian Exp $
+ *   $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.97 2005/12/28 18:34:16 tgl Exp $
  *
  **********************************************************************/
 
@@ -69,6 +69,8 @@
 #define pTHX void
 #endif
 
+extern DLLIMPORT bool check_function_bodies;
+
 
 /**********************************************************************
  * The information we cache about loaded procedures
@@ -622,10 +624,13 @@ plperl_validator(PG_FUNCTION_ARGS)
    Oid         funcoid = PG_GETARG_OID(0);
    HeapTuple   tuple;
    Form_pg_proc proc;
+   char        functyptype;
+   int         numargs;
+   Oid        *argtypes;
+   char      **argnames;
+   char       *argmodes;
    bool        istrigger = false;
-   plperl_proc_desc *prodesc;
-
-   plperl_init_all();
+   int         i;
 
    /* Get the new function's pg_proc entry */
    tuple = SearchSysCache(PROCOID,
@@ -635,14 +640,47 @@ plperl_validator(PG_FUNCTION_ARGS)
        elog(ERROR, "cache lookup failed for function %u", funcoid);
    proc = (Form_pg_proc) GETSTRUCT(tuple);
 
-   /* we assume OPAQUE with no arguments means a trigger */
-   if (proc->prorettype == TRIGGEROID ||
-       (proc->prorettype == OPAQUEOID && proc->pronargs == 0))
-       istrigger = true;
+   functyptype = get_typtype(proc->prorettype);
+
+   /* Disallow pseudotype result */
+   /* except for TRIGGER, RECORD, or VOID */
+   if (functyptype == 'p')
+   {
+       /* we assume OPAQUE with no arguments means a trigger */
+       if (proc->prorettype == TRIGGEROID ||
+           (proc->prorettype == OPAQUEOID && proc->pronargs == 0))
+           istrigger = true;
+       else if (proc->prorettype != RECORDOID &&
+                proc->prorettype != VOIDOID)
+           ereport(ERROR,
+                   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                    errmsg("plperl functions cannot return type %s",
+                           format_type_be(proc->prorettype))));
+   }
+
+   /* Disallow pseudotypes in arguments (either IN or OUT) */
+   numargs = get_func_arg_info(tuple,
+                               &argtypes, &argnames, &argmodes);
+   for (i = 0; i < numargs; i++)
+   {
+       if (get_typtype(argtypes[i]) == 'p')
+           ereport(ERROR,
+                   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                    errmsg("plperl functions cannot take type %s",
+                           format_type_be(argtypes[i]))));
+   }
 
    ReleaseSysCache(tuple);
 
-   prodesc = compile_plperl_function(funcoid, istrigger);
+   /* Postpone body checks if !check_function_bodies */
+   if (check_function_bodies)
+   {
+       plperl_proc_desc *prodesc;
+
+       plperl_init_all();
+
+       prodesc = compile_plperl_function(funcoid, istrigger);
+   }
 
    /* the result of a validator is ignored */
    PG_RETURN_VOID();