plperl validator function - Mailing list pgsql-patches

From Andrew Dunstan
Subject plperl validator function
Date
Msg-id 42B8AA65.8010008@dunslane.net
Whole thread Raw
Responses Re: plperl validator function
List pgsql-patches
That attached 2 patches implement a validator function for plperl, and
support for it in createlang.

This has somewhat less utility than do such functions for languages with
stricter compiletime as opposed to runtime requirements, but I still
think it's useful. If this is acceptable I'll provide a regression test
in due course - I don't think any documentation is required.

cheers

andrew
Index: createlang.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/scripts/createlang.c,v
retrieving revision 1.15
diff -c -r1.15 createlang.c
*** createlang.c    31 Dec 2004 22:03:17 -0000    1.15
--- createlang.c    21 Jun 2005 23:49:59 -0000
***************
*** 191,202 ****
--- 191,204 ----
      {
          trusted = true;
          handler = "plperl_call_handler";
+         validator = "plperl_validator";
          object = "plperl";
      }
      else if (strcmp(langname, "plperlu") == 0)
      {
          trusted = false;
          handler = "plperl_call_handler";
+         validator = "plperl_validator";
          object = "plperl";
      }
      else if (strcmp(langname, "plpythonu") == 0)
Index: plperl.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/pl/plperl/plperl.c,v
retrieving revision 1.76
diff -c -r1.76 plperl.c
*** plperl.c    5 Jun 2005 03:16:35 -0000    1.76
--- plperl.c    21 Jun 2005 23:09:48 -0000
***************
*** 113,118 ****
--- 114,120 ----
  static void plperl_init_interp(void);

  Datum        plperl_call_handler(PG_FUNCTION_ARGS);
+ Datum        plperl_validator(PG_FUNCTION_ARGS);
  void        plperl_init(void);

  HV           *plperl_spi_exec(char *query, int limit);
***************
*** 505,511 ****
  }


! /* This is the only externally-visible part of the plperl interface.
   * The Postgres function and trigger managers call it to execute a
   * perl function. */

--- 586,592 ----
  }


! /* This is the only externally-visible part of the plperl call interface.
   * The Postgres function and trigger managers call it to execute a
   * perl function. */

***************
*** 540,545 ****
--- 621,676 ----
      return retval;
  }

+ /*
+  * This is the other externally visible function - it is called when CREATE OR
+  * REPLACE FUNCTION is issued to validate the function being created/replaced.
+  *
+  * Some code copied from plpgsql's validator, but in our case most of the
+  * checking is built into the compile routine, so we need to do less work here.
+  */
+
+ PG_FUNCTION_INFO_V1(plperl_validator);
+
+ Datum
+ plperl_validator(PG_FUNCTION_ARGS)
+ {
+
+     Oid funcoid;
+     HeapTuple   tuple;
+     Form_pg_proc proc;
+     char        functyptype;
+     bool        istrigger = false;
+     plperl_proc_desc *prodesc;
+
+     plperl_init_all();
+
+     funcoid = PG_GETARG_OID(0);
+
+     /* Get the new function's pg_proc entry */
+     tuple = SearchSysCache(PROCOID,
+                            ObjectIdGetDatum(funcoid),
+                            0, 0, 0);
+     if (!HeapTupleIsValid(tuple))
+         elog(ERROR, "cache lookup failed for function %u", funcoid);
+     proc = (Form_pg_proc) GETSTRUCT(tuple);
+
+     functyptype = get_typtype(proc->prorettype);
+
+     if (functyptype == 'p')
+     {
+         /* we assume OPAQUE with no arguments means a trigger */
+         istrigger = (proc->prorettype == TRIGGEROID ||
+                      (proc->prorettype == OPAQUEOID && proc->pronargs == 0));
+     }
+
+     prodesc = compile_plperl_function(funcoid,istrigger);
+
+     ReleaseSysCache(tuple);
+
+     /* the result of a validator is ignored */
+     PG_RETURN_VOID();
+ }
+

  /* Uses mksafefunc/mkunsafefunc to create an anonymous sub whose text is
   * supplied in s, and returns a reference to the closure. */
***************
*** 599,605 ****
       */
      subref = newSVsv(POPs);

!     if (!SvROK(subref))
      {
          PUTBACK;
          FREETMPS;
--- 730,736 ----
       */
      subref = newSVsv(POPs);

!     if (!SvROK(subref) || SvTYPE(SvRV(subref)) != SVt_PVCV)
      {
          PUTBACK;
          FREETMPS;

pgsql-patches by date:

Previous
From: "Magnus Hagander"
Date:
Subject: Removing Kerberos 4
Next
From: Neil Conway
Date:
Subject: Re: Continue stmt for plpgsql