1 /**********************************************************************
2 * plperl.c - perl as a procedural language for PostgreSQL
6 * This software is copyrighted by Mark Hollomon
7 * but is shameless cribbed from pltcl.c by Jan Weick.
9 * The author hereby grants permission to use, copy, modify,
10 * distribute, and license this software and its documentation
11 * for any purpose, provided that existing copyright notices are
12 * retained in all copies and that this notice is included
13 * verbatim in any distributions. No written agreement, license,
14 * or royalty fee is required for any of the authorized uses.
15 * Modifications to this software may be copyrighted by their
16 * author and need not follow the licensing terms described
17 * here, provided that the new terms are clearly indicated on
18 * the first page of each file where they apply.
20 * IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY
21 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
22 * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
23 * SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
24 * IF THE AUTHOR HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
27 * THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
28 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
30 * PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
31 * AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE NO
32 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
33 * ENHANCEMENTS, OR MODIFICATIONS.
36 * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.35 2002/09/21 18:39:26 tgl Exp $
38 **********************************************************************/
47 /* postgreSQL stuff */
48 #include "executor/spi.h"
49 #include "commands/trigger.h"
50 #include "utils/elog.h"
52 #include "access/heapam.h"
53 #include "tcop/tcopprot.h"
54 #include "utils/syscache.h"
55 #include "catalog/pg_language.h"
56 #include "catalog/pg_proc.h"
57 #include "catalog/pg_type.h"
65 /* just in case these symbols aren't provided */
72 /**********************************************************************
73 * The information we cache about loaded procedures
74 **********************************************************************/
75 typedef struct plperl_proc_desc
78 TransactionId fn_xmin;
81 FmgrInfo result_in_func;
84 FmgrInfo arg_out_func[FUNC_MAX_ARGS];
85 Oid arg_out_elem[FUNC_MAX_ARGS];
86 int arg_is_rel[FUNC_MAX_ARGS];
91 /**********************************************************************
93 **********************************************************************/
94 static int plperl_firstcall = 1;
95 static int plperl_call_level = 0;
96 static int plperl_restart_in_progress = 0;
97 static PerlInterpreter *plperl_interp = NULL;
98 static HV *plperl_proc_hash = NULL;
100 /**********************************************************************
101 * Forward declarations
102 **********************************************************************/
103 static void plperl_init_all(void);
104 static void plperl_init_interp(void);
106 Datum plperl_call_handler(PG_FUNCTION_ARGS);
108 static Datum plperl_func_handler(PG_FUNCTION_ARGS);
110 static plperl_proc_desc *compile_plperl_function(Oid fn_oid, bool is_trigger);
112 static SV *plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc);
113 static void plperl_init_shared_libs(pTHX);
117 * This routine is a crock, and so is everyplace that calls it. The problem
118 * is that the cached form of plperl functions/queries is allocated permanently
119 * (mostly via malloc()) and never released until backend exit. Subsidiary
120 * data structures such as fmgr info records therefore must live forever
121 * as well. A better implementation would store all this stuff in a per-
122 * function memory context that could be reclaimed at need. In the meantime,
123 * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
124 * it might allocate, and whatever the eventual function might allocate using
125 * fn_mcxt, will live forever too.
128 perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
130 fmgr_info_cxt(functionId, finfo, TopMemoryContext);
133 /**********************************************************************
134 * plperl_init_all() - Initialize all
135 **********************************************************************/
137 plperl_init_all(void)
140 /************************************************************
141 * Do initialization only once
142 ************************************************************/
143 if (!plperl_firstcall)
147 /************************************************************
148 * Destroy the existing Perl interpreter
149 ************************************************************/
150 if (plperl_interp != NULL)
152 perl_destruct(plperl_interp);
153 perl_free(plperl_interp);
154 plperl_interp = NULL;
157 /************************************************************
158 * Free the proc hash table
159 ************************************************************/
160 if (plperl_proc_hash != NULL)
162 hv_undef(plperl_proc_hash);
163 SvREFCNT_dec((SV *) plperl_proc_hash);
164 plperl_proc_hash = NULL;
167 /************************************************************
168 * Now recreate a new Perl interpreter
169 ************************************************************/
170 plperl_init_interp();
172 plperl_firstcall = 0;
176 /**********************************************************************
177 * plperl_init_interp() - Create the Perl interpreter
178 **********************************************************************/
180 plperl_init_interp(void)
183 char *embedding[3] = {
187 * no commas between the next 5 please. They are supposed to be
190 "require Safe; SPI::bootstrap();"
191 "sub ::mksafefunc { my $x = new Safe; $x->permit_only(':default');$x->permit(':base_math');"
192 "$x->share(qw[&elog &DEBUG &LOG &INFO &NOTICE &WARNING &ERROR]);"
193 " return $x->reval(qq[sub { $_[0] }]); }"
194 "sub ::mkunsafefunc {return eval(qq[ sub { $_[0] } ]); }"
197 plperl_interp = perl_alloc();
199 elog(ERROR, "plperl_init_interp(): could not allocate perl interpreter");
201 perl_construct(plperl_interp);
202 perl_parse(plperl_interp, plperl_init_shared_libs, 3, embedding, NULL);
203 perl_run(plperl_interp);
207 /************************************************************
208 * Initialize the proc and query hash tables
209 ************************************************************/
210 plperl_proc_hash = newHV();
216 /**********************************************************************
217 * plperl_call_handler - This is the only visible function
218 * of the PL interpreter. The PostgreSQL
219 * function manager and trigger manager
220 * call this function for execution of
222 **********************************************************************/
223 PG_FUNCTION_INFO_V1(plperl_call_handler);
225 /* keep non-static */
227 plperl_call_handler(PG_FUNCTION_ARGS)
231 /************************************************************
232 * Initialize interpreters on first call
233 ************************************************************/
234 if (plperl_firstcall)
237 /************************************************************
238 * Connect to SPI manager
239 ************************************************************/
240 if (SPI_connect() != SPI_OK_CONNECT)
241 elog(ERROR, "plperl: cannot connect to SPI manager");
242 /************************************************************
243 * Keep track about the nesting of Perl-SPI-Perl-... calls
244 ************************************************************/
247 /************************************************************
248 * Determine if called as function or trigger and
249 * call appropriate subhandler
250 ************************************************************/
251 if (CALLED_AS_TRIGGER(fcinfo))
253 elog(ERROR, "plperl: can't use perl in triggers yet.");
256 * retval = PointerGetDatum(plperl_trigger_handler(fcinfo));
258 /* make the compiler happy */
262 retval = plperl_func_handler(fcinfo);
270 /**********************************************************************
271 * plperl_create_sub() - calls the perl interpreter to
272 * create the anonymous subroutine whose text is in the SV.
273 * Returns the SV containing the RV to the closure.
274 **********************************************************************/
277 plperl_create_sub(char *s, bool trusted)
287 XPUSHs(sv_2mortal(newSVpv(s, 0)));
289 count = perl_call_pv((trusted ? "mksafefunc" : "mkunsafefunc"),
290 G_SCALAR | G_EVAL | G_KEEPERR);
299 elog(ERROR, "creation of function failed: %s", SvPV(ERRSV, PL_na));
303 elog(ERROR, "creation of function failed - no return from mksafefunc");
306 * need to make a deep copy of the return. it comes off the stack as a
309 subref = newSVsv(POPs);
318 * subref is our responsibility because it is not mortal
320 SvREFCNT_dec(subref);
321 elog(ERROR, "plperl_create_sub: didn't get a code ref");
330 /**********************************************************************
331 * plperl_init_shared_libs() -
333 * We cannot use the DynaLoader directly to get at the Opcode
334 * module (used by Safe.pm). So, we link Opcode into ourselves
335 * and do the initialization behind perl's back.
337 **********************************************************************/
339 EXTERN_C void boot_DynaLoader(pTHX_ CV * cv);
340 EXTERN_C void boot_SPI(pTHX_ CV * cv);
343 plperl_init_shared_libs(pTHX)
345 char *file = __FILE__;
347 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
348 newXS("SPI::bootstrap", boot_SPI, file);
351 /**********************************************************************
352 * plperl_call_perl_func() - calls a perl function through the RV
353 * stored in the prodesc structure. massages the input parms properly
354 **********************************************************************/
357 plperl_call_perl_func(plperl_proc_desc * desc, FunctionCallInfo fcinfo)
370 for (i = 0; i < desc->nargs; i++)
372 if (desc->arg_is_rel[i])
374 TupleTableSlot *slot = (TupleTableSlot *) fcinfo->arg[i];
377 Assert(slot != NULL && !fcinfo->argnull[i]);
380 * plperl_build_tuple_argument better return a mortal SV.
382 hashref = plperl_build_tuple_argument(slot->val,
383 slot->ttc_tupleDescriptor);
388 if (fcinfo->argnull[i])
389 XPUSHs(&PL_sv_undef);
394 tmp = DatumGetCString(FunctionCall3(&(desc->arg_out_func[i]),
396 ObjectIdGetDatum(desc->arg_out_elem[i]),
398 XPUSHs(sv_2mortal(newSVpv(tmp, 0)));
404 count = perl_call_sv(desc->reference, G_SCALAR | G_EVAL | G_KEEPERR);
413 elog(ERROR, "plperl: didn't get a return item from function");
422 elog(ERROR, "plperl: error from function: %s", SvPV(ERRSV, PL_na));
425 retval = newSVsv(POPs);
437 /**********************************************************************
438 * plperl_func_handler() - Handler for regular function calls
439 **********************************************************************/
441 plperl_func_handler(PG_FUNCTION_ARGS)
443 plperl_proc_desc *prodesc;
446 sigjmp_buf save_restart;
448 /* Find or compile the function */
449 prodesc = compile_plperl_function(fcinfo->flinfo->fn_oid, false);
451 /* Set up error handling */
452 memcpy(&save_restart, &Warn_restart, sizeof(save_restart));
454 if (sigsetjmp(Warn_restart, 1) != 0)
456 memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
457 plperl_restart_in_progress = 1;
458 if (--plperl_call_level == 0)
459 plperl_restart_in_progress = 0;
460 siglongjmp(Warn_restart, 1);
463 /************************************************************
464 * Call the Perl function
465 ************************************************************/
466 perlret = plperl_call_perl_func(prodesc, fcinfo);
468 /************************************************************
469 * Disconnect from SPI manager and then create the return
470 * values datum (if the input function does a palloc for it
471 * this must not be allocated in the SPI memory context
472 * because SPI_finish would free it).
473 ************************************************************/
474 if (SPI_finish() != SPI_OK_FINISH)
475 elog(ERROR, "plperl: SPI_finish() failed");
477 if (!(perlret && SvOK(perlret)))
479 /* return NULL if Perl code returned undef */
481 fcinfo->isnull = true;
485 retval = FunctionCall3(&prodesc->result_in_func,
486 PointerGetDatum(SvPV(perlret, PL_na)),
487 ObjectIdGetDatum(prodesc->result_in_elem),
491 SvREFCNT_dec(perlret);
493 memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
494 if (plperl_restart_in_progress)
496 if (--plperl_call_level == 0)
497 plperl_restart_in_progress = 0;
498 siglongjmp(Warn_restart, 1);
505 /**********************************************************************
506 * compile_plperl_function - compile (or hopefully just look up) function
507 **********************************************************************/
508 static plperl_proc_desc *
509 compile_plperl_function(Oid fn_oid, bool is_trigger)
512 Form_pg_proc procStruct;
513 char internal_proname[64];
515 plperl_proc_desc *prodesc = NULL;
518 /* We'll need the pg_proc tuple in any case... */
519 procTup = SearchSysCache(PROCOID,
520 ObjectIdGetDatum(fn_oid),
522 if (!HeapTupleIsValid(procTup))
523 elog(ERROR, "plperl: cache lookup for proc %u failed", fn_oid);
524 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
526 /************************************************************
527 * Build our internal proc name from the functions Oid
528 ************************************************************/
530 sprintf(internal_proname, "__PLPerl_proc_%u", fn_oid);
532 sprintf(internal_proname, "__PLPerl_proc_%u_trigger", fn_oid);
533 proname_len = strlen(internal_proname);
535 /************************************************************
536 * Lookup the internal proc name in the hashtable
537 ************************************************************/
538 if (hv_exists(plperl_proc_hash, internal_proname, proname_len))
542 prodesc = (plperl_proc_desc *) SvIV(*hv_fetch(plperl_proc_hash,
543 internal_proname, proname_len, 0));
545 /************************************************************
546 * If it's present, must check whether it's still up to date.
547 * This is needed because CREATE OR REPLACE FUNCTION can modify the
548 * function's pg_proc entry without changing its OID.
549 ************************************************************/
550 uptodate = (prodesc->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
551 prodesc->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data));
555 /* need we delete old entry? */
560 /************************************************************
561 * If we haven't found it in the hashtable, we analyze
562 * the functions arguments and returntype and store
563 * the in-/out-functions in the prodesc block and create
564 * a new hashtable entry for it.
566 * Then we load the procedure into the Perl interpreter.
567 ************************************************************/
572 Form_pg_language langStruct;
573 Form_pg_type typeStruct;
576 /************************************************************
577 * Allocate a new procedure description block
578 ************************************************************/
579 prodesc = (plperl_proc_desc *) malloc(sizeof(plperl_proc_desc));
581 elog(ERROR, "plperl: out of memory");
582 MemSet(prodesc, 0, sizeof(plperl_proc_desc));
583 prodesc->proname = strdup(internal_proname);
584 prodesc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
585 prodesc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
587 /************************************************************
588 * Lookup the pg_language tuple by Oid
589 ************************************************************/
590 langTup = SearchSysCache(LANGOID,
591 ObjectIdGetDatum(procStruct->prolang),
593 if (!HeapTupleIsValid(langTup))
595 free(prodesc->proname);
597 elog(ERROR, "plperl: cache lookup for language %u failed",
598 procStruct->prolang);
600 langStruct = (Form_pg_language) GETSTRUCT(langTup);
601 prodesc->lanpltrusted = langStruct->lanpltrusted;
602 ReleaseSysCache(langTup);
604 /************************************************************
605 * Get the required information for input conversion of the
607 ************************************************************/
610 typeTup = SearchSysCache(TYPEOID,
611 ObjectIdGetDatum(procStruct->prorettype),
613 if (!HeapTupleIsValid(typeTup))
615 free(prodesc->proname);
617 elog(ERROR, "plperl: cache lookup for return type %u failed",
618 procStruct->prorettype);
620 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
622 /* Disallow pseudotype result, except VOID */
623 if (typeStruct->typtype == 'p')
625 if (procStruct->prorettype == VOIDOID)
627 else if (procStruct->prorettype == TRIGGEROID)
629 free(prodesc->proname);
631 elog(ERROR, "plperl functions cannot return type %s"
632 "\n\texcept when used as triggers",
633 format_type_be(procStruct->prorettype));
637 free(prodesc->proname);
639 elog(ERROR, "plperl functions cannot return type %s",
640 format_type_be(procStruct->prorettype));
644 if (typeStruct->typrelid != InvalidOid)
646 free(prodesc->proname);
648 elog(ERROR, "plperl: return types of tuples not supported yet");
651 perm_fmgr_info(typeStruct->typinput, &(prodesc->result_in_func));
652 prodesc->result_in_elem = typeStruct->typelem;
654 ReleaseSysCache(typeTup);
657 /************************************************************
658 * Get the required information for output conversion
659 * of all procedure arguments
660 ************************************************************/
663 prodesc->nargs = procStruct->pronargs;
664 for (i = 0; i < prodesc->nargs; i++)
666 typeTup = SearchSysCache(TYPEOID,
667 ObjectIdGetDatum(procStruct->proargtypes[i]),
669 if (!HeapTupleIsValid(typeTup))
671 free(prodesc->proname);
673 elog(ERROR, "plperl: cache lookup for argument type %u failed",
674 procStruct->proargtypes[i]);
676 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
678 /* Disallow pseudotype argument */
679 if (typeStruct->typtype == 'p')
681 free(prodesc->proname);
683 elog(ERROR, "plperl functions cannot take type %s",
684 format_type_be(procStruct->proargtypes[i]));
687 if (typeStruct->typrelid != InvalidOid)
688 prodesc->arg_is_rel[i] = 1;
690 prodesc->arg_is_rel[i] = 0;
692 perm_fmgr_info(typeStruct->typoutput, &(prodesc->arg_out_func[i]));
693 prodesc->arg_out_elem[i] = typeStruct->typelem;
694 ReleaseSysCache(typeTup);
698 /************************************************************
699 * create the text of the anonymous subroutine.
700 * we do not use a named subroutine so that we can call directly
701 * through the reference.
703 ************************************************************/
704 proc_source = DatumGetCString(DirectFunctionCall1(textout,
705 PointerGetDatum(&procStruct->prosrc)));
707 /************************************************************
708 * Create the procedure in the interpreter
709 ************************************************************/
710 prodesc->reference = plperl_create_sub(proc_source, prodesc->lanpltrusted);
712 if (!prodesc->reference)
714 free(prodesc->proname);
716 elog(ERROR, "plperl: cannot create internal procedure %s",
720 /************************************************************
721 * Add the proc description block to the hashtable
722 ************************************************************/
723 hv_store(plperl_proc_hash, internal_proname, proname_len,
724 newSViv((IV) prodesc), 0);
727 ReleaseSysCache(procTup);
733 /**********************************************************************
734 * plperl_build_tuple_argument() - Build a string for a ref to a hash
735 * from all attributes of a given tuple
736 **********************************************************************/
738 plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
750 output = sv_2mortal(newSVpv("{", 0));
752 for (i = 0; i < tupdesc->natts; i++)
754 /************************************************************
755 * Get the attribute name
756 ************************************************************/
757 attname = tupdesc->attrs[i]->attname.data;
759 /************************************************************
760 * Get the attributes value
761 ************************************************************/
762 attr = heap_getattr(tuple, i + 1, tupdesc, &isnull);
764 /************************************************************
765 * If it is null it will be set to undef in the hash.
766 ************************************************************/
769 sv_catpvf(output, "'%s' => undef,", attname);
773 /************************************************************
774 * Lookup the attribute type in the syscache
775 * for the output function
776 ************************************************************/
777 typeTup = SearchSysCache(TYPEOID,
778 ObjectIdGetDatum(tupdesc->attrs[i]->atttypid),
780 if (!HeapTupleIsValid(typeTup))
781 elog(ERROR, "plperl: Cache lookup for attribute '%s' type %u failed",
782 attname, tupdesc->attrs[i]->atttypid);
784 typoutput = ((Form_pg_type) GETSTRUCT(typeTup))->typoutput;
785 typelem = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
786 ReleaseSysCache(typeTup);
788 /************************************************************
789 * Append the attribute name and the value to the list.
790 ************************************************************/
791 outputstr = DatumGetCString(OidFunctionCall3(typoutput,
793 ObjectIdGetDatum(typelem),
794 Int32GetDatum(tupdesc->attrs[i]->atttypmod)));
795 sv_catpvf(output, "'%s' => '%s',", attname, outputstr);
799 sv_catpv(output, "}");
800 output = perl_eval_pv(SvPV(output, PL_na), TRUE);