1 /**********************************************************************
2 * plperl.c - perl as a procedural language for PostgreSQL
6 * This software is copyrighted by Mark Hollomon
7 * but is shamelessly 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.104 2006/03/05 16:40:51 adunstan Exp $
38 **********************************************************************/
50 /* postgreSQL stuff */
51 #include "commands/trigger.h"
52 #include "executor/spi.h"
54 #include "utils/lsyscache.h"
55 #include "utils/memutils.h"
56 #include "utils/typcache.h"
57 #include "miscadmin.h"
58 #include "mb/pg_wchar.h"
59 #include "parser/parse_type.h"
61 /* define this before the perl headers get a chance to mangle DLLIMPORT */
62 extern DLLIMPORT bool check_function_bodies;
67 /**********************************************************************
68 * The information we cache about loaded procedures
69 **********************************************************************/
70 typedef struct plperl_proc_desc
73 TransactionId fn_xmin;
77 bool fn_retistuple; /* true, if function returns tuple */
78 bool fn_retisset; /* true, if function returns set */
79 bool fn_retisarray; /* true if function returns array */
80 Oid result_oid; /* Oid of result type */
81 FmgrInfo result_in_func; /* I/O function and arg for result type */
82 Oid result_typioparam;
84 FmgrInfo arg_out_func[FUNC_MAX_ARGS];
85 bool arg_is_rowtype[FUNC_MAX_ARGS];
90 * The information we cache for the duration of a single call to a
93 typedef struct plperl_call_data
95 plperl_proc_desc *prodesc;
96 FunctionCallInfo fcinfo;
97 Tuplestorestate *tuple_store;
99 AttInMetadata *attinmeta;
100 MemoryContext tmp_cxt;
103 /**********************************************************************
104 * The information we cache about prepared and saved plans
105 **********************************************************************/
106 typedef struct plperl_query_desc
108 char qname[sizeof(long) * 2 + 1];
112 FmgrInfo *arginfuncs;
116 /**********************************************************************
118 **********************************************************************/
119 static bool plperl_firstcall = true;
120 static bool plperl_safe_init_done = false;
121 static PerlInterpreter *plperl_interp = NULL;
122 static HV *plperl_proc_hash = NULL;
123 static HV *plperl_query_hash = NULL;
125 static bool plperl_use_strict = false;
127 /* this is saved and restored by plperl_call_handler */
128 static plperl_call_data *current_call_data = NULL;
130 /**********************************************************************
131 * Forward declarations
132 **********************************************************************/
133 static void plperl_init_all(void);
134 static void plperl_init_interp(void);
136 Datum plperl_call_handler(PG_FUNCTION_ARGS);
137 Datum plperl_validator(PG_FUNCTION_ARGS);
138 void plperl_init(void);
140 static Datum plperl_func_handler(PG_FUNCTION_ARGS);
142 static Datum plperl_trigger_handler(PG_FUNCTION_ARGS);
143 static plperl_proc_desc *compile_plperl_function(Oid fn_oid, bool is_trigger);
145 static SV *plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc);
146 static void plperl_init_shared_libs(pTHX);
147 static HV *plperl_spi_execute_fetch_result(SPITupleTable *, int, int);
150 * This routine is a crock, and so is everyplace that calls it. The problem
151 * is that the cached form of plperl functions/queries is allocated permanently
152 * (mostly via malloc()) and never released until backend exit. Subsidiary
153 * data structures such as fmgr info records therefore must live forever
154 * as well. A better implementation would store all this stuff in a per-
155 * function memory context that could be reclaimed at need. In the meantime,
156 * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
157 * it might allocate, and whatever the eventual function might allocate using
158 * fn_mcxt, will live forever too.
161 perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
163 fmgr_info_cxt(functionId, finfo, TopMemoryContext);
167 /* Perform initialization during postmaster startup. */
172 if (!plperl_firstcall)
175 DefineCustomBoolVariable(
177 "If true, will compile trusted and untrusted perl code in strict mode",
183 EmitWarningsOnPlaceholders("plperl");
185 plperl_init_interp();
186 plperl_firstcall = false;
190 /* Perform initialization during backend startup. */
193 plperl_init_all(void)
195 if (plperl_firstcall)
198 /* We don't need to do anything yet when a new backend starts. */
201 /* Each of these macros must represent a single string literal */
204 "SPI::bootstrap(); use vars qw(%_SHARED);" \
205 "sub ::plperl_warn { my $msg = shift; " \
206 " $msg =~ s/\\(eval \\d+\\) //g; &elog(&NOTICE, $msg); } " \
207 "$SIG{__WARN__} = \\&::plperl_warn; " \
208 "sub ::plperl_die { my $msg = shift; " \
209 " $msg =~ s/\\(eval \\d+\\) //g; die $msg; } " \
210 "$SIG{__DIE__} = \\&::plperl_die; " \
211 "sub ::mkunsafefunc {" \
212 " my $ret = eval(qq[ sub { $_[0] $_[1] } ]); " \
213 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }" \
215 "sub ::mk_strict_unsafefunc {" \
216 " my $ret = eval(qq[ sub { use strict; $_[0] $_[1] } ]); " \
217 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; } " \
218 "sub ::_plperl_to_pg_array {" \
219 " my $arg = shift; ref $arg eq 'ARRAY' || return $arg; " \
220 " my $res = ''; my $first = 1; " \
221 " foreach my $elem (@$arg) " \
223 " $res .= ', ' unless $first; $first = undef; " \
226 " $res .= _plperl_to_pg_array($elem); " \
228 " elsif (defined($elem)) " \
230 " my $str = qq($elem); " \
231 " $str =~ s/([\"\\\\])/\\\\$1/g; " \
232 " $res .= qq(\"$str\"); " \
236 " $res .= 'NULL' ; " \
239 " return qq({$res}); " \
242 #define SAFE_MODULE \
243 "require Safe; $Safe::VERSION"
246 "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" \
247 "$PLContainer->permit_only(':default');" \
248 "$PLContainer->permit(qw[:base_math !:base_io sort time]);" \
249 "$PLContainer->share(qw[&elog &spi_exec_query &return_next " \
250 "&spi_query &spi_fetchrow &spi_cursor_close " \
251 "&spi_prepare &spi_exec_prepared &spi_query_prepared &spi_freeplan " \
252 "&_plperl_to_pg_array " \
253 "&DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %_SHARED ]);" \
254 "sub ::mksafefunc {" \
255 " my $ret = $PLContainer->reval(qq[sub { $_[0] $_[1] }]); " \
256 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }" \
257 "$PLContainer->permit('require'); $PLContainer->reval('use strict;');" \
258 "$PLContainer->deny('require');" \
259 "sub ::mk_strict_safefunc {" \
260 " my $ret = $PLContainer->reval(qq[sub { BEGIN { strict->import(); } $_[0] $_[1] }]); " \
261 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }"
264 "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" \
265 "$PLContainer->permit_only(':default');" \
266 "$PLContainer->share(qw[&elog &ERROR ]);" \
267 "sub ::mksafefunc { return $PLContainer->reval(qq[sub { " \
268 " elog(ERROR,'trusted Perl functions disabled - " \
269 " please upgrade Perl Safe module to version 2.09 or later');}]); }" \
270 "sub ::mk_strict_safefunc { return $PLContainer->reval(qq[sub { " \
271 " elog(ERROR,'trusted Perl functions disabled - " \
272 " please upgrade Perl Safe module to version 2.09 or later');}]); }"
276 plperl_init_interp(void)
278 static char *embedding[3] = {
285 * The perl library on startup does horrible things like call
286 * setlocale(LC_ALL,""). We have protected against that on most
287 * platforms by setting the environment appropriately. However, on
288 * Windows, setlocale() does not consult the environment, so we need
289 * to save the existing locale settings before perl has a chance to
290 * mangle them and restore them after its dirty deeds are done.
293 * http://msdn.microsoft.com/library/en-us/vclib/html/_crt_locale.asp
295 * It appears that we only need to do this on interpreter startup, and
296 * subsequent calls to the interpreter don't mess with the locale
299 * We restore them using Perl's POSIX::setlocale() function so that
300 * Perl doesn't have a different idea of the locale from Postgres.
305 char *save_collate, *save_ctype, *save_monetary, *save_numeric, *save_time;
308 loc = setlocale(LC_COLLATE,NULL);
309 save_collate = loc ? pstrdup(loc) : NULL;
310 loc = setlocale(LC_CTYPE,NULL);
311 save_ctype = loc ? pstrdup(loc) : NULL;
312 loc = setlocale(LC_MONETARY,NULL);
313 save_monetary = loc ? pstrdup(loc) : NULL;
314 loc = setlocale(LC_NUMERIC,NULL);
315 save_numeric = loc ? pstrdup(loc) : NULL;
316 loc = setlocale(LC_TIME,NULL);
317 save_time = loc ? pstrdup(loc) : NULL;
321 plperl_interp = perl_alloc();
323 elog(ERROR, "could not allocate Perl interpreter");
325 perl_construct(plperl_interp);
326 perl_parse(plperl_interp, plperl_init_shared_libs, 3, embedding, NULL);
327 perl_run(plperl_interp);
329 plperl_proc_hash = newHV();
330 plperl_query_hash = newHV();
334 eval_pv("use POSIX qw(locale_h);", TRUE); /* croak on failure */
336 if (save_collate != NULL)
338 snprintf(buf, sizeof(buf),"setlocale(%s,'%s');",
339 "LC_COLLATE",save_collate);
343 if (save_ctype != NULL)
345 snprintf(buf, sizeof(buf),"setlocale(%s,'%s');",
346 "LC_CTYPE",save_ctype);
350 if (save_monetary != NULL)
352 snprintf(buf, sizeof(buf),"setlocale(%s,'%s');",
353 "LC_MONETARY",save_monetary);
355 pfree(save_monetary);
357 if (save_numeric != NULL)
359 snprintf(buf, sizeof(buf),"setlocale(%s,'%s');",
360 "LC_NUMERIC",save_numeric);
364 if (save_time != NULL)
366 snprintf(buf, sizeof(buf),"setlocale(%s,'%s');",
367 "LC_TIME",save_time);
378 plperl_safe_init(void)
383 res = eval_pv(SAFE_MODULE, FALSE); /* TRUE = croak if failure */
385 safe_version = SvNV(res);
388 * We actually want to reject safe_version < 2.09, but it's risky to
389 * assume that floating-point comparisons are exact, so use a slightly
390 * smaller comparison value.
392 if (safe_version < 2.0899)
394 /* not safe, so disallow all trusted funcs */
395 eval_pv(SAFE_BAD, FALSE);
399 eval_pv(SAFE_OK, FALSE);
402 plperl_safe_init_done = true;
406 * Perl likes to put a newline after its error messages; clean up such
409 strip_trailing_ws(const char *msg)
411 char *res = pstrdup(msg);
412 int len = strlen(res);
414 while (len > 0 && isspace((unsigned char) res[len - 1]))
420 /* Build a tuple from a hash. */
423 plperl_build_tuple_result(HV *perlhash, AttInMetadata *attinmeta)
425 TupleDesc td = attinmeta->tupdesc;
432 values = (char **) palloc0(td->natts * sizeof(char *));
434 hv_iterinit(perlhash);
435 while ((val = hv_iternextsv(perlhash, &key, &klen)))
437 int attn = SPI_fnumber(td, key);
439 if (attn <= 0 || td->attrs[attn - 1]->attisdropped)
441 (errcode(ERRCODE_UNDEFINED_COLUMN),
442 errmsg("Perl hash contains nonexistent column \"%s\"",
444 if (SvOK(val) && SvTYPE(val) != SVt_NULL)
445 values[attn - 1] = SvPV(val, PL_na);
447 hv_iterinit(perlhash);
449 tup = BuildTupleFromCStrings(attinmeta, values);
455 * convert perl array to postgres string representation
458 plperl_convert_to_pg_array(SV *src)
469 count = call_pv("::_plperl_to_pg_array", G_SCALAR);
474 elog(ERROR, "unexpected _plperl_to_pg_array failure");
484 /* Set up the arguments for a trigger call. */
487 plperl_trigger_build_args(FunctionCallInfo fcinfo)
500 tdata = (TriggerData *) fcinfo->context;
501 tupdesc = tdata->tg_relation->rd_att;
503 relid = DatumGetCString(
504 DirectFunctionCall1(oidout,
505 ObjectIdGetDatum(tdata->tg_relation->rd_id)
509 hv_store(hv, "name", 4, newSVpv(tdata->tg_trigger->tgname, 0), 0);
510 hv_store(hv, "relid", 5, newSVpv(relid, 0), 0);
512 if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
515 if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
516 hv_store(hv, "new", 3,
517 plperl_hash_from_tuple(tdata->tg_trigtuple, tupdesc),
520 else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
523 if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
524 hv_store(hv, "old", 3,
525 plperl_hash_from_tuple(tdata->tg_trigtuple, tupdesc),
528 else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
531 if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
533 hv_store(hv, "old", 3,
534 plperl_hash_from_tuple(tdata->tg_trigtuple, tupdesc),
536 hv_store(hv, "new", 3,
537 plperl_hash_from_tuple(tdata->tg_newtuple, tupdesc),
544 hv_store(hv, "event", 5, newSVpv(event, 0), 0);
545 hv_store(hv, "argc", 4, newSViv(tdata->tg_trigger->tgnargs), 0);
547 if (tdata->tg_trigger->tgnargs > 0)
551 for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
552 av_push(av, newSVpv(tdata->tg_trigger->tgargs[i], 0));
553 hv_store(hv, "args", 4, newRV_noinc((SV *) av), 0);
556 hv_store(hv, "relname", 7,
557 newSVpv(SPI_getrelname(tdata->tg_relation), 0), 0);
559 if (TRIGGER_FIRED_BEFORE(tdata->tg_event))
561 else if (TRIGGER_FIRED_AFTER(tdata->tg_event))
565 hv_store(hv, "when", 4, newSVpv(when, 0), 0);
567 if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
569 else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event))
573 hv_store(hv, "level", 5, newSVpv(level, 0), 0);
575 return newRV_noinc((SV *) hv);
579 /* Set up the new tuple returned from a trigger. */
582 plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup)
597 tupdesc = tdata->tg_relation->rd_att;
599 svp = hv_fetch(hvTD, "new", 3, FALSE);
602 (errcode(ERRCODE_UNDEFINED_COLUMN),
603 errmsg("$_TD->{new} does not exist")));
604 if (!SvOK(*svp) || SvTYPE(*svp) != SVt_RV || SvTYPE(SvRV(*svp)) != SVt_PVHV)
606 (errcode(ERRCODE_DATATYPE_MISMATCH),
607 errmsg("$_TD->{new} is not a hash reference")));
608 hvNew = (HV *) SvRV(*svp);
610 modattrs = palloc(tupdesc->natts * sizeof(int));
611 modvalues = palloc(tupdesc->natts * sizeof(Datum));
612 modnulls = palloc(tupdesc->natts * sizeof(char));
616 while ((val = hv_iternextsv(hvNew, &key, &klen)))
618 int attn = SPI_fnumber(tupdesc, key);
620 if (attn <= 0 || tupdesc->attrs[attn - 1]->attisdropped)
622 (errcode(ERRCODE_UNDEFINED_COLUMN),
623 errmsg("Perl hash contains nonexistent column \"%s\"",
625 if (SvOK(val) && SvTYPE(val) != SVt_NULL)
631 /* XXX would be better to cache these lookups */
632 getTypeInputInfo(tupdesc->attrs[attn - 1]->atttypid,
633 &typinput, &typioparam);
634 fmgr_info(typinput, &finfo);
635 modvalues[slotsused] = FunctionCall3(&finfo,
636 CStringGetDatum(SvPV(val, PL_na)),
637 ObjectIdGetDatum(typioparam),
638 Int32GetDatum(tupdesc->attrs[attn - 1]->atttypmod));
639 modnulls[slotsused] = ' ';
643 modvalues[slotsused] = (Datum) 0;
644 modnulls[slotsused] = 'n';
646 modattrs[slotsused] = attn;
651 rtup = SPI_modifytuple(tdata->tg_relation, otup, slotsused,
652 modattrs, modvalues, modnulls);
659 elog(ERROR, "SPI_modifytuple failed: %s",
660 SPI_result_code_string(SPI_result));
667 * This is the only externally-visible part of the plperl call interface.
668 * The Postgres function and trigger managers call it to execute a
671 PG_FUNCTION_INFO_V1(plperl_call_handler);
674 plperl_call_handler(PG_FUNCTION_ARGS)
677 plperl_call_data *save_call_data;
681 save_call_data = current_call_data;
684 if (CALLED_AS_TRIGGER(fcinfo))
685 retval = PointerGetDatum(plperl_trigger_handler(fcinfo));
687 retval = plperl_func_handler(fcinfo);
691 current_call_data = save_call_data;
696 current_call_data = save_call_data;
701 * This is the other externally visible function - it is called when CREATE
702 * FUNCTION is issued to validate the function being created/replaced.
704 PG_FUNCTION_INFO_V1(plperl_validator);
707 plperl_validator(PG_FUNCTION_ARGS)
709 Oid funcoid = PG_GETARG_OID(0);
717 bool istrigger = false;
720 /* Get the new function's pg_proc entry */
721 tuple = SearchSysCache(PROCOID,
722 ObjectIdGetDatum(funcoid),
724 if (!HeapTupleIsValid(tuple))
725 elog(ERROR, "cache lookup failed for function %u", funcoid);
726 proc = (Form_pg_proc) GETSTRUCT(tuple);
728 functyptype = get_typtype(proc->prorettype);
730 /* Disallow pseudotype result */
731 /* except for TRIGGER, RECORD, or VOID */
732 if (functyptype == 'p')
734 /* we assume OPAQUE with no arguments means a trigger */
735 if (proc->prorettype == TRIGGEROID ||
736 (proc->prorettype == OPAQUEOID && proc->pronargs == 0))
738 else if (proc->prorettype != RECORDOID &&
739 proc->prorettype != VOIDOID)
741 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
742 errmsg("plperl functions cannot return type %s",
743 format_type_be(proc->prorettype))));
746 /* Disallow pseudotypes in arguments (either IN or OUT) */
747 numargs = get_func_arg_info(tuple,
748 &argtypes, &argnames, &argmodes);
749 for (i = 0; i < numargs; i++)
751 if (get_typtype(argtypes[i]) == 'p')
753 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
754 errmsg("plperl functions cannot take type %s",
755 format_type_be(argtypes[i]))));
758 ReleaseSysCache(tuple);
760 /* Postpone body checks if !check_function_bodies */
761 if (check_function_bodies)
763 plperl_proc_desc *prodesc;
767 prodesc = compile_plperl_function(funcoid, istrigger);
770 /* the result of a validator is ignored */
775 /* Uses mksafefunc/mkunsafefunc to create an anonymous sub whose text is
776 * supplied in s, and returns a reference to the closure. */
779 plperl_create_sub(char *s, bool trusted)
786 if (trusted && !plperl_safe_init_done)
795 XPUSHs(sv_2mortal(newSVpv("my $_TD=$_[0]; shift;", 0)));
796 XPUSHs(sv_2mortal(newSVpv(s, 0)));
800 * G_KEEPERR seems to be needed here, else we don't recognize compile
801 * errors properly. Perhaps it's because there's another level of eval
805 if (trusted && plperl_use_strict)
806 compile_sub = "::mk_strict_safefunc";
807 else if (plperl_use_strict)
808 compile_sub = "::mk_strict_unsafefunc";
810 compile_sub = "::mksafefunc";
812 compile_sub = "::mkunsafefunc";
814 count = perl_call_pv(compile_sub, G_SCALAR | G_EVAL | G_KEEPERR);
822 elog(ERROR, "didn't get a return item from mksafefunc");
832 (errcode(ERRCODE_SYNTAX_ERROR),
833 errmsg("creation of Perl function failed: %s",
834 strip_trailing_ws(SvPV(ERRSV, PL_na)))));
838 * need to make a deep copy of the return. it comes off the stack as a
841 subref = newSVsv(POPs);
843 if (!SvROK(subref) || SvTYPE(SvRV(subref)) != SVt_PVCV)
850 * subref is our responsibility because it is not mortal
852 SvREFCNT_dec(subref);
853 elog(ERROR, "didn't get a code ref");
864 /**********************************************************************
865 * plperl_init_shared_libs() -
867 * We cannot use the DynaLoader directly to get at the Opcode
868 * module (used by Safe.pm). So, we link Opcode into ourselves
869 * and do the initialization behind perl's back.
871 **********************************************************************/
873 EXTERN_C void boot_DynaLoader(pTHX_ CV *cv);
874 EXTERN_C void boot_SPI(pTHX_ CV *cv);
877 plperl_init_shared_libs(pTHX)
879 char *file = __FILE__;
881 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
882 newXS("SPI::bootstrap", boot_SPI, file);
887 plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
900 XPUSHs(&PL_sv_undef); /* no trigger data */
902 for (i = 0; i < desc->nargs; i++)
904 if (fcinfo->argnull[i])
905 XPUSHs(&PL_sv_undef);
906 else if (desc->arg_is_rowtype[i])
912 HeapTupleData tmptup;
915 td = DatumGetHeapTupleHeader(fcinfo->arg[i]);
916 /* Extract rowtype info and find a tupdesc */
917 tupType = HeapTupleHeaderGetTypeId(td);
918 tupTypmod = HeapTupleHeaderGetTypMod(td);
919 tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
920 /* Build a temporary HeapTuple control structure */
921 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
924 hashref = plperl_hash_from_tuple(&tmptup, tupdesc);
925 XPUSHs(sv_2mortal(hashref));
931 tmp = DatumGetCString(FunctionCall1(&(desc->arg_out_func[i]),
933 sv = newSVpv(tmp, 0);
934 #if PERL_BCDVERSION >= 0x5006000L
935 if (GetDatabaseEncoding() == PG_UTF8)
938 XPUSHs(sv_2mortal(sv));
944 /* Do NOT use G_KEEPERR here */
945 count = perl_call_sv(desc->reference, G_SCALAR | G_EVAL);
954 elog(ERROR, "didn't get a return item from function");
963 /* XXX need to find a way to assign an errcode here */
965 (errmsg("error from Perl function: %s",
966 strip_trailing_ws(SvPV(ERRSV, PL_na)))));
969 retval = newSVsv(POPs);
980 plperl_call_perl_trigger_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo,
996 tg_trigger = ((TriggerData *) fcinfo->context)->tg_trigger;
997 for (i = 0; i < tg_trigger->tgnargs; i++)
998 XPUSHs(sv_2mortal(newSVpv(tg_trigger->tgargs[i], 0)));
1001 /* Do NOT use G_KEEPERR here */
1002 count = perl_call_sv(desc->reference, G_SCALAR | G_EVAL);
1011 elog(ERROR, "didn't get a return item from trigger function");
1020 /* XXX need to find a way to assign an errcode here */
1022 (errmsg("error from Perl trigger function: %s",
1023 strip_trailing_ws(SvPV(ERRSV, PL_na)))));
1026 retval = newSVsv(POPs);
1037 plperl_func_handler(PG_FUNCTION_ARGS)
1039 plperl_proc_desc *prodesc;
1043 SV *array_ret = NULL;
1046 * Create the call_data beforing connecting to SPI, so that it is
1047 * not allocated in the SPI memory context
1049 current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
1050 current_call_data->fcinfo = fcinfo;
1052 if (SPI_connect() != SPI_OK_CONNECT)
1053 elog(ERROR, "could not connect to SPI manager");
1055 prodesc = compile_plperl_function(fcinfo->flinfo->fn_oid, false);
1056 current_call_data->prodesc = prodesc;
1058 rsi = (ReturnSetInfo *) fcinfo->resultinfo;
1060 if (prodesc->fn_retisset)
1062 /* Check context before allowing the call to go through */
1063 if (!rsi || !IsA(rsi, ReturnSetInfo) ||
1064 (rsi->allowedModes & SFRM_Materialize) == 0 ||
1065 rsi->expectedDesc == NULL)
1067 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1068 errmsg("set-valued function called in context that "
1069 "cannot accept a set")));
1072 perlret = plperl_call_perl_func(prodesc, fcinfo);
1074 /************************************************************
1075 * Disconnect from SPI manager and then create the return
1076 * values datum (if the input function does a palloc for it
1077 * this must not be allocated in the SPI memory context
1078 * because SPI_finish would free it).
1079 ************************************************************/
1080 if (SPI_finish() != SPI_OK_FINISH)
1081 elog(ERROR, "SPI_finish() failed");
1083 if (prodesc->fn_retisset)
1086 * If the Perl function returned an arrayref, we pretend that it
1087 * called return_next() for each element of the array, to handle old
1088 * SRFs that didn't know about return_next(). Any other sort of return
1089 * value is an error.
1091 if (SvTYPE(perlret) == SVt_RV &&
1092 SvTYPE(SvRV(perlret)) == SVt_PVAV)
1096 AV *rav = (AV *) SvRV(perlret);
1098 while ((svp = av_fetch(rav, i, FALSE)) != NULL)
1100 plperl_return_next(*svp);
1104 else if (SvTYPE(perlret) != SVt_NULL)
1107 (errcode(ERRCODE_DATATYPE_MISMATCH),
1108 errmsg("set-returning Perl function must return "
1109 "reference to array or use return_next")));
1112 rsi->returnMode = SFRM_Materialize;
1113 if (current_call_data->tuple_store)
1115 rsi->setResult = current_call_data->tuple_store;
1116 rsi->setDesc = current_call_data->ret_tdesc;
1120 else if (SvTYPE(perlret) == SVt_NULL)
1122 /* Return NULL if Perl code returned undef */
1123 if (rsi && IsA(rsi, ReturnSetInfo))
1124 rsi->isDone = ExprEndResult;
1125 fcinfo->isnull = true;
1128 else if (prodesc->fn_retistuple)
1130 /* Return a perl hash converted to a Datum */
1132 AttInMetadata *attinmeta;
1135 if (!SvOK(perlret) || SvTYPE(perlret) != SVt_RV ||
1136 SvTYPE(SvRV(perlret)) != SVt_PVHV)
1139 (errcode(ERRCODE_DATATYPE_MISMATCH),
1140 errmsg("composite-returning Perl function "
1141 "must return reference to hash")));
1144 /* XXX should cache the attinmeta data instead of recomputing */
1145 if (get_call_result_type(fcinfo, NULL, &td) != TYPEFUNC_COMPOSITE)
1148 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1149 errmsg("function returning record called in context "
1150 "that cannot accept type record")));
1153 attinmeta = TupleDescGetAttInMetadata(td);
1154 tup = plperl_build_tuple_result((HV *) SvRV(perlret), attinmeta);
1155 retval = HeapTupleGetDatum(tup);
1159 /* Return a perl string converted to a Datum */
1162 if (prodesc->fn_retisarray && SvROK(perlret) &&
1163 SvTYPE(SvRV(perlret)) == SVt_PVAV)
1165 array_ret = plperl_convert_to_pg_array(perlret);
1166 SvREFCNT_dec(perlret);
1167 perlret = array_ret;
1170 val = SvPV(perlret, PL_na);
1172 retval = FunctionCall3(&prodesc->result_in_func,
1173 CStringGetDatum(val),
1174 ObjectIdGetDatum(prodesc->result_typioparam),
1178 if (array_ret == NULL)
1179 SvREFCNT_dec(perlret);
1181 current_call_data = NULL;
1187 plperl_trigger_handler(PG_FUNCTION_ARGS)
1189 plperl_proc_desc *prodesc;
1196 * Create the call_data beforing connecting to SPI, so that it is
1197 * not allocated in the SPI memory context
1199 current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
1200 current_call_data->fcinfo = fcinfo;
1202 /* Connect to SPI manager */
1203 if (SPI_connect() != SPI_OK_CONNECT)
1204 elog(ERROR, "could not connect to SPI manager");
1206 /* Find or compile the function */
1207 prodesc = compile_plperl_function(fcinfo->flinfo->fn_oid, true);
1208 current_call_data->prodesc = prodesc;
1210 svTD = plperl_trigger_build_args(fcinfo);
1211 perlret = plperl_call_perl_trigger_func(prodesc, fcinfo, svTD);
1212 hvTD = (HV *) SvRV(svTD);
1214 /************************************************************
1215 * Disconnect from SPI manager and then create the return
1216 * values datum (if the input function does a palloc for it
1217 * this must not be allocated in the SPI memory context
1218 * because SPI_finish would free it).
1219 ************************************************************/
1220 if (SPI_finish() != SPI_OK_FINISH)
1221 elog(ERROR, "SPI_finish() failed");
1223 if (!(perlret && SvOK(perlret) && SvTYPE(perlret) != SVt_NULL))
1225 /* undef result means go ahead with original tuple */
1226 TriggerData *trigdata = ((TriggerData *) fcinfo->context);
1228 if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
1229 retval = (Datum) trigdata->tg_trigtuple;
1230 else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
1231 retval = (Datum) trigdata->tg_newtuple;
1232 else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
1233 retval = (Datum) trigdata->tg_trigtuple;
1235 retval = (Datum) 0; /* can this happen? */
1242 tmp = SvPV(perlret, PL_na);
1244 if (pg_strcasecmp(tmp, "SKIP") == 0)
1246 else if (pg_strcasecmp(tmp, "MODIFY") == 0)
1248 TriggerData *trigdata = (TriggerData *) fcinfo->context;
1250 if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
1251 trv = plperl_modify_tuple(hvTD, trigdata,
1252 trigdata->tg_trigtuple);
1253 else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
1254 trv = plperl_modify_tuple(hvTD, trigdata,
1255 trigdata->tg_newtuple);
1259 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1260 errmsg("ignoring modified tuple in DELETE trigger")));
1267 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1268 errmsg("result of Perl trigger function must be undef, "
1269 "\"SKIP\" or \"MODIFY\"")));
1272 retval = PointerGetDatum(trv);
1277 SvREFCNT_dec(perlret);
1279 current_call_data = NULL;
1284 static plperl_proc_desc *
1285 compile_plperl_function(Oid fn_oid, bool is_trigger)
1288 Form_pg_proc procStruct;
1289 char internal_proname[64];
1291 plperl_proc_desc *prodesc = NULL;
1295 /* We'll need the pg_proc tuple in any case... */
1296 procTup = SearchSysCache(PROCOID,
1297 ObjectIdGetDatum(fn_oid),
1299 if (!HeapTupleIsValid(procTup))
1300 elog(ERROR, "cache lookup failed for function %u", fn_oid);
1301 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
1303 /************************************************************
1304 * Build our internal proc name from the function's Oid
1305 ************************************************************/
1307 sprintf(internal_proname, "__PLPerl_proc_%u", fn_oid);
1309 sprintf(internal_proname, "__PLPerl_proc_%u_trigger", fn_oid);
1311 proname_len = strlen(internal_proname);
1313 /************************************************************
1314 * Lookup the internal proc name in the hashtable
1315 ************************************************************/
1316 svp = hv_fetch(plperl_proc_hash, internal_proname, proname_len, FALSE);
1321 prodesc = INT2PTR( plperl_proc_desc *, SvUV(*svp));
1323 /************************************************************
1324 * If it's present, must check whether it's still up to date.
1325 * This is needed because CREATE OR REPLACE FUNCTION can modify the
1326 * function's pg_proc entry without changing its OID.
1327 ************************************************************/
1328 uptodate = (prodesc->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
1329 prodesc->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data));
1333 /* need we delete old entry? */
1338 /************************************************************
1339 * If we haven't found it in the hashtable, we analyze
1340 * the function's arguments and return type and store
1341 * the in-/out-functions in the prodesc block and create
1342 * a new hashtable entry for it.
1344 * Then we load the procedure into the Perl interpreter.
1345 ************************************************************/
1346 if (prodesc == NULL)
1350 Form_pg_language langStruct;
1351 Form_pg_type typeStruct;
1356 /************************************************************
1357 * Allocate a new procedure description block
1358 ************************************************************/
1359 prodesc = (plperl_proc_desc *) malloc(sizeof(plperl_proc_desc));
1360 if (prodesc == NULL)
1362 (errcode(ERRCODE_OUT_OF_MEMORY),
1363 errmsg("out of memory")));
1364 MemSet(prodesc, 0, sizeof(plperl_proc_desc));
1365 prodesc->proname = strdup(internal_proname);
1366 prodesc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
1367 prodesc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);
1369 /* Remember if function is STABLE/IMMUTABLE */
1370 prodesc->fn_readonly =
1371 (procStruct->provolatile != PROVOLATILE_VOLATILE);
1373 /************************************************************
1374 * Lookup the pg_language tuple by Oid
1375 ************************************************************/
1376 langTup = SearchSysCache(LANGOID,
1377 ObjectIdGetDatum(procStruct->prolang),
1379 if (!HeapTupleIsValid(langTup))
1381 free(prodesc->proname);
1383 elog(ERROR, "cache lookup failed for language %u",
1384 procStruct->prolang);
1386 langStruct = (Form_pg_language) GETSTRUCT(langTup);
1387 prodesc->lanpltrusted = langStruct->lanpltrusted;
1388 ReleaseSysCache(langTup);
1390 /************************************************************
1391 * Get the required information for input conversion of the
1393 ************************************************************/
1396 typeTup = SearchSysCache(TYPEOID,
1397 ObjectIdGetDatum(procStruct->prorettype),
1399 if (!HeapTupleIsValid(typeTup))
1401 free(prodesc->proname);
1403 elog(ERROR, "cache lookup failed for type %u",
1404 procStruct->prorettype);
1406 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1408 /* Disallow pseudotype result, except VOID or RECORD */
1409 if (typeStruct->typtype == 'p')
1411 if (procStruct->prorettype == VOIDOID ||
1412 procStruct->prorettype == RECORDOID)
1414 else if (procStruct->prorettype == TRIGGEROID)
1416 free(prodesc->proname);
1419 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1420 errmsg("trigger functions may only be called "
1425 free(prodesc->proname);
1428 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1429 errmsg("plperl functions cannot return type %s",
1430 format_type_be(procStruct->prorettype))));
1434 prodesc->result_oid = procStruct->prorettype;
1435 prodesc->fn_retisset = procStruct->proretset;
1436 prodesc->fn_retistuple = (typeStruct->typtype == 'c' ||
1437 procStruct->prorettype == RECORDOID);
1439 prodesc->fn_retisarray =
1440 (typeStruct->typlen == -1 && typeStruct->typelem);
1442 perm_fmgr_info(typeStruct->typinput, &(prodesc->result_in_func));
1443 prodesc->result_typioparam = getTypeIOParam(typeTup);
1445 ReleaseSysCache(typeTup);
1448 /************************************************************
1449 * Get the required information for output conversion
1450 * of all procedure arguments
1451 ************************************************************/
1454 prodesc->nargs = procStruct->pronargs;
1455 for (i = 0; i < prodesc->nargs; i++)
1457 typeTup = SearchSysCache(TYPEOID,
1458 ObjectIdGetDatum(procStruct->proargtypes.values[i]),
1460 if (!HeapTupleIsValid(typeTup))
1462 free(prodesc->proname);
1464 elog(ERROR, "cache lookup failed for type %u",
1465 procStruct->proargtypes.values[i]);
1467 typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
1469 /* Disallow pseudotype argument */
1470 if (typeStruct->typtype == 'p')
1472 free(prodesc->proname);
1475 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1476 errmsg("plperl functions cannot take type %s",
1477 format_type_be(procStruct->proargtypes.values[i]))));
1480 if (typeStruct->typtype == 'c')
1481 prodesc->arg_is_rowtype[i] = true;
1484 prodesc->arg_is_rowtype[i] = false;
1485 perm_fmgr_info(typeStruct->typoutput,
1486 &(prodesc->arg_out_func[i]));
1489 ReleaseSysCache(typeTup);
1493 /************************************************************
1494 * create the text of the anonymous subroutine.
1495 * we do not use a named subroutine so that we can call directly
1496 * through the reference.
1497 ************************************************************/
1498 prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
1499 Anum_pg_proc_prosrc, &isnull);
1501 elog(ERROR, "null prosrc");
1502 proc_source = DatumGetCString(DirectFunctionCall1(textout,
1505 /************************************************************
1506 * Create the procedure in the interpreter
1507 ************************************************************/
1508 prodesc->reference = plperl_create_sub(proc_source, prodesc->lanpltrusted);
1510 if (!prodesc->reference) /* can this happen? */
1512 free(prodesc->proname);
1514 elog(ERROR, "could not create internal procedure \"%s\"",
1518 hv_store(plperl_proc_hash, internal_proname, proname_len,
1519 newSVuv( PTR2UV( prodesc)), 0);
1522 ReleaseSysCache(procTup);
1528 /* Build a hash from all attributes of a given tuple. */
1531 plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc)
1538 for (i = 0; i < tupdesc->natts; i++)
1549 if (tupdesc->attrs[i]->attisdropped)
1552 attname = NameStr(tupdesc->attrs[i]->attname);
1553 namelen = strlen(attname);
1554 attr = heap_getattr(tuple, i + 1, tupdesc, &isnull);
1558 /* Store (attname => undef) and move on. */
1559 hv_store(hv, attname, namelen, newSV(0), 0);
1563 /* XXX should have a way to cache these lookups */
1565 getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
1566 &typoutput, &typisvarlena);
1568 outputstr = DatumGetCString(OidFunctionCall1(typoutput, attr));
1570 sv = newSVpv(outputstr, 0);
1571 #if PERL_BCDVERSION >= 0x5006000L
1572 if (GetDatabaseEncoding() == PG_UTF8)
1575 hv_store(hv, attname, namelen, sv, 0);
1580 return newRV_noinc((SV *) hv);
1585 plperl_spi_exec(char *query, int limit)
1590 * Execute the query inside a sub-transaction, so we can cope with errors
1593 MemoryContext oldcontext = CurrentMemoryContext;
1594 ResourceOwner oldowner = CurrentResourceOwner;
1596 BeginInternalSubTransaction(NULL);
1597 /* Want to run inside function's memory context */
1598 MemoryContextSwitchTo(oldcontext);
1604 spi_rv = SPI_execute(query, current_call_data->prodesc->fn_readonly,
1606 ret_hv = plperl_spi_execute_fetch_result(SPI_tuptable, SPI_processed,
1609 /* Commit the inner transaction, return to outer xact context */
1610 ReleaseCurrentSubTransaction();
1611 MemoryContextSwitchTo(oldcontext);
1612 CurrentResourceOwner = oldowner;
1615 * AtEOSubXact_SPI() should not have popped any SPI context, but just
1616 * in case it did, make sure we remain connected.
1618 SPI_restore_connection();
1624 /* Save error info */
1625 MemoryContextSwitchTo(oldcontext);
1626 edata = CopyErrorData();
1629 /* Abort the inner transaction */
1630 RollbackAndReleaseCurrentSubTransaction();
1631 MemoryContextSwitchTo(oldcontext);
1632 CurrentResourceOwner = oldowner;
1635 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
1636 * have left us in a disconnected state. We need this hack to return
1637 * to connected state.
1639 SPI_restore_connection();
1641 /* Punt the error to Perl */
1642 croak("%s", edata->message);
1644 /* Can't get here, but keep compiler quiet */
1654 plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed,
1661 hv_store(result, "status", strlen("status"),
1662 newSVpv((char *) SPI_result_code_string(status), 0), 0);
1663 hv_store(result, "processed", strlen("processed"),
1664 newSViv(processed), 0);
1666 if (status == SPI_OK_SELECT)
1673 for (i = 0; i < processed; i++)
1675 row = plperl_hash_from_tuple(tuptable->vals[i], tuptable->tupdesc);
1678 hv_store(result, "rows", strlen("rows"),
1679 newRV_noinc((SV *) rows), 0);
1682 SPI_freetuptable(tuptable);
1689 * Note: plperl_return_next is called both in Postgres and Perl contexts.
1690 * We report any errors in Postgres fashion (via ereport). If called in
1691 * Perl context, it is SPI.xs's responsibility to catch the error and
1692 * convert to a Perl error. We assume (perhaps without adequate justification)
1693 * that we need not abort the current transaction if the Perl code traps the
1697 plperl_return_next(SV *sv)
1699 plperl_proc_desc *prodesc;
1700 FunctionCallInfo fcinfo;
1702 MemoryContext old_cxt;
1708 prodesc = current_call_data->prodesc;
1709 fcinfo = current_call_data->fcinfo;
1710 rsi = (ReturnSetInfo *) fcinfo->resultinfo;
1712 if (!prodesc->fn_retisset)
1714 (errcode(ERRCODE_SYNTAX_ERROR),
1715 errmsg("cannot use return_next in a non-SETOF function")));
1717 if (prodesc->fn_retistuple &&
1718 !(SvOK(sv) && SvTYPE(sv) == SVt_RV && SvTYPE(SvRV(sv)) == SVt_PVHV))
1720 (errcode(ERRCODE_DATATYPE_MISMATCH),
1721 errmsg("setof-composite-returning Perl function "
1722 "must call return_next with reference to hash")));
1724 if (!current_call_data->ret_tdesc)
1728 Assert(!current_call_data->tuple_store);
1729 Assert(!current_call_data->attinmeta);
1732 * This is the first call to return_next in the current
1733 * PL/Perl function call, so memoize some lookups
1735 if (prodesc->fn_retistuple)
1736 (void) get_call_result_type(fcinfo, NULL, &tupdesc);
1738 tupdesc = rsi->expectedDesc;
1741 * Make sure the tuple_store and ret_tdesc are sufficiently
1744 old_cxt = MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);
1746 current_call_data->ret_tdesc = CreateTupleDescCopy(tupdesc);
1747 current_call_data->tuple_store =
1748 tuplestore_begin_heap(true, false, work_mem);
1749 if (prodesc->fn_retistuple)
1751 current_call_data->attinmeta =
1752 TupleDescGetAttInMetadata(current_call_data->ret_tdesc);
1755 MemoryContextSwitchTo(old_cxt);
1759 * Producing the tuple we want to return requires making plenty of
1760 * palloc() allocations that are not cleaned up. Since this
1761 * function can be called many times before the current memory
1762 * context is reset, we need to do those allocations in a
1763 * temporary context.
1765 if (!current_call_data->tmp_cxt)
1767 current_call_data->tmp_cxt =
1768 AllocSetContextCreate(rsi->econtext->ecxt_per_tuple_memory,
1769 "PL/Perl return_next temporary cxt",
1770 ALLOCSET_DEFAULT_MINSIZE,
1771 ALLOCSET_DEFAULT_INITSIZE,
1772 ALLOCSET_DEFAULT_MAXSIZE);
1775 old_cxt = MemoryContextSwitchTo(current_call_data->tmp_cxt);
1777 if (prodesc->fn_retistuple)
1779 tuple = plperl_build_tuple_result((HV *) SvRV(sv),
1780 current_call_data->attinmeta);
1784 Datum ret = (Datum) 0;
1787 if (SvOK(sv) && SvTYPE(sv) != SVt_NULL)
1789 char *val = SvPV(sv, PL_na);
1791 ret = FunctionCall3(&prodesc->result_in_func,
1792 PointerGetDatum(val),
1793 ObjectIdGetDatum(prodesc->result_typioparam),
1798 tuple = heap_form_tuple(current_call_data->ret_tdesc, &ret, &isNull);
1801 /* Make sure to store the tuple in a long-lived memory context */
1802 MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory);
1803 tuplestore_puttuple(current_call_data->tuple_store, tuple);
1804 MemoryContextSwitchTo(old_cxt);
1806 MemoryContextReset(current_call_data->tmp_cxt);
1811 plperl_spi_query(char *query)
1816 * Execute the query inside a sub-transaction, so we can cope with errors
1819 MemoryContext oldcontext = CurrentMemoryContext;
1820 ResourceOwner oldowner = CurrentResourceOwner;
1822 BeginInternalSubTransaction(NULL);
1823 /* Want to run inside function's memory context */
1824 MemoryContextSwitchTo(oldcontext);
1831 /* Create a cursor for the query */
1832 plan = SPI_prepare(query, 0, NULL);
1834 elog(ERROR, "SPI_prepare() failed:%s",
1835 SPI_result_code_string(SPI_result));
1837 portal = SPI_cursor_open(NULL, plan, NULL, NULL, false);
1838 SPI_freeplan( plan);
1839 if ( portal == NULL)
1840 elog(ERROR, "SPI_cursor_open() failed:%s",
1841 SPI_result_code_string(SPI_result));
1842 cursor = newSVpv(portal->name, 0);
1844 /* Commit the inner transaction, return to outer xact context */
1845 ReleaseCurrentSubTransaction();
1846 MemoryContextSwitchTo(oldcontext);
1847 CurrentResourceOwner = oldowner;
1850 * AtEOSubXact_SPI() should not have popped any SPI context, but just
1851 * in case it did, make sure we remain connected.
1853 SPI_restore_connection();
1859 /* Save error info */
1860 MemoryContextSwitchTo(oldcontext);
1861 edata = CopyErrorData();
1864 /* Abort the inner transaction */
1865 RollbackAndReleaseCurrentSubTransaction();
1866 MemoryContextSwitchTo(oldcontext);
1867 CurrentResourceOwner = oldowner;
1870 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
1871 * have left us in a disconnected state. We need this hack to return
1872 * to connected state.
1874 SPI_restore_connection();
1876 /* Punt the error to Perl */
1877 croak("%s", edata->message);
1879 /* Can't get here, but keep compiler quiet */
1889 plperl_spi_fetchrow(char *cursor)
1894 * Execute the FETCH inside a sub-transaction, so we can cope with errors
1897 MemoryContext oldcontext = CurrentMemoryContext;
1898 ResourceOwner oldowner = CurrentResourceOwner;
1900 BeginInternalSubTransaction(NULL);
1901 /* Want to run inside function's memory context */
1902 MemoryContextSwitchTo(oldcontext);
1906 Portal p = SPI_cursor_find(cursor);
1914 SPI_cursor_fetch(p, true, 1);
1915 if (SPI_processed == 0)
1917 SPI_cursor_close(p);
1922 row = plperl_hash_from_tuple(SPI_tuptable->vals[0],
1923 SPI_tuptable->tupdesc);
1925 SPI_freetuptable(SPI_tuptable);
1928 /* Commit the inner transaction, return to outer xact context */
1929 ReleaseCurrentSubTransaction();
1930 MemoryContextSwitchTo(oldcontext);
1931 CurrentResourceOwner = oldowner;
1934 * AtEOSubXact_SPI() should not have popped any SPI context, but just
1935 * in case it did, make sure we remain connected.
1937 SPI_restore_connection();
1943 /* Save error info */
1944 MemoryContextSwitchTo(oldcontext);
1945 edata = CopyErrorData();
1948 /* Abort the inner transaction */
1949 RollbackAndReleaseCurrentSubTransaction();
1950 MemoryContextSwitchTo(oldcontext);
1951 CurrentResourceOwner = oldowner;
1954 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
1955 * have left us in a disconnected state. We need this hack to return
1956 * to connected state.
1958 SPI_restore_connection();
1960 /* Punt the error to Perl */
1961 croak("%s", edata->message);
1963 /* Can't get here, but keep compiler quiet */
1972 plperl_spi_cursor_close(char *cursor)
1974 Portal p = SPI_cursor_find(cursor);
1976 SPI_cursor_close(p);
1980 plperl_spi_prepare(char* query, int argc, SV ** argv)
1982 plperl_query_desc *qdesc;
1987 MemoryContext oldcontext = CurrentMemoryContext;
1988 ResourceOwner oldowner = CurrentResourceOwner;
1990 BeginInternalSubTransaction(NULL);
1991 MemoryContextSwitchTo(oldcontext);
1993 /************************************************************
1994 * Allocate the new querydesc structure
1995 ************************************************************/
1996 qdesc = (plperl_query_desc *) malloc(sizeof(plperl_query_desc));
1997 MemSet(qdesc, 0, sizeof(plperl_query_desc));
1998 snprintf(qdesc-> qname, sizeof(qdesc-> qname), "%lx", (long) qdesc);
1999 qdesc-> nargs = argc;
2000 qdesc-> argtypes = (Oid *) malloc(argc * sizeof(Oid));
2001 qdesc-> arginfuncs = (FmgrInfo *) malloc(argc * sizeof(FmgrInfo));
2002 qdesc-> argtypioparams = (Oid *) malloc(argc * sizeof(Oid));
2006 /************************************************************
2007 * Lookup the argument types by name in the system cache
2008 * and remember the required information for input conversion
2009 ************************************************************/
2010 for (i = 0; i < argc; i++)
2017 /************************************************************
2018 * Use SplitIdentifierString() on a copy of the type name,
2019 * turn the resulting pointer list into a TypeName node
2020 * and call typenameType() to get the pg_type tuple.
2021 ************************************************************/
2022 argcopy = pstrdup(SvPV(argv[i],PL_na));
2023 SplitIdentifierString(argcopy, '.', &names);
2024 typename = makeNode(TypeName);
2026 typename->names = lappend(typename->names, makeString(lfirst(l)));
2028 typeTup = typenameType(typename);
2029 qdesc->argtypes[i] = HeapTupleGetOid(typeTup);
2030 perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput,
2031 &(qdesc->arginfuncs[i]));
2032 qdesc->argtypioparams[i] = getTypeIOParam(typeTup);
2033 ReleaseSysCache(typeTup);
2035 list_free(typename->names);
2041 /************************************************************
2042 * Prepare the plan and check for errors
2043 ************************************************************/
2044 plan = SPI_prepare(query, argc, qdesc->argtypes);
2047 elog(ERROR, "SPI_prepare() failed:%s",
2048 SPI_result_code_string(SPI_result));
2050 /************************************************************
2051 * Save the plan into permanent memory (right now it's in the
2052 * SPI procCxt, which will go away at function end).
2053 ************************************************************/
2054 qdesc->plan = SPI_saveplan(plan);
2055 if (qdesc->plan == NULL)
2056 elog(ERROR, "SPI_saveplan() failed: %s",
2057 SPI_result_code_string(SPI_result));
2059 /* Release the procCxt copy to avoid within-function memory leak */
2062 /* Commit the inner transaction, return to outer xact context */
2063 ReleaseCurrentSubTransaction();
2064 MemoryContextSwitchTo(oldcontext);
2065 CurrentResourceOwner = oldowner;
2067 * AtEOSubXact_SPI() should not have popped any SPI context,
2068 * but just in case it did, make sure we remain connected.
2070 SPI_restore_connection();
2076 free(qdesc-> argtypes);
2077 free(qdesc-> arginfuncs);
2078 free(qdesc-> argtypioparams);
2081 /* Save error info */
2082 MemoryContextSwitchTo(oldcontext);
2083 edata = CopyErrorData();
2086 /* Abort the inner transaction */
2087 RollbackAndReleaseCurrentSubTransaction();
2088 MemoryContextSwitchTo(oldcontext);
2089 CurrentResourceOwner = oldowner;
2092 * If AtEOSubXact_SPI() popped any SPI context of the subxact,
2093 * it will have left us in a disconnected state. We need this
2094 * hack to return to connected state.
2096 SPI_restore_connection();
2098 /* Punt the error to Perl */
2099 croak("%s", edata->message);
2101 /* Can't get here, but keep compiler quiet */
2106 /************************************************************
2107 * Insert a hashtable entry for the plan and return
2108 * the key to the caller.
2109 ************************************************************/
2110 hv_store( plperl_query_hash, qdesc->qname, strlen(qdesc->qname), newSVuv( PTR2UV( qdesc)), 0);
2112 return newSVpv( qdesc->qname, strlen(qdesc->qname));
2116 plperl_spi_exec_prepared(char* query, HV * attr, int argc, SV ** argv)
2120 int i, limit, spi_rv;
2123 plperl_query_desc *qdesc;
2126 * Execute the query inside a sub-transaction, so we can cope with
2129 MemoryContext oldcontext = CurrentMemoryContext;
2130 ResourceOwner oldowner = CurrentResourceOwner;
2132 BeginInternalSubTransaction(NULL);
2133 /* Want to run inside function's memory context */
2134 MemoryContextSwitchTo(oldcontext);
2138 /************************************************************
2139 * Fetch the saved plan descriptor, see if it's o.k.
2140 ************************************************************/
2141 sv = hv_fetch(plperl_query_hash, query, strlen(query), 0);
2143 elog(ERROR, "spi_exec_prepared: Invalid prepared query passed");
2144 if ( *sv == NULL || !SvOK( *sv))
2145 elog(ERROR, "spi_exec_prepared: panic - plperl_query_hash value corrupted");
2147 qdesc = INT2PTR( plperl_query_desc *, SvUV(*sv));
2149 elog(ERROR, "spi_exec_prepared: panic - plperl_query_hash value vanished");
2151 if ( qdesc-> nargs != argc)
2152 elog(ERROR, "spi_exec_prepared: expected %d argument(s), %d passed",
2153 qdesc-> nargs, argc);
2155 /************************************************************
2156 * Parse eventual attributes
2157 ************************************************************/
2161 sv = hv_fetch( attr, "limit", 5, 0);
2162 if ( *sv && SvIOK( *sv))
2165 /************************************************************
2167 ************************************************************/
2170 nulls = (char *)palloc( argc);
2171 argvalues = (Datum *) palloc(argc * sizeof(Datum));
2172 if ( nulls == NULL || argvalues == NULL)
2173 elog(ERROR, "spi_exec_prepared: not enough memory");
2181 for ( i = 0; i < argc; i++)
2183 if ( SvTYPE( argv[i]) != SVt_NULL)
2186 FunctionCall3( &qdesc->arginfuncs[i],
2187 CStringGetDatum( SvPV( argv[i], PL_na)),
2188 ObjectIdGetDatum( qdesc->argtypioparams[i]),
2195 argvalues[i] = (Datum) 0;
2200 /************************************************************
2202 ************************************************************/
2203 spi_rv = SPI_execute_plan(qdesc-> plan, argvalues, nulls,
2204 current_call_data->prodesc->fn_readonly, limit);
2205 ret_hv = plperl_spi_execute_fetch_result(SPI_tuptable, SPI_processed,
2213 /* Commit the inner transaction, return to outer xact context */
2214 ReleaseCurrentSubTransaction();
2215 MemoryContextSwitchTo(oldcontext);
2216 CurrentResourceOwner = oldowner;
2218 * AtEOSubXact_SPI() should not have popped any SPI context,
2219 * but just in case it did, make sure we remain connected.
2221 SPI_restore_connection();
2227 /* Save error info */
2228 MemoryContextSwitchTo(oldcontext);
2229 edata = CopyErrorData();
2232 /* Abort the inner transaction */
2233 RollbackAndReleaseCurrentSubTransaction();
2234 MemoryContextSwitchTo(oldcontext);
2235 CurrentResourceOwner = oldowner;
2238 * If AtEOSubXact_SPI() popped any SPI context of the subxact,
2239 * it will have left us in a disconnected state. We need this
2240 * hack to return to connected state.
2242 SPI_restore_connection();
2244 /* Punt the error to Perl */
2245 croak("%s", edata->message);
2247 /* Can't get here, but keep compiler quiet */
2256 plperl_spi_query_prepared(char* query, int argc, SV ** argv)
2262 plperl_query_desc *qdesc;
2264 Portal portal = NULL;
2267 * Execute the query inside a sub-transaction, so we can cope with
2270 MemoryContext oldcontext = CurrentMemoryContext;
2271 ResourceOwner oldowner = CurrentResourceOwner;
2273 BeginInternalSubTransaction(NULL);
2274 /* Want to run inside function's memory context */
2275 MemoryContextSwitchTo(oldcontext);
2279 /************************************************************
2280 * Fetch the saved plan descriptor, see if it's o.k.
2281 ************************************************************/
2282 sv = hv_fetch(plperl_query_hash, query, strlen(query), 0);
2284 elog(ERROR, "spi_query_prepared: Invalid prepared query passed");
2285 if ( *sv == NULL || !SvOK( *sv))
2286 elog(ERROR, "spi_query_prepared: panic - plperl_query_hash value corrupted");
2288 qdesc = INT2PTR( plperl_query_desc *, SvUV(*sv));
2290 elog(ERROR, "spi_query_prepared: panic - plperl_query_hash value vanished");
2292 if ( qdesc-> nargs != argc)
2293 elog(ERROR, "spi_query_prepared: expected %d argument(s), %d passed",
2294 qdesc-> nargs, argc);
2296 /************************************************************
2298 ************************************************************/
2301 nulls = (char *)palloc( argc);
2302 argvalues = (Datum *) palloc(argc * sizeof(Datum));
2303 if ( nulls == NULL || argvalues == NULL)
2304 elog(ERROR, "spi_query_prepared: not enough memory");
2312 for ( i = 0; i < argc; i++)
2314 if ( SvTYPE( argv[i]) != SVt_NULL)
2317 FunctionCall3( &qdesc->arginfuncs[i],
2318 CStringGetDatum( SvPV( argv[i], PL_na)),
2319 ObjectIdGetDatum( qdesc->argtypioparams[i]),
2326 argvalues[i] = (Datum) 0;
2331 /************************************************************
2333 ************************************************************/
2334 portal = SPI_cursor_open(NULL, qdesc-> plan, argvalues, nulls,
2335 current_call_data->prodesc->fn_readonly);
2341 if ( portal == NULL)
2342 elog(ERROR, "SPI_cursor_open() failed:%s",
2343 SPI_result_code_string(SPI_result));
2345 cursor = newSVpv(portal->name, 0);
2347 /* Commit the inner transaction, return to outer xact context */
2348 ReleaseCurrentSubTransaction();
2349 MemoryContextSwitchTo(oldcontext);
2350 CurrentResourceOwner = oldowner;
2352 * AtEOSubXact_SPI() should not have popped any SPI context,
2353 * but just in case it did, make sure we remain connected.
2355 SPI_restore_connection();
2361 /* Save error info */
2362 MemoryContextSwitchTo(oldcontext);
2363 edata = CopyErrorData();
2366 /* Abort the inner transaction */
2367 RollbackAndReleaseCurrentSubTransaction();
2368 MemoryContextSwitchTo(oldcontext);
2369 CurrentResourceOwner = oldowner;
2372 * If AtEOSubXact_SPI() popped any SPI context of the subxact,
2373 * it will have left us in a disconnected state. We need this
2374 * hack to return to connected state.
2376 SPI_restore_connection();
2378 /* Punt the error to Perl */
2379 croak("%s", edata->message);
2381 /* Can't get here, but keep compiler quiet */
2390 plperl_spi_freeplan(char *query)
2394 plperl_query_desc *qdesc;
2396 sv = hv_fetch(plperl_query_hash, query, strlen(query), 0);
2398 elog(ERROR, "spi_exec_freeplan: Invalid prepared query passed");
2399 if ( *sv == NULL || !SvOK( *sv))
2400 elog(ERROR, "spi_exec_freeplan: panic - plperl_query_hash value corrupted");
2402 qdesc = INT2PTR( plperl_query_desc *, SvUV(*sv));
2404 elog(ERROR, "spi_exec_freeplan: panic - plperl_query_hash value vanished");
2407 * free all memory before SPI_freeplan, so if it dies, nothing will be left over
2409 hv_delete(plperl_query_hash, query, strlen(query), G_DISCARD);
2410 plan = qdesc-> plan;
2411 free(qdesc-> argtypes);
2412 free(qdesc-> arginfuncs);
2413 free(qdesc-> argtypioparams);
2416 SPI_freeplan( plan);