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 Wieck.
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 * $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.95 2005/11/18 17:00:28 adunstan Exp $
38 **********************************************************************/
49 /* postgreSQL stuff */
50 #include "commands/trigger.h"
51 #include "executor/spi.h"
53 #include "utils/lsyscache.h"
54 #include "utils/memutils.h"
55 #include "utils/typcache.h"
56 #include "miscadmin.h"
57 #include "mb/pg_wchar.h"
64 #include "spi_internal.h"
66 /* just in case these symbols aren't provided */
73 /**********************************************************************
74 * The information we cache about loaded procedures
75 **********************************************************************/
76 typedef struct plperl_proc_desc
79 TransactionId fn_xmin;
83 bool fn_retistuple; /* true, if function returns tuple */
84 bool fn_retisset; /* true, if function returns set */
85 bool fn_retisarray; /* true if function returns array */
86 Oid result_oid; /* Oid of result type */
87 FmgrInfo result_in_func; /* I/O function and arg for result type */
88 Oid result_typioparam;
90 FmgrInfo arg_out_func[FUNC_MAX_ARGS];
91 bool arg_is_rowtype[FUNC_MAX_ARGS];
96 /**********************************************************************
98 **********************************************************************/
99 static int plperl_firstcall = 1;
100 static bool plperl_safe_init_done = false;
101 static PerlInterpreter *plperl_interp = NULL;
102 static HV *plperl_proc_hash = NULL;
104 static bool plperl_use_strict = false;
106 /* these are saved and restored by plperl_call_handler */
107 static plperl_proc_desc *plperl_current_prodesc = NULL;
108 static FunctionCallInfo plperl_current_caller_info;
109 static Tuplestorestate *plperl_current_tuple_store;
110 static TupleDesc plperl_current_tuple_desc;
112 /**********************************************************************
113 * Forward declarations
114 **********************************************************************/
115 static void plperl_init_all(void);
116 static void plperl_init_interp(void);
118 Datum plperl_call_handler(PG_FUNCTION_ARGS);
119 Datum plperl_validator(PG_FUNCTION_ARGS);
120 void plperl_init(void);
122 static Datum plperl_func_handler(PG_FUNCTION_ARGS);
124 static Datum plperl_trigger_handler(PG_FUNCTION_ARGS);
125 static plperl_proc_desc *compile_plperl_function(Oid fn_oid, bool is_trigger);
127 static SV *plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc);
128 static void plperl_init_shared_libs(pTHX);
129 static HV *plperl_spi_execute_fetch_result(SPITupleTable *, int, int);
132 * This routine is a crock, and so is everyplace that calls it. The problem
133 * is that the cached form of plperl functions/queries is allocated permanently
134 * (mostly via malloc()) and never released until backend exit. Subsidiary
135 * data structures such as fmgr info records therefore must live forever
136 * as well. A better implementation would store all this stuff in a per-
137 * function memory context that could be reclaimed at need. In the meantime,
138 * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
139 * it might allocate, and whatever the eventual function might allocate using
140 * fn_mcxt, will live forever too.
143 perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
145 fmgr_info_cxt(functionId, finfo, TopMemoryContext);
149 /* Perform initialization during postmaster startup. */
154 if (!plperl_firstcall)
157 DefineCustomBoolVariable(
159 "If true, will compile trusted and untrusted perl code in strict mode",
165 EmitWarningsOnPlaceholders("plperl");
167 plperl_init_interp();
168 plperl_firstcall = 0;
172 /* Perform initialization during backend startup. */
175 plperl_init_all(void)
177 if (plperl_firstcall)
180 /* We don't need to do anything yet when a new backend starts. */
183 /* Each of these macros must represent a single string literal */
186 "SPI::bootstrap(); use vars qw(%_SHARED);" \
187 "sub ::plperl_warn { my $msg = shift; " \
188 " $msg =~ s/\\(eval \\d+\\) //g; &elog(&NOTICE, $msg); } " \
189 "$SIG{__WARN__} = \\&::plperl_warn; " \
190 "sub ::plperl_die { my $msg = shift; " \
191 " $msg =~ s/\\(eval \\d+\\) //g; die $msg; } " \
192 "$SIG{__DIE__} = \\&::plperl_die; " \
193 "sub ::mkunsafefunc {" \
194 " my $ret = eval(qq[ sub { $_[0] $_[1] } ]); " \
195 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }" \
197 "sub ::mk_strict_unsafefunc {" \
198 " my $ret = eval(qq[ sub { use strict; $_[0] $_[1] } ]); " \
199 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; } " \
200 "sub ::_plperl_to_pg_array {" \
201 " my $arg = shift; ref $arg eq 'ARRAY' || return $arg; " \
202 " my $res = ''; my $first = 1; " \
203 " foreach my $elem (@$arg) " \
205 " $res .= ', ' unless $first; $first = undef; " \
208 " $res .= _plperl_to_pg_array($elem); " \
210 " elsif (defined($elem)) " \
212 " my $str = qq($elem); " \
213 " $str =~ s/([\"\\\\])/\\\\$1/g; " \
214 " $res .= qq(\"$str\"); " \
218 " $res .= 'NULL' ; " \
221 " return qq({$res}); " \
224 #define SAFE_MODULE \
225 "require Safe; $Safe::VERSION"
228 "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" \
229 "$PLContainer->permit_only(':default');" \
230 "$PLContainer->permit(qw[:base_math !:base_io sort time]);" \
231 "$PLContainer->share(qw[&elog &spi_exec_query &return_next " \
232 "&spi_query &spi_fetchrow " \
233 "&_plperl_to_pg_array " \
234 "&DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %_SHARED ]);" \
235 "sub ::mksafefunc {" \
236 " my $ret = $PLContainer->reval(qq[sub { $_[0] $_[1] }]); " \
237 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }" \
238 "$PLContainer->permit('require'); $PLContainer->reval('use strict;');" \
239 "$PLContainer->deny('require');" \
240 "sub ::mk_strict_safefunc {" \
241 " my $ret = $PLContainer->reval(qq[sub { BEGIN { strict->import(); } $_[0] $_[1] }]); " \
242 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }"
245 "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" \
246 "$PLContainer->permit_only(':default');" \
247 "$PLContainer->share(qw[&elog &ERROR ]);" \
248 "sub ::mksafefunc { return $PLContainer->reval(qq[sub { " \
249 " elog(ERROR,'trusted Perl functions disabled - " \
250 " please upgrade Perl Safe module to version 2.09 or later');}]); }" \
251 "sub ::mk_strict_safefunc { return $PLContainer->reval(qq[sub { " \
252 " elog(ERROR,'trusted Perl functions disabled - " \
253 " please upgrade Perl Safe module to version 2.09 or later');}]); }"
257 plperl_init_interp(void)
259 static char *embedding[3] = {
263 plperl_interp = perl_alloc();
265 elog(ERROR, "could not allocate Perl interpreter");
267 perl_construct(plperl_interp);
268 perl_parse(plperl_interp, plperl_init_shared_libs, 3, embedding, NULL);
269 perl_run(plperl_interp);
271 plperl_proc_hash = newHV();
276 plperl_safe_init(void)
281 res = eval_pv(SAFE_MODULE, FALSE); /* TRUE = croak if failure */
283 safe_version = SvNV(res);
286 * We actually want to reject safe_version < 2.09, but it's risky to
287 * assume that floating-point comparisons are exact, so use a slightly
288 * smaller comparison value.
290 if (safe_version < 2.0899)
292 /* not safe, so disallow all trusted funcs */
293 eval_pv(SAFE_BAD, FALSE);
297 eval_pv(SAFE_OK, FALSE);
300 plperl_safe_init_done = true;
305 * Perl likes to put a newline after its error messages; clean up such
308 strip_trailing_ws(const char *msg)
310 char *res = pstrdup(msg);
311 int len = strlen(res);
313 while (len > 0 && isspace((unsigned char) res[len - 1]))
319 /* Build a tuple from a hash. */
322 plperl_build_tuple_result(HV * perlhash, AttInMetadata *attinmeta)
324 TupleDesc td = attinmeta->tupdesc;
331 values = (char **) palloc0(td->natts * sizeof(char *));
333 hv_iterinit(perlhash);
334 while ((val = hv_iternextsv(perlhash, &key, &klen)))
336 int attn = SPI_fnumber(td, key);
338 if (attn <= 0 || td->attrs[attn - 1]->attisdropped)
340 (errcode(ERRCODE_UNDEFINED_COLUMN),
341 errmsg("Perl hash contains nonexistent column \"%s\"",
343 if (SvOK(val) && SvTYPE(val) != SVt_NULL)
344 values[attn - 1] = SvPV(val, PL_na);
346 hv_iterinit(perlhash);
348 tup = BuildTupleFromCStrings(attinmeta, values);
354 * convert perl array to postgres string representation
357 plperl_convert_to_pg_array(SV * src)
368 count = call_pv("::_plperl_to_pg_array", G_SCALAR);
373 elog(ERROR, "unexpected _plperl_to_pg_array failure");
383 /* Set up the arguments for a trigger call. */
386 plperl_trigger_build_args(FunctionCallInfo fcinfo)
399 tdata = (TriggerData *) fcinfo->context;
400 tupdesc = tdata->tg_relation->rd_att;
402 relid = DatumGetCString(
403 DirectFunctionCall1(oidout,
404 ObjectIdGetDatum(tdata->tg_relation->rd_id)
408 hv_store(hv, "name", 4, newSVpv(tdata->tg_trigger->tgname, 0), 0);
409 hv_store(hv, "relid", 5, newSVpv(relid, 0), 0);
411 if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
414 if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
415 hv_store(hv, "new", 3,
416 plperl_hash_from_tuple(tdata->tg_trigtuple, tupdesc),
419 else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
422 if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
423 hv_store(hv, "old", 3,
424 plperl_hash_from_tuple(tdata->tg_trigtuple, tupdesc),
427 else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
430 if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
432 hv_store(hv, "old", 3,
433 plperl_hash_from_tuple(tdata->tg_trigtuple, tupdesc),
435 hv_store(hv, "new", 3,
436 plperl_hash_from_tuple(tdata->tg_newtuple, tupdesc),
443 hv_store(hv, "event", 5, newSVpv(event, 0), 0);
444 hv_store(hv, "argc", 4, newSViv(tdata->tg_trigger->tgnargs), 0);
446 if (tdata->tg_trigger->tgnargs > 0)
450 for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
451 av_push(av, newSVpv(tdata->tg_trigger->tgargs[i], 0));
452 hv_store(hv, "args", 4, newRV_noinc((SV *) av), 0);
455 hv_store(hv, "relname", 7,
456 newSVpv(SPI_getrelname(tdata->tg_relation), 0), 0);
458 if (TRIGGER_FIRED_BEFORE(tdata->tg_event))
460 else if (TRIGGER_FIRED_AFTER(tdata->tg_event))
464 hv_store(hv, "when", 4, newSVpv(when, 0), 0);
466 if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
468 else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event))
472 hv_store(hv, "level", 5, newSVpv(level, 0), 0);
474 return newRV_noinc((SV *) hv);
478 /* Set up the new tuple returned from a trigger. */
481 plperl_modify_tuple(HV * hvTD, TriggerData *tdata, HeapTuple otup)
496 tupdesc = tdata->tg_relation->rd_att;
498 svp = hv_fetch(hvTD, "new", 3, FALSE);
501 (errcode(ERRCODE_UNDEFINED_COLUMN),
502 errmsg("$_TD->{new} does not exist")));
503 if (!SvOK(*svp) || SvTYPE(*svp) != SVt_RV || SvTYPE(SvRV(*svp)) != SVt_PVHV)
505 (errcode(ERRCODE_DATATYPE_MISMATCH),
506 errmsg("$_TD->{new} is not a hash reference")));
507 hvNew = (HV *) SvRV(*svp);
509 modattrs = palloc(tupdesc->natts * sizeof(int));
510 modvalues = palloc(tupdesc->natts * sizeof(Datum));
511 modnulls = palloc(tupdesc->natts * sizeof(char));
515 while ((val = hv_iternextsv(hvNew, &key, &klen)))
517 int attn = SPI_fnumber(tupdesc, key);
519 if (attn <= 0 || tupdesc->attrs[attn - 1]->attisdropped)
521 (errcode(ERRCODE_UNDEFINED_COLUMN),
522 errmsg("Perl hash contains nonexistent column \"%s\"",
524 if (SvOK(val) && SvTYPE(val) != SVt_NULL)
530 /* XXX would be better to cache these lookups */
531 getTypeInputInfo(tupdesc->attrs[attn - 1]->atttypid,
532 &typinput, &typioparam);
533 fmgr_info(typinput, &finfo);
534 modvalues[slotsused] = FunctionCall3(&finfo,
535 CStringGetDatum(SvPV(val, PL_na)),
536 ObjectIdGetDatum(typioparam),
537 Int32GetDatum(tupdesc->attrs[attn - 1]->atttypmod));
538 modnulls[slotsused] = ' ';
542 modvalues[slotsused] = (Datum) 0;
543 modnulls[slotsused] = 'n';
545 modattrs[slotsused] = attn;
550 rtup = SPI_modifytuple(tdata->tg_relation, otup, slotsused,
551 modattrs, modvalues, modnulls);
558 elog(ERROR, "SPI_modifytuple failed: %s",
559 SPI_result_code_string(SPI_result));
566 * This is the only externally-visible part of the plperl call interface.
567 * The Postgres function and trigger managers call it to execute a
570 PG_FUNCTION_INFO_V1(plperl_call_handler);
573 plperl_call_handler(PG_FUNCTION_ARGS)
576 plperl_proc_desc *save_prodesc;
577 FunctionCallInfo save_caller_info;
578 Tuplestorestate *save_tuple_store;
579 TupleDesc save_tuple_desc;
583 save_prodesc = plperl_current_prodesc;
584 save_caller_info = plperl_current_caller_info;
585 save_tuple_store = plperl_current_tuple_store;
586 save_tuple_desc = plperl_current_tuple_desc;
590 if (CALLED_AS_TRIGGER(fcinfo))
591 retval = PointerGetDatum(plperl_trigger_handler(fcinfo));
593 retval = plperl_func_handler(fcinfo);
597 plperl_current_prodesc = save_prodesc;
598 plperl_current_caller_info = save_caller_info;
599 plperl_current_tuple_store = save_tuple_store;
600 plperl_current_tuple_desc = save_tuple_desc;
605 plperl_current_prodesc = save_prodesc;
606 plperl_current_caller_info = save_caller_info;
607 plperl_current_tuple_store = save_tuple_store;
608 plperl_current_tuple_desc = save_tuple_desc;
614 * This is the other externally visible function - it is called when CREATE
615 * FUNCTION is issued to validate the function being created/replaced.
617 PG_FUNCTION_INFO_V1(plperl_validator);
620 plperl_validator(PG_FUNCTION_ARGS)
622 Oid funcoid = PG_GETARG_OID(0);
625 bool istrigger = false;
626 plperl_proc_desc *prodesc;
630 /* Get the new function's pg_proc entry */
631 tuple = SearchSysCache(PROCOID,
632 ObjectIdGetDatum(funcoid),
634 if (!HeapTupleIsValid(tuple))
635 elog(ERROR, "cache lookup failed for function %u", funcoid);
636 proc = (Form_pg_proc) GETSTRUCT(tuple);
638 /* we assume OPAQUE with no arguments means a trigger */
639 if (proc->prorettype == TRIGGEROID ||
640 (proc->prorettype == OPAQUEOID && proc->pronargs == 0))
643 ReleaseSysCache(tuple);
645 prodesc = compile_plperl_function(funcoid, istrigger);
647 /* the result of a validator is ignored */
652 /* Uses mksafefunc/mkunsafefunc to create an anonymous sub whose text is
653 * supplied in s, and returns a reference to the closure. */
656 plperl_create_sub(char *s, bool trusted)
663 if (trusted && !plperl_safe_init_done)
672 XPUSHs(sv_2mortal(newSVpv("my $_TD=$_[0]; shift;", 0)));
673 XPUSHs(sv_2mortal(newSVpv(s, 0)));
677 * G_KEEPERR seems to be needed here, else we don't recognize compile
678 * errors properly. Perhaps it's because there's another level of eval
682 if (trusted && plperl_use_strict)
683 compile_sub = "::mk_strict_safefunc";
684 else if (plperl_use_strict)
685 compile_sub = "::mk_strict_unsafefunc";
687 compile_sub = "::mksafefunc";
689 compile_sub = "::mkunsafefunc";
691 count = perl_call_pv(compile_sub, G_SCALAR | G_EVAL | G_KEEPERR);
699 elog(ERROR, "didn't get a return item from mksafefunc");
709 (errcode(ERRCODE_SYNTAX_ERROR),
710 errmsg("creation of Perl function failed: %s",
711 strip_trailing_ws(SvPV(ERRSV, PL_na)))));
715 * need to make a deep copy of the return. it comes off the stack as a
718 subref = newSVsv(POPs);
720 if (!SvROK(subref) || SvTYPE(SvRV(subref)) != SVt_PVCV)
727 * subref is our responsibility because it is not mortal
729 SvREFCNT_dec(subref);
730 elog(ERROR, "didn't get a code ref");
741 /**********************************************************************
742 * plperl_init_shared_libs() -
744 * We cannot use the DynaLoader directly to get at the Opcode
745 * module (used by Safe.pm). So, we link Opcode into ourselves
746 * and do the initialization behind perl's back.
748 **********************************************************************/
750 EXTERN_C void boot_DynaLoader(pTHX_ CV * cv);
751 EXTERN_C void boot_SPI(pTHX_ CV * cv);
754 plperl_init_shared_libs(pTHX)
756 char *file = __FILE__;
758 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
759 newXS("SPI::bootstrap", boot_SPI, file);
764 plperl_call_perl_func(plperl_proc_desc * desc, FunctionCallInfo fcinfo)
777 XPUSHs(&PL_sv_undef); /* no trigger data */
779 for (i = 0; i < desc->nargs; i++)
781 if (fcinfo->argnull[i])
782 XPUSHs(&PL_sv_undef);
783 else if (desc->arg_is_rowtype[i])
789 HeapTupleData tmptup;
792 td = DatumGetHeapTupleHeader(fcinfo->arg[i]);
793 /* Extract rowtype info and find a tupdesc */
794 tupType = HeapTupleHeaderGetTypeId(td);
795 tupTypmod = HeapTupleHeaderGetTypMod(td);
796 tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
797 /* Build a temporary HeapTuple control structure */
798 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
801 hashref = plperl_hash_from_tuple(&tmptup, tupdesc);
802 XPUSHs(sv_2mortal(hashref));
808 tmp = DatumGetCString(FunctionCall1(&(desc->arg_out_func[i]),
810 sv = newSVpv(tmp, 0);
811 #if PERL_BCDVERSION >= 0x5006000L
812 if (GetDatabaseEncoding() == PG_UTF8)
815 XPUSHs(sv_2mortal(sv));
821 /* Do NOT use G_KEEPERR here */
822 count = perl_call_sv(desc->reference, G_SCALAR | G_EVAL);
831 elog(ERROR, "didn't get a return item from function");
840 /* XXX need to find a way to assign an errcode here */
842 (errmsg("error from Perl function: %s",
843 strip_trailing_ws(SvPV(ERRSV, PL_na)))));
846 retval = newSVsv(POPs);
857 plperl_call_perl_trigger_func(plperl_proc_desc * desc, FunctionCallInfo fcinfo,
873 tg_trigger = ((TriggerData *) fcinfo->context)->tg_trigger;
874 for (i = 0; i < tg_trigger->tgnargs; i++)
875 XPUSHs(sv_2mortal(newSVpv(tg_trigger->tgargs[i], 0)));
878 /* Do NOT use G_KEEPERR here */
879 count = perl_call_sv(desc->reference, G_SCALAR | G_EVAL);
888 elog(ERROR, "didn't get a return item from trigger function");
897 /* XXX need to find a way to assign an errcode here */
899 (errmsg("error from Perl trigger function: %s",
900 strip_trailing_ws(SvPV(ERRSV, PL_na)))));
903 retval = newSVsv(POPs);
914 plperl_func_handler(PG_FUNCTION_ARGS)
916 plperl_proc_desc *prodesc;
920 SV *array_ret = NULL;
922 if (SPI_connect() != SPI_OK_CONNECT)
923 elog(ERROR, "could not connect to SPI manager");
925 prodesc = compile_plperl_function(fcinfo->flinfo->fn_oid, false);
927 plperl_current_prodesc = prodesc;
928 plperl_current_caller_info = fcinfo;
929 plperl_current_tuple_store = 0;
930 plperl_current_tuple_desc = 0;
932 rsi = (ReturnSetInfo *) fcinfo->resultinfo;
934 if (prodesc->fn_retisset)
936 /* Check context before allowing the call to go through */
937 if (!rsi || !IsA(rsi, ReturnSetInfo) ||
938 (rsi->allowedModes & SFRM_Materialize) == 0 ||
939 rsi->expectedDesc == NULL)
941 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
942 errmsg("set-valued function called in context that "
943 "cannot accept a set")));
946 perlret = plperl_call_perl_func(prodesc, fcinfo);
948 /************************************************************
949 * Disconnect from SPI manager and then create the return
950 * values datum (if the input function does a palloc for it
951 * this must not be allocated in the SPI memory context
952 * because SPI_finish would free it).
953 ************************************************************/
954 if (SPI_finish() != SPI_OK_FINISH)
955 elog(ERROR, "SPI_finish() failed");
957 if (prodesc->fn_retisset)
960 * If the Perl function returned an arrayref, we pretend that it
961 * called return_next() for each element of the array, to handle old
962 * SRFs that didn't know about return_next(). Any other sort of return
965 if (SvTYPE(perlret) == SVt_RV &&
966 SvTYPE(SvRV(perlret)) == SVt_PVAV)
970 AV *rav = (AV *) SvRV(perlret);
972 while ((svp = av_fetch(rav, i, FALSE)) != NULL)
974 plperl_return_next(*svp);
978 else if (SvTYPE(perlret) != SVt_NULL)
981 (errcode(ERRCODE_DATATYPE_MISMATCH),
982 errmsg("set-returning Perl function must return "
983 "reference to array or use return_next")));
986 rsi->returnMode = SFRM_Materialize;
987 if (plperl_current_tuple_store)
989 rsi->setResult = plperl_current_tuple_store;
990 rsi->setDesc = plperl_current_tuple_desc;
994 else if (SvTYPE(perlret) == SVt_NULL)
996 /* Return NULL if Perl code returned undef */
997 if (rsi && IsA(rsi, ReturnSetInfo))
998 rsi->isDone = ExprEndResult;
999 fcinfo->isnull = true;
1002 else if (prodesc->fn_retistuple)
1004 /* Return a perl hash converted to a Datum */
1006 AttInMetadata *attinmeta;
1009 if (!SvOK(perlret) || SvTYPE(perlret) != SVt_RV ||
1010 SvTYPE(SvRV(perlret)) != SVt_PVHV)
1013 (errcode(ERRCODE_DATATYPE_MISMATCH),
1014 errmsg("composite-returning Perl function "
1015 "must return reference to hash")));
1018 /* XXX should cache the attinmeta data instead of recomputing */
1019 if (get_call_result_type(fcinfo, NULL, &td) != TYPEFUNC_COMPOSITE)
1022 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1023 errmsg("function returning record called in context "
1024 "that cannot accept type record")));
1027 attinmeta = TupleDescGetAttInMetadata(td);
1028 tup = plperl_build_tuple_result((HV *) SvRV(perlret), attinmeta);
1029 retval = HeapTupleGetDatum(tup);
1033 /* Return a perl string converted to a Datum */
1036 if (prodesc->fn_retisarray && SvROK(perlret) &&
1037 SvTYPE(SvRV(perlret)) == SVt_PVAV)
1039 array_ret = plperl_convert_to_pg_array(perlret);
1040 SvREFCNT_dec(perlret);
1041 perlret = array_ret;
1044 val = SvPV(perlret, PL_na);
1046 retval = FunctionCall3(&prodesc->result_in_func,
1047 CStringGetDatum(val),
1048 ObjectIdGetDatum(prodesc->result_typioparam),
1052 if (array_ret == NULL)
1053 SvREFCNT_dec(perlret);
1060 plperl_trigger_handler(PG_FUNCTION_ARGS)
1062 plperl_proc_desc *prodesc;
1068 /* Connect to SPI manager */
1069 if (SPI_connect() != SPI_OK_CONNECT)
1070 elog(ERROR, "could not connect to SPI manager");
1072 /* Find or compile the function */
1073 prodesc = compile_plperl_function(fcinfo->flinfo->fn_oid, true);
1075 plperl_current_prodesc = prodesc;
1077 svTD = plperl_trigger_build_args(fcinfo);
1078 perlret = plperl_call_perl_trigger_func(prodesc, fcinfo, svTD);
1079 hvTD = (HV *) SvRV(svTD);
1081 /************************************************************
1082 * Disconnect from SPI manager and then create the return
1083 * values datum (if the input function does a palloc for it
1084 * this must not be allocated in the SPI memory context
1085 * because SPI_finish would free it).
1086 ************************************************************/
1087 if (SPI_finish() != SPI_OK_FINISH)
1088 elog(ERROR, "SPI_finish() failed");
1090 if (!(perlret && SvOK(perlret) && SvTYPE(perlret) != SVt_NULL))
1092 /* undef result means go ahead with original tuple */
1093 TriggerData *trigdata = ((TriggerData *) fcinfo->context);
1095 if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
1096 retval = (Datum) trigdata->tg_trigtuple;
1097 else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
1098 retval = (Datum) trigdata->tg_newtuple;
1099 else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
1100 retval = (Datum) trigdata->tg_trigtuple;
1102 retval = (Datum) 0; /* can this happen? */
1109 tmp = SvPV(perlret, PL_na);
1111 if (pg_strcasecmp(tmp, "SKIP") == 0)
1113 else if (pg_strcasecmp(tmp, "MODIFY") == 0)
1115 TriggerData *trigdata = (TriggerData *) fcinfo->context;
1117 if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
1118 trv = plperl_modify_tuple(hvTD, trigdata,
1119 trigdata->tg_trigtuple);
1120 else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
1121 trv = plperl_modify_tuple(hvTD, trigdata,
1122 trigdata->tg_newtuple);
1126 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1127 errmsg("ignoring modified tuple in DELETE trigger")));
1134 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1135 errmsg("result of Perl trigger function must be undef, "
1136 "\"SKIP\" or \"MODIFY\"")));
1139 retval = PointerGetDatum(trv);
1144 SvREFCNT_dec(perlret);
1150 static plperl_proc_desc *
1151 compile_plperl_function(Oid fn_oid, bool is_trigger)
1154 Form_pg_proc procStruct;
1155 char internal_proname[64];
1157 plperl_proc_desc *prodesc = NULL;
1161 /* We'll need the pg_proc tuple in any case... */
1162 procTup = SearchSysCache(PROCOID,
1163 ObjectIdGetDatum(fn_oid),
1165 if (!HeapTupleIsValid(procTup))
1166 elog(ERROR, "cache lookup failed for function %u", fn_oid);
1167 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
1169 /************************************************************
1170 * Build our internal proc name from the functions Oid
1171 ************************************************************/
1173 sprintf(internal_proname, "__PLPerl_proc_%u", fn_oid);
1175 sprintf(internal_proname, "__PLPerl_proc_%u_trigger", fn_oid);
1177 proname_len = strlen(internal_proname);
1179 /************************************************************
1180 * Lookup the internal proc name in the hashtable
1181 ************************************************************/
1182 svp = hv_fetch(plperl_proc_hash, internal_proname, proname_len, FALSE);
1187 prodesc = (plperl_proc_desc *) SvIV(*svp);
1189 /************************************************************
1190 * If it's present, must check whether it's still up to date.
1191 * This is needed because CREATE OR REPLACE FUNCTION can modify the
1192 * function's pg_proc entry without changing its OID.
1193 ************************************************************/
1194 uptodate = (prodesc->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
1195 prodesc->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data));
1199 /* need we delete old entry? */
1204 /************************************************************
1205 * If we haven't found it in the hashtable, we analyze
1206 * the functions arguments and returntype and store
1207 * the in-/out-functions in the prodesc block and create
1208 * a new hashtable entry for it.
1210 * Then we load the procedure into the Perl interpreter.
1211 ************************************************************/
1212 if (prodesc == NULL)
1216 Form_pg_language langStruct;
1217 Form_pg_type typeStruct;
1222 /************************************************************
1223 * Allocate a new procedure description block
1224 ************************************************************/
1225 prodesc = (plperl_proc_desc *) malloc(sizeof(plperl_proc_desc));
1226 if (prodesc == NULL)
1228 (errcode(ERRCODE_OUT_OF_MEMORY),
1229 errmsg("out of memory")));
1230 MemSet(prodesc, 0, sizeof(plperl_proc_desc));
1231 prodesc->proname = strdup(internal_proname);
1232 prodesc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
1233 prodesc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
1235 /* Remember if function is STABLE/IMMUTABLE */
1236 prodesc->fn_readonly =
1237 (procStruct->provolatile != PROVOLATILE_VOLATILE);
1239 /************************************************************
1240 * Lookup the pg_language tuple by Oid
1241 ************************************************************/
1242 langTup = SearchSysCache(LANGOID,
1243 ObjectIdGetDatum(procStruct->prolang),
1245 if (!HeapTupleIsValid(langTup))
1247 free(prodesc->proname);
1249 elog(ERROR, "cache lookup failed for language %u",
1250 procStruct->prolang);
1252 langStruct = (Form_pg_language) GETSTRUCT(langTup);
1253 prodesc->lanpltrusted = langStruct->lanpltrusted;
1254 ReleaseSysCache(langTup);
1256 /************************************************************
1257 * Get the required information for input conversion of the
1259 ************************************************************/
1262 typeTup = SearchSysCache(TYPEOID,
1263 ObjectIdGetDatum(procStruct->prorettype),
1265 if (!HeapTupleIsValid(typeTup))
1267 free(prodesc->proname);
1269 elog(ERROR, "cache lookup failed for type %u",
1270 procStruct->prorettype);
1272 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1274 /* Disallow pseudotype result, except VOID or RECORD */
1275 if (typeStruct->typtype == 'p')
1277 if (procStruct->prorettype == VOIDOID ||
1278 procStruct->prorettype == RECORDOID)
1280 else if (procStruct->prorettype == TRIGGEROID)
1282 free(prodesc->proname);
1285 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1286 errmsg("trigger functions may only be called "
1291 free(prodesc->proname);
1294 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1295 errmsg("plperl functions cannot return type %s",
1296 format_type_be(procStruct->prorettype))));
1300 prodesc->result_oid = procStruct->prorettype;
1301 prodesc->fn_retisset = procStruct->proretset;
1302 prodesc->fn_retistuple = (typeStruct->typtype == 'c' ||
1303 procStruct->prorettype == RECORDOID);
1305 prodesc->fn_retisarray =
1306 (typeStruct->typlen == -1 && typeStruct->typelem);
1308 perm_fmgr_info(typeStruct->typinput, &(prodesc->result_in_func));
1309 prodesc->result_typioparam = getTypeIOParam(typeTup);
1311 ReleaseSysCache(typeTup);
1314 /************************************************************
1315 * Get the required information for output conversion
1316 * of all procedure arguments
1317 ************************************************************/
1320 prodesc->nargs = procStruct->pronargs;
1321 for (i = 0; i < prodesc->nargs; i++)
1323 typeTup = SearchSysCache(TYPEOID,
1324 ObjectIdGetDatum(procStruct->proargtypes.values[i]),
1326 if (!HeapTupleIsValid(typeTup))
1328 free(prodesc->proname);
1330 elog(ERROR, "cache lookup failed for type %u",
1331 procStruct->proargtypes.values[i]);
1333 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1335 /* Disallow pseudotype argument */
1336 if (typeStruct->typtype == 'p')
1338 free(prodesc->proname);
1341 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1342 errmsg("plperl functions cannot take type %s",
1343 format_type_be(procStruct->proargtypes.values[i]))));
1346 if (typeStruct->typtype == 'c')
1347 prodesc->arg_is_rowtype[i] = true;
1350 prodesc->arg_is_rowtype[i] = false;
1351 perm_fmgr_info(typeStruct->typoutput,
1352 &(prodesc->arg_out_func[i]));
1355 ReleaseSysCache(typeTup);
1359 /************************************************************
1360 * create the text of the anonymous subroutine.
1361 * we do not use a named subroutine so that we can call directly
1362 * through the reference.
1363 ************************************************************/
1364 prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
1365 Anum_pg_proc_prosrc, &isnull);
1367 elog(ERROR, "null prosrc");
1368 proc_source = DatumGetCString(DirectFunctionCall1(textout,
1371 /************************************************************
1372 * Create the procedure in the interpreter
1373 ************************************************************/
1374 prodesc->reference = plperl_create_sub(proc_source, prodesc->lanpltrusted);
1376 if (!prodesc->reference) /* can this happen? */
1378 free(prodesc->proname);
1380 elog(ERROR, "could not create internal procedure \"%s\"",
1384 hv_store(plperl_proc_hash, internal_proname, proname_len,
1385 newSViv((IV) prodesc), 0);
1388 ReleaseSysCache(procTup);
1394 /* Build a hash from all attributes of a given tuple. */
1397 plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc)
1404 for (i = 0; i < tupdesc->natts; i++)
1415 if (tupdesc->attrs[i]->attisdropped)
1418 attname = NameStr(tupdesc->attrs[i]->attname);
1419 namelen = strlen(attname);
1420 attr = heap_getattr(tuple, i + 1, tupdesc, &isnull);
1424 /* Store (attname => undef) and move on. */
1425 hv_store(hv, attname, namelen, newSV(0), 0);
1429 /* XXX should have a way to cache these lookups */
1431 getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
1432 &typoutput, &typisvarlena);
1434 outputstr = DatumGetCString(OidFunctionCall1(typoutput, attr));
1436 sv = newSVpv(outputstr, 0);
1437 #if PERL_BCDVERSION >= 0x5006000L
1438 if (GetDatabaseEncoding() == PG_UTF8)
1441 hv_store(hv, attname, namelen, sv, 0);
1446 return newRV_noinc((SV *) hv);
1451 plperl_spi_exec(char *query, int limit)
1456 * Execute the query inside a sub-transaction, so we can cope with errors
1459 MemoryContext oldcontext = CurrentMemoryContext;
1460 ResourceOwner oldowner = CurrentResourceOwner;
1462 BeginInternalSubTransaction(NULL);
1463 /* Want to run inside function's memory context */
1464 MemoryContextSwitchTo(oldcontext);
1470 spi_rv = SPI_execute(query, plperl_current_prodesc->fn_readonly,
1472 ret_hv = plperl_spi_execute_fetch_result(SPI_tuptable, SPI_processed,
1475 /* Commit the inner transaction, return to outer xact context */
1476 ReleaseCurrentSubTransaction();
1477 MemoryContextSwitchTo(oldcontext);
1478 CurrentResourceOwner = oldowner;
1481 * AtEOSubXact_SPI() should not have popped any SPI context, but just
1482 * in case it did, make sure we remain connected.
1484 SPI_restore_connection();
1490 /* Save error info */
1491 MemoryContextSwitchTo(oldcontext);
1492 edata = CopyErrorData();
1495 /* Abort the inner transaction */
1496 RollbackAndReleaseCurrentSubTransaction();
1497 MemoryContextSwitchTo(oldcontext);
1498 CurrentResourceOwner = oldowner;
1501 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
1502 * have left us in a disconnected state. We need this hack to return
1503 * to connected state.
1505 SPI_restore_connection();
1507 /* Punt the error to Perl */
1508 croak("%s", edata->message);
1510 /* Can't get here, but keep compiler quiet */
1520 plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed,
1527 hv_store(result, "status", strlen("status"),
1528 newSVpv((char *) SPI_result_code_string(status), 0), 0);
1529 hv_store(result, "processed", strlen("processed"),
1530 newSViv(processed), 0);
1532 if (status == SPI_OK_SELECT)
1539 for (i = 0; i < processed; i++)
1541 row = plperl_hash_from_tuple(tuptable->vals[i], tuptable->tupdesc);
1544 hv_store(result, "rows", strlen("rows"),
1545 newRV_noinc((SV *) rows), 0);
1548 SPI_freetuptable(tuptable);
1555 * Note: plperl_return_next is called both in Postgres and Perl contexts.
1556 * We report any errors in Postgres fashion (via ereport). If called in
1557 * Perl context, it is SPI.xs's responsibility to catch the error and
1558 * convert to a Perl error. We assume (perhaps without adequate justification)
1559 * that we need not abort the current transaction if the Perl code traps the
1563 plperl_return_next(SV *sv)
1565 plperl_proc_desc *prodesc = plperl_current_prodesc;
1566 FunctionCallInfo fcinfo = plperl_current_caller_info;
1567 ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
1575 if (!prodesc->fn_retisset)
1577 (errcode(ERRCODE_SYNTAX_ERROR),
1578 errmsg("cannot use return_next in a non-SETOF function")));
1580 if (prodesc->fn_retistuple &&
1581 !(SvOK(sv) && SvTYPE(sv) == SVt_RV && SvTYPE(SvRV(sv)) == SVt_PVHV))
1583 (errcode(ERRCODE_DATATYPE_MISMATCH),
1584 errmsg("setof-composite-returning Perl function "
1585 "must call return_next with reference to hash")));
1587 cxt = MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);
1589 if (!plperl_current_tuple_store)
1590 plperl_current_tuple_store =
1591 tuplestore_begin_heap(true, false, work_mem);
1593 if (prodesc->fn_retistuple)
1595 TypeFuncClass rettype;
1596 AttInMetadata *attinmeta;
1598 rettype = get_call_result_type(fcinfo, NULL, &tupdesc);
1599 tupdesc = CreateTupleDescCopy(tupdesc);
1600 attinmeta = TupleDescGetAttInMetadata(tupdesc);
1601 tuple = plperl_build_tuple_result((HV *) SvRV(sv), attinmeta);
1608 tupdesc = CreateTupleDescCopy(rsi->expectedDesc);
1610 if (SvOK(sv) && SvTYPE(sv) != SVt_NULL)
1612 char *val = SvPV(sv, PL_na);
1614 ret = FunctionCall3(&prodesc->result_in_func,
1615 PointerGetDatum(val),
1616 ObjectIdGetDatum(prodesc->result_typioparam),
1626 tuple = heap_form_tuple(tupdesc, &ret, &isNull);
1629 if (!plperl_current_tuple_desc)
1630 plperl_current_tuple_desc = tupdesc;
1632 tuplestore_puttuple(plperl_current_tuple_store, tuple);
1633 heap_freetuple(tuple);
1634 MemoryContextSwitchTo(cxt);
1639 plperl_spi_query(char *query)
1644 * Execute the query inside a sub-transaction, so we can cope with errors
1647 MemoryContext oldcontext = CurrentMemoryContext;
1648 ResourceOwner oldowner = CurrentResourceOwner;
1650 BeginInternalSubTransaction(NULL);
1651 /* Want to run inside function's memory context */
1652 MemoryContextSwitchTo(oldcontext);
1657 Portal portal = NULL;
1659 /* Create a cursor for the query */
1660 plan = SPI_prepare(query, 0, NULL);
1662 portal = SPI_cursor_open(NULL, plan, NULL, NULL, false);
1664 cursor = newSVpv(portal->name, 0);
1668 /* Commit the inner transaction, return to outer xact context */
1669 ReleaseCurrentSubTransaction();
1670 MemoryContextSwitchTo(oldcontext);
1671 CurrentResourceOwner = oldowner;
1674 * AtEOSubXact_SPI() should not have popped any SPI context, but just
1675 * in case it did, make sure we remain connected.
1677 SPI_restore_connection();
1683 /* Save error info */
1684 MemoryContextSwitchTo(oldcontext);
1685 edata = CopyErrorData();
1688 /* Abort the inner transaction */
1689 RollbackAndReleaseCurrentSubTransaction();
1690 MemoryContextSwitchTo(oldcontext);
1691 CurrentResourceOwner = oldowner;
1694 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
1695 * have left us in a disconnected state. We need this hack to return
1696 * to connected state.
1698 SPI_restore_connection();
1700 /* Punt the error to Perl */
1701 croak("%s", edata->message);
1703 /* Can't get here, but keep compiler quiet */
1713 plperl_spi_fetchrow(char *cursor)
1718 * Execute the FETCH inside a sub-transaction, so we can cope with errors
1721 MemoryContext oldcontext = CurrentMemoryContext;
1722 ResourceOwner oldowner = CurrentResourceOwner;
1724 BeginInternalSubTransaction(NULL);
1725 /* Want to run inside function's memory context */
1726 MemoryContextSwitchTo(oldcontext);
1730 Portal p = SPI_cursor_find(cursor);
1736 SPI_cursor_fetch(p, true, 1);
1737 if (SPI_processed == 0)
1739 SPI_cursor_close(p);
1744 row = plperl_hash_from_tuple(SPI_tuptable->vals[0],
1745 SPI_tuptable->tupdesc);
1747 SPI_freetuptable(SPI_tuptable);
1750 /* Commit the inner transaction, return to outer xact context */
1751 ReleaseCurrentSubTransaction();
1752 MemoryContextSwitchTo(oldcontext);
1753 CurrentResourceOwner = oldowner;
1756 * AtEOSubXact_SPI() should not have popped any SPI context, but just
1757 * in case it did, make sure we remain connected.
1759 SPI_restore_connection();
1765 /* Save error info */
1766 MemoryContextSwitchTo(oldcontext);
1767 edata = CopyErrorData();
1770 /* Abort the inner transaction */
1771 RollbackAndReleaseCurrentSubTransaction();
1772 MemoryContextSwitchTo(oldcontext);
1773 CurrentResourceOwner = oldowner;
1776 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
1777 * have left us in a disconnected state. We need this hack to return
1778 * to connected state.
1780 SPI_restore_connection();
1782 /* Punt the error to Perl */
1783 croak("%s", edata->message);
1785 /* Can't get here, but keep compiler quiet */