1 /**********************************************************************
2 * plperl.c - perl as a procedural language for PostgreSQL
6 **********************************************************************/
18 /* postgreSQL stuff */
19 #include "access/xact.h"
20 #include "catalog/pg_language.h"
21 #include "catalog/pg_proc.h"
22 #include "catalog/pg_type.h"
23 #include "commands/trigger.h"
24 #include "executor/spi.h"
26 #include "mb/pg_wchar.h"
27 #include "miscadmin.h"
28 #include "nodes/makefuncs.h"
29 #include "parser/parse_type.h"
30 #include "utils/builtins.h"
31 #include "utils/fmgroids.h"
32 #include "utils/guc.h"
33 #include "utils/hsearch.h"
34 #include "utils/lsyscache.h"
35 #include "utils/memutils.h"
36 #include "utils/syscache.h"
37 #include "utils/typcache.h"
39 /* define our text domain for translations */
41 #define TEXTDOMAIN PG_TEXTDOMAIN("plperl")
48 /**********************************************************************
49 * The information we cache about loaded procedures
50 **********************************************************************/
51 typedef struct plperl_proc_desc
53 char *proname
; /* user name of procedure */
54 TransactionId fn_xmin
;
55 ItemPointerData fn_tid
;
58 bool fn_retistuple
; /* true, if function returns tuple */
59 bool fn_retisset
; /* true, if function returns set */
60 bool fn_retisarray
; /* true if function returns array */
61 Oid result_oid
; /* Oid of result type */
62 FmgrInfo result_in_func
; /* I/O function and arg for result type */
63 Oid result_typioparam
;
65 FmgrInfo arg_out_func
[FUNC_MAX_ARGS
];
66 bool arg_is_rowtype
[FUNC_MAX_ARGS
];
70 /* hash table entry for proc desc */
72 typedef struct plperl_proc_entry
74 char proc_name
[NAMEDATALEN
]; /* internal name, eg
75 * __PLPerl_proc_39987 */
76 plperl_proc_desc
*proc_data
;
80 * The information we cache for the duration of a single call to a
83 typedef struct plperl_call_data
85 plperl_proc_desc
*prodesc
;
86 FunctionCallInfo fcinfo
;
87 Tuplestorestate
*tuple_store
;
89 AttInMetadata
*attinmeta
;
90 MemoryContext tmp_cxt
;
93 /**********************************************************************
94 * The information we cache about prepared and saved plans
95 **********************************************************************/
96 typedef struct plperl_query_desc
98 char qname
[sizeof(long) * 2 + 1];
102 FmgrInfo
*arginfuncs
;
106 /* hash table entry for query desc */
108 typedef struct plperl_query_entry
110 char query_name
[NAMEDATALEN
];
111 plperl_query_desc
*query_data
;
112 } plperl_query_entry
;
114 /**********************************************************************
116 **********************************************************************/
127 static InterpState interp_state
= INTERP_NONE
;
128 static bool can_run_two
= false;
130 static bool plperl_safe_init_done
= false;
131 static PerlInterpreter
*plperl_trusted_interp
= NULL
;
132 static PerlInterpreter
*plperl_untrusted_interp
= NULL
;
133 static PerlInterpreter
*plperl_held_interp
= NULL
;
134 static bool trusted_context
;
135 static HTAB
*plperl_proc_hash
= NULL
;
136 static HTAB
*plperl_query_hash
= NULL
;
138 static bool plperl_use_strict
= false;
140 /* this is saved and restored by plperl_call_handler */
141 static plperl_call_data
*current_call_data
= NULL
;
143 /**********************************************************************
144 * Forward declarations
145 **********************************************************************/
146 Datum
plperl_call_handler(PG_FUNCTION_ARGS
);
147 Datum
plperl_validator(PG_FUNCTION_ARGS
);
150 static void plperl_init_interp(void);
152 static Datum
plperl_func_handler(PG_FUNCTION_ARGS
);
154 static Datum
plperl_trigger_handler(PG_FUNCTION_ARGS
);
155 static plperl_proc_desc
*compile_plperl_function(Oid fn_oid
, bool is_trigger
);
157 static SV
*plperl_hash_from_tuple(HeapTuple tuple
, TupleDesc tupdesc
);
158 static void plperl_init_shared_libs(pTHX
);
159 static HV
*plperl_spi_execute_fetch_result(SPITupleTable
*, int, int);
160 static SV
*newSVstring(const char *str
);
161 static SV
**hv_store_string(HV
*hv
, const char *key
, SV
*val
);
162 static SV
**hv_fetch_string(HV
*hv
, const char *key
);
163 static SV
*plperl_create_sub(char *proname
, char *s
, bool trusted
);
164 static SV
*plperl_call_perl_func(plperl_proc_desc
*desc
, FunctionCallInfo fcinfo
);
167 * This routine is a crock, and so is everyplace that calls it. The problem
168 * is that the cached form of plperl functions/queries is allocated permanently
169 * (mostly via malloc()) and never released until backend exit. Subsidiary
170 * data structures such as fmgr info records therefore must live forever
171 * as well. A better implementation would store all this stuff in a per-
172 * function memory context that could be reclaimed at need. In the meantime,
173 * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
174 * it might allocate, and whatever the eventual function might allocate using
175 * fn_mcxt, will live forever too.
178 perm_fmgr_info(Oid functionId
, FmgrInfo
*finfo
)
180 fmgr_info_cxt(functionId
, finfo
, TopMemoryContext
);
185 * _PG_init() - library load-time initialization
187 * DO NOT make this static nor change its name!
192 /* Be sure we do initialization only once (should be redundant now) */
193 static bool inited
= false;
199 pg_bindtextdomain(TEXTDOMAIN
);
201 DefineCustomBoolVariable("plperl.use_strict",
202 gettext_noop("If true, trusted and untrusted Perl code will be compiled in strict mode."),
209 EmitWarningsOnPlaceholders("plperl");
211 MemSet(&hash_ctl
, 0, sizeof(hash_ctl
));
213 hash_ctl
.keysize
= NAMEDATALEN
;
214 hash_ctl
.entrysize
= sizeof(plperl_proc_entry
);
216 plperl_proc_hash
= hash_create("PLPerl Procedures",
221 hash_ctl
.entrysize
= sizeof(plperl_query_entry
);
222 plperl_query_hash
= hash_create("PLPerl Queries",
227 plperl_init_interp();
232 /* Each of these macros must represent a single string literal */
235 "SPI::bootstrap(); use vars qw(%_SHARED);" \
236 "sub ::plperl_warn { my $msg = shift; " \
237 " $msg =~ s/\\(eval \\d+\\) //g; &elog(&NOTICE, $msg); } " \
238 "$SIG{__WARN__} = \\&::plperl_warn; " \
239 "sub ::plperl_die { my $msg = shift; " \
240 " $msg =~ s/\\(eval \\d+\\) //g; die $msg; } " \
241 "$SIG{__DIE__} = \\&::plperl_die; " \
242 "sub ::mkunsafefunc {" \
243 " my $ret = eval(qq[ sub { $_[0] $_[1] } ]); " \
244 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }" \
246 "sub ::mk_strict_unsafefunc {" \
247 " my $ret = eval(qq[ sub { use strict; $_[0] $_[1] } ]); " \
248 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; } " \
249 "sub ::_plperl_to_pg_array {" \
250 " my $arg = shift; ref $arg eq 'ARRAY' || return $arg; " \
251 " my $res = ''; my $first = 1; " \
252 " foreach my $elem (@$arg) " \
254 " $res .= ', ' unless $first; $first = undef; " \
257 " $res .= _plperl_to_pg_array($elem); " \
259 " elsif (defined($elem)) " \
261 " my $str = qq($elem); " \
262 " $str =~ s/([\"\\\\])/\\\\$1/g; " \
263 " $res .= qq(\"$str\"); " \
267 " $res .= 'NULL' ; " \
270 " return qq({$res}); " \
273 #define SAFE_MODULE \
274 "require Safe; $Safe::VERSION"
277 * The temporary enabling of the caller opcode here is to work around a
278 * bug in perl 5.10, which unkindly changed the way its Safe.pm works, without
279 * notice. It is quite safe, as caller is informational only, and in any case
280 * we only enable it while we load the 'strict' module.
284 "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" \
285 "$PLContainer->permit_only(':default');" \
286 "$PLContainer->permit(qw[:base_math !:base_io sort time]);" \
287 "$PLContainer->share(qw[&elog &spi_exec_query &return_next " \
288 "&spi_query &spi_fetchrow &spi_cursor_close " \
289 "&spi_prepare &spi_exec_prepared &spi_query_prepared &spi_freeplan " \
290 "&_plperl_to_pg_array " \
291 "&DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %_SHARED ]);" \
292 "sub ::mksafefunc {" \
293 " my $ret = $PLContainer->reval(qq[sub { $_[0] $_[1] }]); " \
294 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }" \
295 "$PLContainer->permit(qw[require caller]); $PLContainer->reval('use strict;');" \
296 "$PLContainer->deny(qw[require caller]); " \
297 "sub ::mk_strict_safefunc {" \
298 " my $ret = $PLContainer->reval(qq[sub { BEGIN { strict->import(); } $_[0] $_[1] }]); " \
299 " $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }"
302 "use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" \
303 "$PLContainer->permit_only(':default');" \
304 "$PLContainer->share(qw[&elog &ERROR ]);" \
305 "sub ::mksafefunc { return $PLContainer->reval(qq[sub { " \
306 " elog(ERROR,'trusted Perl functions disabled - " \
307 " please upgrade Perl Safe module to version 2.09 or later');}]); }" \
308 "sub ::mk_strict_safefunc { return $PLContainer->reval(qq[sub { " \
309 " elog(ERROR,'trusted Perl functions disabled - " \
310 " please upgrade Perl Safe module to version 2.09 or later');}]); }"
312 #define TEST_FOR_MULTI \
314 "$Config{usemultiplicity} eq 'define' or " \
315 "($Config{usethreads} eq 'define' " \
316 " and $Config{useithreads} eq 'define')"
319 /********************************************************************
321 * We start out by creating a "held" interpreter that we can use in
322 * trusted or untrusted mode (but not both) as the need arises. Later, we
323 * assign that interpreter if it is available to either the trusted or
324 * untrusted interpreter. If it has already been assigned, and we need to
325 * create the other interpreter, we do that if we can, or error out.
326 * We detect if it is safe to run two interpreters during the setup of the
332 check_interp(bool trusted
)
334 if (interp_state
== INTERP_HELD
)
338 plperl_trusted_interp
= plperl_held_interp
;
339 interp_state
= INTERP_TRUSTED
;
343 plperl_untrusted_interp
= plperl_held_interp
;
344 interp_state
= INTERP_UNTRUSTED
;
346 plperl_held_interp
= NULL
;
347 trusted_context
= trusted
;
349 else if (interp_state
== INTERP_BOTH
||
350 (trusted
&& interp_state
== INTERP_TRUSTED
) ||
351 (!trusted
&& interp_state
== INTERP_UNTRUSTED
))
353 if (trusted_context
!= trusted
)
356 PERL_SET_CONTEXT(plperl_trusted_interp
);
358 PERL_SET_CONTEXT(plperl_untrusted_interp
);
359 trusted_context
= trusted
;
362 else if (can_run_two
)
364 PERL_SET_CONTEXT(plperl_held_interp
);
365 plperl_init_interp();
367 plperl_trusted_interp
= plperl_held_interp
;
369 plperl_untrusted_interp
= plperl_held_interp
;
370 interp_state
= INTERP_BOTH
;
371 plperl_held_interp
= NULL
;
372 trusted_context
= trusted
;
377 "cannot allocate second Perl interpreter on this platform");
383 restore_context(bool old_context
)
385 if (trusted_context
!= old_context
)
388 PERL_SET_CONTEXT(plperl_trusted_interp
);
390 PERL_SET_CONTEXT(plperl_untrusted_interp
);
391 trusted_context
= old_context
;
396 plperl_init_interp(void)
398 static char *embedding
[3] = {
406 * The perl library on startup does horrible things like call
407 * setlocale(LC_ALL,""). We have protected against that on most platforms
408 * by setting the environment appropriately. However, on Windows,
409 * setlocale() does not consult the environment, so we need to save the
410 * existing locale settings before perl has a chance to mangle them and
411 * restore them after its dirty deeds are done.
414 * http://msdn.microsoft.com/library/en-us/vclib/html/_crt_locale.asp
416 * It appears that we only need to do this on interpreter startup, and
417 * subsequent calls to the interpreter don't mess with the locale
420 * We restore them using Perl's POSIX::setlocale() function so that Perl
421 * doesn't have a different idea of the locale from Postgres.
433 loc
= setlocale(LC_COLLATE
, NULL
);
434 save_collate
= loc
? pstrdup(loc
) : NULL
;
435 loc
= setlocale(LC_CTYPE
, NULL
);
436 save_ctype
= loc
? pstrdup(loc
) : NULL
;
437 loc
= setlocale(LC_MONETARY
, NULL
);
438 save_monetary
= loc
? pstrdup(loc
) : NULL
;
439 loc
= setlocale(LC_NUMERIC
, NULL
);
440 save_numeric
= loc
? pstrdup(loc
) : NULL
;
441 loc
= setlocale(LC_TIME
, NULL
);
442 save_time
= loc
? pstrdup(loc
) : NULL
;
446 * The perl API docs state that PERL_SYS_INIT3 should be called before
447 * allocating interprters. Unfortunately, on some platforms this fails
448 * in the Perl_do_taint() routine, which is called when the platform is
449 * using the system's malloc() instead of perl's own. Other platforms,
450 * notably Windows, fail if PERL_SYS_INIT3 is not called. So we call it
451 * if it's available, unless perl is using the system malloc(), which is
452 * true when MYMALLOC is set.
454 #if defined(PERL_SYS_INIT3) && !defined(MYMALLOC)
455 /* only call this the first time through, as per perlembed man page */
456 if (interp_state
== INTERP_NONE
)
458 char *dummy_env
[1] = {NULL
};
460 PERL_SYS_INIT3(&nargs
, (char ***) &embedding
, (char ***) &dummy_env
);
464 plperl_held_interp
= perl_alloc();
465 if (!plperl_held_interp
)
466 elog(ERROR
, "could not allocate Perl interpreter");
468 perl_construct(plperl_held_interp
);
469 perl_parse(plperl_held_interp
, plperl_init_shared_libs
,
470 nargs
, embedding
, NULL
);
471 perl_run(plperl_held_interp
);
473 if (interp_state
== INTERP_NONE
)
477 res
= eval_pv(TEST_FOR_MULTI
, TRUE
);
478 can_run_two
= SvIV(res
);
479 interp_state
= INTERP_HELD
;
484 eval_pv("use POSIX qw(locale_h);", TRUE
); /* croak on failure */
486 if (save_collate
!= NULL
)
488 snprintf(buf
, sizeof(buf
), "setlocale(%s,'%s');",
489 "LC_COLLATE", save_collate
);
493 if (save_ctype
!= NULL
)
495 snprintf(buf
, sizeof(buf
), "setlocale(%s,'%s');",
496 "LC_CTYPE", save_ctype
);
500 if (save_monetary
!= NULL
)
502 snprintf(buf
, sizeof(buf
), "setlocale(%s,'%s');",
503 "LC_MONETARY", save_monetary
);
505 pfree(save_monetary
);
507 if (save_numeric
!= NULL
)
509 snprintf(buf
, sizeof(buf
), "setlocale(%s,'%s');",
510 "LC_NUMERIC", save_numeric
);
514 if (save_time
!= NULL
)
516 snprintf(buf
, sizeof(buf
), "setlocale(%s,'%s');",
517 "LC_TIME", save_time
);
527 plperl_safe_init(void)
532 res
= eval_pv(SAFE_MODULE
, FALSE
); /* TRUE = croak if failure */
534 safe_version
= SvNV(res
);
537 * We actually want to reject safe_version < 2.09, but it's risky to
538 * assume that floating-point comparisons are exact, so use a slightly
539 * smaller comparison value.
541 if (safe_version
< 2.0899)
543 /* not safe, so disallow all trusted funcs */
544 eval_pv(SAFE_BAD
, FALSE
);
548 eval_pv(SAFE_OK
, FALSE
);
549 if (GetDatabaseEncoding() == PG_UTF8
)
552 * Fill in just enough information to set up this perl function in
553 * the safe container and call it. For some reason not entirely
554 * clear, it prevents errors that can arise from the regex code
555 * later trying to load utf8 modules.
557 plperl_proc_desc desc
;
558 FunctionCallInfoData fcinfo
;
562 /* make sure we don't call ourselves recursively */
563 plperl_safe_init_done
= true;
565 /* compile the function */
566 func
= plperl_create_sub("utf8fix",
567 "return shift =~ /\\xa9/i ? 'true' : 'false' ;",
570 /* set up to call the function with a single text argument 'a' */
571 desc
.reference
= func
;
573 desc
.arg_is_rowtype
[0] = false;
574 fmgr_info(F_TEXTOUT
, &(desc
.arg_out_func
[0]));
576 fcinfo
.arg
[0] = CStringGetTextDatum("a");
577 fcinfo
.argnull
[0] = false;
579 /* and make the call */
580 ret
= plperl_call_perl_func(&desc
, &fcinfo
);
584 plperl_safe_init_done
= true;
588 * Perl likes to put a newline after its error messages; clean up such
591 strip_trailing_ws(const char *msg
)
593 char *res
= pstrdup(msg
);
594 int len
= strlen(res
);
596 while (len
> 0 && isspace((unsigned char) res
[len
- 1]))
602 /* Build a tuple from a hash. */
605 plperl_build_tuple_result(HV
*perlhash
, AttInMetadata
*attinmeta
)
607 TupleDesc td
= attinmeta
->tupdesc
;
614 values
= (char **) palloc0(td
->natts
* sizeof(char *));
616 hv_iterinit(perlhash
);
617 while ((val
= hv_iternextsv(perlhash
, &key
, &klen
)))
619 int attn
= SPI_fnumber(td
, key
);
621 if (attn
<= 0 || td
->attrs
[attn
- 1]->attisdropped
)
623 (errcode(ERRCODE_UNDEFINED_COLUMN
),
624 errmsg("Perl hash contains nonexistent column \"%s\"",
627 values
[attn
- 1] = SvPV(val
, PL_na
);
629 hv_iterinit(perlhash
);
631 tup
= BuildTupleFromCStrings(attinmeta
, values
);
637 * convert perl array to postgres string representation
640 plperl_convert_to_pg_array(SV
*src
)
651 count
= call_pv("::_plperl_to_pg_array", G_SCALAR
);
656 elog(ERROR
, "unexpected _plperl_to_pg_array failure");
666 /* Set up the arguments for a trigger call. */
669 plperl_trigger_build_args(FunctionCallInfo fcinfo
)
682 tdata
= (TriggerData
*) fcinfo
->context
;
683 tupdesc
= tdata
->tg_relation
->rd_att
;
685 relid
= DatumGetCString(
686 DirectFunctionCall1(oidout
,
687 ObjectIdGetDatum(tdata
->tg_relation
->rd_id
)
691 hv_store_string(hv
, "name", newSVstring(tdata
->tg_trigger
->tgname
));
692 hv_store_string(hv
, "relid", newSVstring(relid
));
694 if (TRIGGER_FIRED_BY_INSERT(tdata
->tg_event
))
697 if (TRIGGER_FIRED_FOR_ROW(tdata
->tg_event
))
698 hv_store_string(hv
, "new",
699 plperl_hash_from_tuple(tdata
->tg_trigtuple
,
702 else if (TRIGGER_FIRED_BY_DELETE(tdata
->tg_event
))
705 if (TRIGGER_FIRED_FOR_ROW(tdata
->tg_event
))
706 hv_store_string(hv
, "old",
707 plperl_hash_from_tuple(tdata
->tg_trigtuple
,
710 else if (TRIGGER_FIRED_BY_UPDATE(tdata
->tg_event
))
713 if (TRIGGER_FIRED_FOR_ROW(tdata
->tg_event
))
715 hv_store_string(hv
, "old",
716 plperl_hash_from_tuple(tdata
->tg_trigtuple
,
718 hv_store_string(hv
, "new",
719 plperl_hash_from_tuple(tdata
->tg_newtuple
,
723 else if (TRIGGER_FIRED_BY_TRUNCATE(tdata
->tg_event
))
728 hv_store_string(hv
, "event", newSVstring(event
));
729 hv_store_string(hv
, "argc", newSViv(tdata
->tg_trigger
->tgnargs
));
731 if (tdata
->tg_trigger
->tgnargs
> 0)
735 for (i
= 0; i
< tdata
->tg_trigger
->tgnargs
; i
++)
736 av_push(av
, newSVstring(tdata
->tg_trigger
->tgargs
[i
]));
737 hv_store_string(hv
, "args", newRV_noinc((SV
*) av
));
740 hv_store_string(hv
, "relname",
741 newSVstring(SPI_getrelname(tdata
->tg_relation
)));
743 hv_store_string(hv
, "table_name",
744 newSVstring(SPI_getrelname(tdata
->tg_relation
)));
746 hv_store_string(hv
, "table_schema",
747 newSVstring(SPI_getnspname(tdata
->tg_relation
)));
749 if (TRIGGER_FIRED_BEFORE(tdata
->tg_event
))
751 else if (TRIGGER_FIRED_AFTER(tdata
->tg_event
))
755 hv_store_string(hv
, "when", newSVstring(when
));
757 if (TRIGGER_FIRED_FOR_ROW(tdata
->tg_event
))
759 else if (TRIGGER_FIRED_FOR_STATEMENT(tdata
->tg_event
))
763 hv_store_string(hv
, "level", newSVstring(level
));
765 return newRV_noinc((SV
*) hv
);
769 /* Set up the new tuple returned from a trigger. */
772 plperl_modify_tuple(HV
*hvTD
, TriggerData
*tdata
, HeapTuple otup
)
787 tupdesc
= tdata
->tg_relation
->rd_att
;
789 svp
= hv_fetch_string(hvTD
, "new");
792 (errcode(ERRCODE_UNDEFINED_COLUMN
),
793 errmsg("$_TD->{new} does not exist")));
794 if (!SvOK(*svp
) || SvTYPE(*svp
) != SVt_RV
|| SvTYPE(SvRV(*svp
)) != SVt_PVHV
)
796 (errcode(ERRCODE_DATATYPE_MISMATCH
),
797 errmsg("$_TD->{new} is not a hash reference")));
798 hvNew
= (HV
*) SvRV(*svp
);
800 modattrs
= palloc(tupdesc
->natts
* sizeof(int));
801 modvalues
= palloc(tupdesc
->natts
* sizeof(Datum
));
802 modnulls
= palloc(tupdesc
->natts
* sizeof(char));
806 while ((val
= hv_iternextsv(hvNew
, &key
, &klen
)))
808 int attn
= SPI_fnumber(tupdesc
, key
);
814 if (attn
<= 0 || tupdesc
->attrs
[attn
- 1]->attisdropped
)
816 (errcode(ERRCODE_UNDEFINED_COLUMN
),
817 errmsg("Perl hash contains nonexistent column \"%s\"",
819 /* XXX would be better to cache these lookups */
820 getTypeInputInfo(tupdesc
->attrs
[attn
- 1]->atttypid
,
821 &typinput
, &typioparam
);
822 fmgr_info(typinput
, &finfo
);
823 atttypmod
= tupdesc
->attrs
[attn
- 1]->atttypmod
;
826 modvalues
[slotsused
] = InputFunctionCall(&finfo
,
830 modnulls
[slotsused
] = ' ';
834 modvalues
[slotsused
] = InputFunctionCall(&finfo
,
838 modnulls
[slotsused
] = 'n';
840 modattrs
[slotsused
] = attn
;
845 rtup
= SPI_modifytuple(tdata
->tg_relation
, otup
, slotsused
,
846 modattrs
, modvalues
, modnulls
);
853 elog(ERROR
, "SPI_modifytuple failed: %s",
854 SPI_result_code_string(SPI_result
));
861 * This is the only externally-visible part of the plperl call interface.
862 * The Postgres function and trigger managers call it to execute a
865 PG_FUNCTION_INFO_V1(plperl_call_handler
);
868 plperl_call_handler(PG_FUNCTION_ARGS
)
871 plperl_call_data
*save_call_data
;
873 save_call_data
= current_call_data
;
876 if (CALLED_AS_TRIGGER(fcinfo
))
877 retval
= PointerGetDatum(plperl_trigger_handler(fcinfo
));
879 retval
= plperl_func_handler(fcinfo
);
883 current_call_data
= save_call_data
;
888 current_call_data
= save_call_data
;
893 * This is the other externally visible function - it is called when CREATE
894 * FUNCTION is issued to validate the function being created/replaced.
896 PG_FUNCTION_INFO_V1(plperl_validator
);
899 plperl_validator(PG_FUNCTION_ARGS
)
901 Oid funcoid
= PG_GETARG_OID(0);
909 bool istrigger
= false;
912 /* Get the new function's pg_proc entry */
913 tuple
= SearchSysCache(PROCOID
,
914 ObjectIdGetDatum(funcoid
),
916 if (!HeapTupleIsValid(tuple
))
917 elog(ERROR
, "cache lookup failed for function %u", funcoid
);
918 proc
= (Form_pg_proc
) GETSTRUCT(tuple
);
920 functyptype
= get_typtype(proc
->prorettype
);
922 /* Disallow pseudotype result */
923 /* except for TRIGGER, RECORD, or VOID */
924 if (functyptype
== TYPTYPE_PSEUDO
)
926 /* we assume OPAQUE with no arguments means a trigger */
927 if (proc
->prorettype
== TRIGGEROID
||
928 (proc
->prorettype
== OPAQUEOID
&& proc
->pronargs
== 0))
930 else if (proc
->prorettype
!= RECORDOID
&&
931 proc
->prorettype
!= VOIDOID
)
933 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
934 errmsg("PL/Perl functions cannot return type %s",
935 format_type_be(proc
->prorettype
))));
938 /* Disallow pseudotypes in arguments (either IN or OUT) */
939 numargs
= get_func_arg_info(tuple
,
940 &argtypes
, &argnames
, &argmodes
);
941 for (i
= 0; i
< numargs
; i
++)
943 if (get_typtype(argtypes
[i
]) == TYPTYPE_PSEUDO
)
945 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
946 errmsg("PL/Perl functions cannot accept type %s",
947 format_type_be(argtypes
[i
]))));
950 ReleaseSysCache(tuple
);
952 /* Postpone body checks if !check_function_bodies */
953 if (check_function_bodies
)
955 (void) compile_plperl_function(funcoid
, istrigger
);
958 /* the result of a validator is ignored */
964 * Uses mksafefunc/mkunsafefunc to create an anonymous sub whose text is
965 * supplied in s, and returns a reference to the closure.
968 plperl_create_sub(char *proname
, char *s
, bool trusted
)
975 if (trusted
&& !plperl_safe_init_done
)
984 XPUSHs(sv_2mortal(newSVstring("our $_TD; local $_TD=$_[0]; shift;")));
985 XPUSHs(sv_2mortal(newSVstring(s
)));
989 * G_KEEPERR seems to be needed here, else we don't recognize compile
990 * errors properly. Perhaps it's because there's another level of eval
994 if (trusted
&& plperl_use_strict
)
995 compile_sub
= "::mk_strict_safefunc";
996 else if (plperl_use_strict
)
997 compile_sub
= "::mk_strict_unsafefunc";
999 compile_sub
= "::mksafefunc";
1001 compile_sub
= "::mkunsafefunc";
1003 count
= perl_call_pv(compile_sub
, G_SCALAR
| G_EVAL
| G_KEEPERR
);
1011 elog(ERROR
, "didn't get a return item from mksafefunc");
1021 (errcode(ERRCODE_SYNTAX_ERROR
),
1022 errmsg("creation of Perl function \"%s\" failed: %s",
1024 strip_trailing_ws(SvPV(ERRSV
, PL_na
)))));
1028 * need to make a deep copy of the return. it comes off the stack as a
1031 subref
= newSVsv(POPs
);
1033 if (!SvROK(subref
) || SvTYPE(SvRV(subref
)) != SVt_PVCV
)
1040 * subref is our responsibility because it is not mortal
1042 SvREFCNT_dec(subref
);
1043 elog(ERROR
, "didn't get a code ref");
1054 /**********************************************************************
1055 * plperl_init_shared_libs() -
1057 * We cannot use the DynaLoader directly to get at the Opcode
1058 * module (used by Safe.pm). So, we link Opcode into ourselves
1059 * and do the initialization behind perl's back.
1061 **********************************************************************/
1063 EXTERN_C
void boot_DynaLoader(pTHX_ CV
*cv
);
1064 EXTERN_C
void boot_SPI(pTHX_ CV
*cv
);
1067 plperl_init_shared_libs(pTHX
)
1069 char *file
= __FILE__
;
1071 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader
, file
);
1072 newXS("SPI::bootstrap", boot_SPI
, file
);
1077 plperl_call_perl_func(plperl_proc_desc
*desc
, FunctionCallInfo fcinfo
)
1090 XPUSHs(&PL_sv_undef
); /* no trigger data */
1092 for (i
= 0; i
< desc
->nargs
; i
++)
1094 if (fcinfo
->argnull
[i
])
1095 XPUSHs(&PL_sv_undef
);
1096 else if (desc
->arg_is_rowtype
[i
])
1102 HeapTupleData tmptup
;
1105 td
= DatumGetHeapTupleHeader(fcinfo
->arg
[i
]);
1106 /* Extract rowtype info and find a tupdesc */
1107 tupType
= HeapTupleHeaderGetTypeId(td
);
1108 tupTypmod
= HeapTupleHeaderGetTypMod(td
);
1109 tupdesc
= lookup_rowtype_tupdesc(tupType
, tupTypmod
);
1110 /* Build a temporary HeapTuple control structure */
1111 tmptup
.t_len
= HeapTupleHeaderGetDatumLength(td
);
1114 hashref
= plperl_hash_from_tuple(&tmptup
, tupdesc
);
1115 XPUSHs(sv_2mortal(hashref
));
1116 ReleaseTupleDesc(tupdesc
);
1122 tmp
= OutputFunctionCall(&(desc
->arg_out_func
[i
]),
1124 sv
= newSVstring(tmp
);
1125 XPUSHs(sv_2mortal(sv
));
1131 /* Do NOT use G_KEEPERR here */
1132 count
= perl_call_sv(desc
->reference
, G_SCALAR
| G_EVAL
);
1141 elog(ERROR
, "didn't get a return item from function");
1150 /* XXX need to find a way to assign an errcode here */
1152 (errmsg("error from Perl function \"%s\": %s",
1154 strip_trailing_ws(SvPV(ERRSV
, PL_na
)))));
1157 retval
= newSVsv(POPs
);
1168 plperl_call_perl_trigger_func(plperl_proc_desc
*desc
, FunctionCallInfo fcinfo
,
1173 Trigger
*tg_trigger
;
1184 tg_trigger
= ((TriggerData
*) fcinfo
->context
)->tg_trigger
;
1185 for (i
= 0; i
< tg_trigger
->tgnargs
; i
++)
1186 XPUSHs(sv_2mortal(newSVstring(tg_trigger
->tgargs
[i
])));
1189 /* Do NOT use G_KEEPERR here */
1190 count
= perl_call_sv(desc
->reference
, G_SCALAR
| G_EVAL
);
1199 elog(ERROR
, "didn't get a return item from trigger function");
1208 /* XXX need to find a way to assign an errcode here */
1210 (errmsg("error from Perl function \"%s\": %s",
1212 strip_trailing_ws(SvPV(ERRSV
, PL_na
)))));
1215 retval
= newSVsv(POPs
);
1226 plperl_func_handler(PG_FUNCTION_ARGS
)
1228 plperl_proc_desc
*prodesc
;
1232 SV
*array_ret
= NULL
;
1233 bool oldcontext
= trusted_context
;
1236 * Create the call_data beforing connecting to SPI, so that it is not
1237 * allocated in the SPI memory context
1239 current_call_data
= (plperl_call_data
*) palloc0(sizeof(plperl_call_data
));
1240 current_call_data
->fcinfo
= fcinfo
;
1242 if (SPI_connect() != SPI_OK_CONNECT
)
1243 elog(ERROR
, "could not connect to SPI manager");
1245 prodesc
= compile_plperl_function(fcinfo
->flinfo
->fn_oid
, false);
1246 current_call_data
->prodesc
= prodesc
;
1248 rsi
= (ReturnSetInfo
*) fcinfo
->resultinfo
;
1250 if (prodesc
->fn_retisset
)
1252 /* Check context before allowing the call to go through */
1253 if (!rsi
|| !IsA(rsi
, ReturnSetInfo
) ||
1254 (rsi
->allowedModes
& SFRM_Materialize
) == 0 ||
1255 rsi
->expectedDesc
== NULL
)
1257 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
1258 errmsg("set-valued function called in context that "
1259 "cannot accept a set")));
1262 check_interp(prodesc
->lanpltrusted
);
1264 perlret
= plperl_call_perl_func(prodesc
, fcinfo
);
1266 /************************************************************
1267 * Disconnect from SPI manager and then create the return
1268 * values datum (if the input function does a palloc for it
1269 * this must not be allocated in the SPI memory context
1270 * because SPI_finish would free it).
1271 ************************************************************/
1272 if (SPI_finish() != SPI_OK_FINISH
)
1273 elog(ERROR
, "SPI_finish() failed");
1275 if (prodesc
->fn_retisset
)
1278 * If the Perl function returned an arrayref, we pretend that it
1279 * called return_next() for each element of the array, to handle old
1280 * SRFs that didn't know about return_next(). Any other sort of return
1281 * value is an error, except undef which means return an empty set.
1283 if (SvOK(perlret
) &&
1284 SvTYPE(perlret
) == SVt_RV
&&
1285 SvTYPE(SvRV(perlret
)) == SVt_PVAV
)
1289 AV
*rav
= (AV
*) SvRV(perlret
);
1291 while ((svp
= av_fetch(rav
, i
, FALSE
)) != NULL
)
1293 plperl_return_next(*svp
);
1297 else if (SvOK(perlret
))
1300 (errcode(ERRCODE_DATATYPE_MISMATCH
),
1301 errmsg("set-returning PL/Perl function must return "
1302 "reference to array or use return_next")));
1305 rsi
->returnMode
= SFRM_Materialize
;
1306 if (current_call_data
->tuple_store
)
1308 rsi
->setResult
= current_call_data
->tuple_store
;
1309 rsi
->setDesc
= current_call_data
->ret_tdesc
;
1313 else if (!SvOK(perlret
))
1315 /* Return NULL if Perl code returned undef */
1316 if (rsi
&& IsA(rsi
, ReturnSetInfo
))
1317 rsi
->isDone
= ExprEndResult
;
1318 retval
= InputFunctionCall(&prodesc
->result_in_func
, NULL
,
1319 prodesc
->result_typioparam
, -1);
1320 fcinfo
->isnull
= true;
1322 else if (prodesc
->fn_retistuple
)
1324 /* Return a perl hash converted to a Datum */
1326 AttInMetadata
*attinmeta
;
1329 if (!SvOK(perlret
) || SvTYPE(perlret
) != SVt_RV
||
1330 SvTYPE(SvRV(perlret
)) != SVt_PVHV
)
1333 (errcode(ERRCODE_DATATYPE_MISMATCH
),
1334 errmsg("composite-returning PL/Perl function "
1335 "must return reference to hash")));
1338 /* XXX should cache the attinmeta data instead of recomputing */
1339 if (get_call_result_type(fcinfo
, NULL
, &td
) != TYPEFUNC_COMPOSITE
)
1342 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
1343 errmsg("function returning record called in context "
1344 "that cannot accept type record")));
1347 attinmeta
= TupleDescGetAttInMetadata(td
);
1348 tup
= plperl_build_tuple_result((HV
*) SvRV(perlret
), attinmeta
);
1349 retval
= HeapTupleGetDatum(tup
);
1353 /* Return a perl string converted to a Datum */
1356 if (prodesc
->fn_retisarray
&& SvROK(perlret
) &&
1357 SvTYPE(SvRV(perlret
)) == SVt_PVAV
)
1359 array_ret
= plperl_convert_to_pg_array(perlret
);
1360 SvREFCNT_dec(perlret
);
1361 perlret
= array_ret
;
1364 val
= SvPV(perlret
, PL_na
);
1366 retval
= InputFunctionCall(&prodesc
->result_in_func
, val
,
1367 prodesc
->result_typioparam
, -1);
1370 if (array_ret
== NULL
)
1371 SvREFCNT_dec(perlret
);
1373 current_call_data
= NULL
;
1374 restore_context(oldcontext
);
1381 plperl_trigger_handler(PG_FUNCTION_ARGS
)
1383 plperl_proc_desc
*prodesc
;
1388 bool oldcontext
= trusted_context
;
1391 * Create the call_data beforing connecting to SPI, so that it is not
1392 * allocated in the SPI memory context
1394 current_call_data
= (plperl_call_data
*) palloc0(sizeof(plperl_call_data
));
1395 current_call_data
->fcinfo
= fcinfo
;
1397 /* Connect to SPI manager */
1398 if (SPI_connect() != SPI_OK_CONNECT
)
1399 elog(ERROR
, "could not connect to SPI manager");
1401 /* Find or compile the function */
1402 prodesc
= compile_plperl_function(fcinfo
->flinfo
->fn_oid
, true);
1403 current_call_data
->prodesc
= prodesc
;
1405 check_interp(prodesc
->lanpltrusted
);
1407 svTD
= plperl_trigger_build_args(fcinfo
);
1408 perlret
= plperl_call_perl_trigger_func(prodesc
, fcinfo
, svTD
);
1409 hvTD
= (HV
*) SvRV(svTD
);
1411 /************************************************************
1412 * Disconnect from SPI manager and then create the return
1413 * values datum (if the input function does a palloc for it
1414 * this must not be allocated in the SPI memory context
1415 * because SPI_finish would free it).
1416 ************************************************************/
1417 if (SPI_finish() != SPI_OK_FINISH
)
1418 elog(ERROR
, "SPI_finish() failed");
1420 if (perlret
== NULL
|| !SvOK(perlret
))
1422 /* undef result means go ahead with original tuple */
1423 TriggerData
*trigdata
= ((TriggerData
*) fcinfo
->context
);
1425 if (TRIGGER_FIRED_BY_INSERT(trigdata
->tg_event
))
1426 retval
= (Datum
) trigdata
->tg_trigtuple
;
1427 else if (TRIGGER_FIRED_BY_UPDATE(trigdata
->tg_event
))
1428 retval
= (Datum
) trigdata
->tg_newtuple
;
1429 else if (TRIGGER_FIRED_BY_DELETE(trigdata
->tg_event
))
1430 retval
= (Datum
) trigdata
->tg_trigtuple
;
1431 else if (TRIGGER_FIRED_BY_TRUNCATE(trigdata
->tg_event
))
1432 retval
= (Datum
) trigdata
->tg_trigtuple
;
1434 retval
= (Datum
) 0; /* can this happen? */
1441 tmp
= SvPV(perlret
, PL_na
);
1443 if (pg_strcasecmp(tmp
, "SKIP") == 0)
1445 else if (pg_strcasecmp(tmp
, "MODIFY") == 0)
1447 TriggerData
*trigdata
= (TriggerData
*) fcinfo
->context
;
1449 if (TRIGGER_FIRED_BY_INSERT(trigdata
->tg_event
))
1450 trv
= plperl_modify_tuple(hvTD
, trigdata
,
1451 trigdata
->tg_trigtuple
);
1452 else if (TRIGGER_FIRED_BY_UPDATE(trigdata
->tg_event
))
1453 trv
= plperl_modify_tuple(hvTD
, trigdata
,
1454 trigdata
->tg_newtuple
);
1458 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED
),
1459 errmsg("ignoring modified row in DELETE trigger")));
1466 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED
),
1467 errmsg("result of PL/Perl trigger function must be undef, "
1468 "\"SKIP\", or \"MODIFY\"")));
1471 retval
= PointerGetDatum(trv
);
1476 SvREFCNT_dec(perlret
);
1478 current_call_data
= NULL
;
1479 restore_context(oldcontext
);
1484 static plperl_proc_desc
*
1485 compile_plperl_function(Oid fn_oid
, bool is_trigger
)
1488 Form_pg_proc procStruct
;
1489 char internal_proname
[NAMEDATALEN
];
1490 plperl_proc_desc
*prodesc
= NULL
;
1492 plperl_proc_entry
*hash_entry
;
1494 bool oldcontext
= trusted_context
;
1496 /* We'll need the pg_proc tuple in any case... */
1497 procTup
= SearchSysCache(PROCOID
,
1498 ObjectIdGetDatum(fn_oid
),
1500 if (!HeapTupleIsValid(procTup
))
1501 elog(ERROR
, "cache lookup failed for function %u", fn_oid
);
1502 procStruct
= (Form_pg_proc
) GETSTRUCT(procTup
);
1504 /************************************************************
1505 * Build our internal proc name from the function's Oid
1506 ************************************************************/
1508 sprintf(internal_proname
, "__PLPerl_proc_%u", fn_oid
);
1510 sprintf(internal_proname
, "__PLPerl_proc_%u_trigger", fn_oid
);
1512 /************************************************************
1513 * Lookup the internal proc name in the hashtable
1514 ************************************************************/
1515 hash_entry
= hash_search(plperl_proc_hash
, internal_proname
,
1522 prodesc
= hash_entry
->proc_data
;
1524 /************************************************************
1525 * If it's present, must check whether it's still up to date.
1526 * This is needed because CREATE OR REPLACE FUNCTION can modify the
1527 * function's pg_proc entry without changing its OID.
1528 ************************************************************/
1529 uptodate
= (prodesc
->fn_xmin
== HeapTupleHeaderGetXmin(procTup
->t_data
) &&
1530 ItemPointerEquals(&prodesc
->fn_tid
, &procTup
->t_self
));
1534 free(prodesc
->proname
);
1537 hash_search(plperl_proc_hash
, internal_proname
,
1542 /************************************************************
1543 * If we haven't found it in the hashtable, we analyze
1544 * the function's arguments and return type and store
1545 * the in-/out-functions in the prodesc block and create
1546 * a new hashtable entry for it.
1548 * Then we load the procedure into the Perl interpreter.
1549 ************************************************************/
1550 if (prodesc
== NULL
)
1554 Form_pg_language langStruct
;
1555 Form_pg_type typeStruct
;
1560 /************************************************************
1561 * Allocate a new procedure description block
1562 ************************************************************/
1563 prodesc
= (plperl_proc_desc
*) malloc(sizeof(plperl_proc_desc
));
1564 if (prodesc
== NULL
)
1566 (errcode(ERRCODE_OUT_OF_MEMORY
),
1567 errmsg("out of memory")));
1568 MemSet(prodesc
, 0, sizeof(plperl_proc_desc
));
1569 prodesc
->proname
= strdup(NameStr(procStruct
->proname
));
1570 prodesc
->fn_xmin
= HeapTupleHeaderGetXmin(procTup
->t_data
);
1571 prodesc
->fn_tid
= procTup
->t_self
;
1573 /* Remember if function is STABLE/IMMUTABLE */
1574 prodesc
->fn_readonly
=
1575 (procStruct
->provolatile
!= PROVOLATILE_VOLATILE
);
1577 /************************************************************
1578 * Lookup the pg_language tuple by Oid
1579 ************************************************************/
1580 langTup
= SearchSysCache(LANGOID
,
1581 ObjectIdGetDatum(procStruct
->prolang
),
1583 if (!HeapTupleIsValid(langTup
))
1585 free(prodesc
->proname
);
1587 elog(ERROR
, "cache lookup failed for language %u",
1588 procStruct
->prolang
);
1590 langStruct
= (Form_pg_language
) GETSTRUCT(langTup
);
1591 prodesc
->lanpltrusted
= langStruct
->lanpltrusted
;
1592 ReleaseSysCache(langTup
);
1594 /************************************************************
1595 * Get the required information for input conversion of the
1597 ************************************************************/
1600 typeTup
= SearchSysCache(TYPEOID
,
1601 ObjectIdGetDatum(procStruct
->prorettype
),
1603 if (!HeapTupleIsValid(typeTup
))
1605 free(prodesc
->proname
);
1607 elog(ERROR
, "cache lookup failed for type %u",
1608 procStruct
->prorettype
);
1610 typeStruct
= (Form_pg_type
) GETSTRUCT(typeTup
);
1612 /* Disallow pseudotype result, except VOID or RECORD */
1613 if (typeStruct
->typtype
== TYPTYPE_PSEUDO
)
1615 if (procStruct
->prorettype
== VOIDOID
||
1616 procStruct
->prorettype
== RECORDOID
)
1618 else if (procStruct
->prorettype
== TRIGGEROID
)
1620 free(prodesc
->proname
);
1623 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
1624 errmsg("trigger functions can only be called "
1629 free(prodesc
->proname
);
1632 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
1633 errmsg("PL/Perl functions cannot return type %s",
1634 format_type_be(procStruct
->prorettype
))));
1638 prodesc
->result_oid
= procStruct
->prorettype
;
1639 prodesc
->fn_retisset
= procStruct
->proretset
;
1640 prodesc
->fn_retistuple
= (procStruct
->prorettype
== RECORDOID
||
1641 typeStruct
->typtype
== TYPTYPE_COMPOSITE
);
1643 prodesc
->fn_retisarray
=
1644 (typeStruct
->typlen
== -1 && typeStruct
->typelem
);
1646 perm_fmgr_info(typeStruct
->typinput
, &(prodesc
->result_in_func
));
1647 prodesc
->result_typioparam
= getTypeIOParam(typeTup
);
1649 ReleaseSysCache(typeTup
);
1652 /************************************************************
1653 * Get the required information for output conversion
1654 * of all procedure arguments
1655 ************************************************************/
1658 prodesc
->nargs
= procStruct
->pronargs
;
1659 for (i
= 0; i
< prodesc
->nargs
; i
++)
1661 typeTup
= SearchSysCache(TYPEOID
,
1662 ObjectIdGetDatum(procStruct
->proargtypes
.values
[i
]),
1664 if (!HeapTupleIsValid(typeTup
))
1666 free(prodesc
->proname
);
1668 elog(ERROR
, "cache lookup failed for type %u",
1669 procStruct
->proargtypes
.values
[i
]);
1671 typeStruct
= (Form_pg_type
) GETSTRUCT(typeTup
);
1673 /* Disallow pseudotype argument */
1674 if (typeStruct
->typtype
== TYPTYPE_PSEUDO
)
1676 free(prodesc
->proname
);
1679 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
1680 errmsg("PL/Perl functions cannot accept type %s",
1681 format_type_be(procStruct
->proargtypes
.values
[i
]))));
1684 if (typeStruct
->typtype
== TYPTYPE_COMPOSITE
)
1685 prodesc
->arg_is_rowtype
[i
] = true;
1688 prodesc
->arg_is_rowtype
[i
] = false;
1689 perm_fmgr_info(typeStruct
->typoutput
,
1690 &(prodesc
->arg_out_func
[i
]));
1693 ReleaseSysCache(typeTup
);
1697 /************************************************************
1698 * create the text of the anonymous subroutine.
1699 * we do not use a named subroutine so that we can call directly
1700 * through the reference.
1701 ************************************************************/
1702 prosrcdatum
= SysCacheGetAttr(PROCOID
, procTup
,
1703 Anum_pg_proc_prosrc
, &isnull
);
1705 elog(ERROR
, "null prosrc");
1706 proc_source
= TextDatumGetCString(prosrcdatum
);
1708 /************************************************************
1709 * Create the procedure in the interpreter
1710 ************************************************************/
1712 check_interp(prodesc
->lanpltrusted
);
1714 prodesc
->reference
= plperl_create_sub(prodesc
->proname
,
1716 prodesc
->lanpltrusted
);
1718 restore_context(oldcontext
);
1721 if (!prodesc
->reference
) /* can this happen? */
1723 free(prodesc
->proname
);
1725 elog(ERROR
, "could not create internal procedure \"%s\"",
1729 hash_entry
= hash_search(plperl_proc_hash
, internal_proname
,
1730 HASH_ENTER
, &found
);
1731 hash_entry
->proc_data
= prodesc
;
1734 ReleaseSysCache(procTup
);
1740 /* Build a hash from all attributes of a given tuple. */
1743 plperl_hash_from_tuple(HeapTuple tuple
, TupleDesc tupdesc
)
1750 for (i
= 0; i
< tupdesc
->natts
; i
++)
1759 if (tupdesc
->attrs
[i
]->attisdropped
)
1762 attname
= NameStr(tupdesc
->attrs
[i
]->attname
);
1763 attr
= heap_getattr(tuple
, i
+ 1, tupdesc
, &isnull
);
1767 /* Store (attname => undef) and move on. */
1768 hv_store_string(hv
, attname
, newSV(0));
1772 /* XXX should have a way to cache these lookups */
1773 getTypeOutputInfo(tupdesc
->attrs
[i
]->atttypid
,
1774 &typoutput
, &typisvarlena
);
1776 outputstr
= OidOutputFunctionCall(typoutput
, attr
);
1778 hv_store_string(hv
, attname
, newSVstring(outputstr
));
1783 return newRV_noinc((SV
*) hv
);
1788 plperl_spi_exec(char *query
, int limit
)
1793 * Execute the query inside a sub-transaction, so we can cope with errors
1796 MemoryContext oldcontext
= CurrentMemoryContext
;
1797 ResourceOwner oldowner
= CurrentResourceOwner
;
1799 BeginInternalSubTransaction(NULL
);
1800 /* Want to run inside function's memory context */
1801 MemoryContextSwitchTo(oldcontext
);
1807 spi_rv
= SPI_execute(query
, current_call_data
->prodesc
->fn_readonly
,
1809 ret_hv
= plperl_spi_execute_fetch_result(SPI_tuptable
, SPI_processed
,
1812 /* Commit the inner transaction, return to outer xact context */
1813 ReleaseCurrentSubTransaction();
1814 MemoryContextSwitchTo(oldcontext
);
1815 CurrentResourceOwner
= oldowner
;
1818 * AtEOSubXact_SPI() should not have popped any SPI context, but just
1819 * in case it did, make sure we remain connected.
1821 SPI_restore_connection();
1827 /* Save error info */
1828 MemoryContextSwitchTo(oldcontext
);
1829 edata
= CopyErrorData();
1832 /* Abort the inner transaction */
1833 RollbackAndReleaseCurrentSubTransaction();
1834 MemoryContextSwitchTo(oldcontext
);
1835 CurrentResourceOwner
= oldowner
;
1838 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
1839 * have left us in a disconnected state. We need this hack to return
1840 * to connected state.
1842 SPI_restore_connection();
1844 /* Punt the error to Perl */
1845 croak("%s", edata
->message
);
1847 /* Can't get here, but keep compiler quiet */
1857 plperl_spi_execute_fetch_result(SPITupleTable
*tuptable
, int processed
,
1864 hv_store_string(result
, "status",
1865 newSVstring(SPI_result_code_string(status
)));
1866 hv_store_string(result
, "processed",
1867 newSViv(processed
));
1869 if (status
> 0 && tuptable
)
1876 for (i
= 0; i
< processed
; i
++)
1878 row
= plperl_hash_from_tuple(tuptable
->vals
[i
], tuptable
->tupdesc
);
1881 hv_store_string(result
, "rows",
1882 newRV_noinc((SV
*) rows
));
1885 SPI_freetuptable(tuptable
);
1892 * Note: plperl_return_next is called both in Postgres and Perl contexts.
1893 * We report any errors in Postgres fashion (via ereport). If called in
1894 * Perl context, it is SPI.xs's responsibility to catch the error and
1895 * convert to a Perl error. We assume (perhaps without adequate justification)
1896 * that we need not abort the current transaction if the Perl code traps the
1900 plperl_return_next(SV
*sv
)
1902 plperl_proc_desc
*prodesc
;
1903 FunctionCallInfo fcinfo
;
1905 MemoryContext old_cxt
;
1910 prodesc
= current_call_data
->prodesc
;
1911 fcinfo
= current_call_data
->fcinfo
;
1912 rsi
= (ReturnSetInfo
*) fcinfo
->resultinfo
;
1914 if (!prodesc
->fn_retisset
)
1916 (errcode(ERRCODE_SYNTAX_ERROR
),
1917 errmsg("cannot use return_next in a non-SETOF function")));
1919 if (prodesc
->fn_retistuple
&&
1920 !(SvOK(sv
) && SvTYPE(sv
) == SVt_RV
&& SvTYPE(SvRV(sv
)) == SVt_PVHV
))
1922 (errcode(ERRCODE_DATATYPE_MISMATCH
),
1923 errmsg("SETOF-composite-returning PL/Perl function "
1924 "must call return_next with reference to hash")));
1926 if (!current_call_data
->ret_tdesc
)
1930 Assert(!current_call_data
->tuple_store
);
1931 Assert(!current_call_data
->attinmeta
);
1934 * This is the first call to return_next in the current PL/Perl
1935 * function call, so memoize some lookups
1937 if (prodesc
->fn_retistuple
)
1938 (void) get_call_result_type(fcinfo
, NULL
, &tupdesc
);
1940 tupdesc
= rsi
->expectedDesc
;
1943 * Make sure the tuple_store and ret_tdesc are sufficiently
1946 old_cxt
= MemoryContextSwitchTo(rsi
->econtext
->ecxt_per_query_memory
);
1948 current_call_data
->ret_tdesc
= CreateTupleDescCopy(tupdesc
);
1949 current_call_data
->tuple_store
=
1950 tuplestore_begin_heap(rsi
->allowedModes
& SFRM_Materialize_Random
,
1952 if (prodesc
->fn_retistuple
)
1954 current_call_data
->attinmeta
=
1955 TupleDescGetAttInMetadata(current_call_data
->ret_tdesc
);
1958 MemoryContextSwitchTo(old_cxt
);
1962 * Producing the tuple we want to return requires making plenty of
1963 * palloc() allocations that are not cleaned up. Since this function can
1964 * be called many times before the current memory context is reset, we
1965 * need to do those allocations in a temporary context.
1967 if (!current_call_data
->tmp_cxt
)
1969 current_call_data
->tmp_cxt
=
1970 AllocSetContextCreate(rsi
->econtext
->ecxt_per_tuple_memory
,
1971 "PL/Perl return_next temporary cxt",
1972 ALLOCSET_DEFAULT_MINSIZE
,
1973 ALLOCSET_DEFAULT_INITSIZE
,
1974 ALLOCSET_DEFAULT_MAXSIZE
);
1977 old_cxt
= MemoryContextSwitchTo(current_call_data
->tmp_cxt
);
1979 if (prodesc
->fn_retistuple
)
1983 tuple
= plperl_build_tuple_result((HV
*) SvRV(sv
),
1984 current_call_data
->attinmeta
);
1986 /* Make sure to store the tuple in a long-lived memory context */
1987 MemoryContextSwitchTo(rsi
->econtext
->ecxt_per_query_memory
);
1988 tuplestore_puttuple(current_call_data
->tuple_store
, tuple
);
1989 MemoryContextSwitchTo(old_cxt
);
1998 char *val
= SvPV(sv
, PL_na
);
2000 ret
= InputFunctionCall(&prodesc
->result_in_func
, val
,
2001 prodesc
->result_typioparam
, -1);
2006 ret
= InputFunctionCall(&prodesc
->result_in_func
, NULL
,
2007 prodesc
->result_typioparam
, -1);
2011 /* Make sure to store the tuple in a long-lived memory context */
2012 MemoryContextSwitchTo(rsi
->econtext
->ecxt_per_query_memory
);
2013 tuplestore_putvalues(current_call_data
->tuple_store
,
2014 current_call_data
->ret_tdesc
,
2016 MemoryContextSwitchTo(old_cxt
);
2019 MemoryContextReset(current_call_data
->tmp_cxt
);
2024 plperl_spi_query(char *query
)
2029 * Execute the query inside a sub-transaction, so we can cope with errors
2032 MemoryContext oldcontext
= CurrentMemoryContext
;
2033 ResourceOwner oldowner
= CurrentResourceOwner
;
2035 BeginInternalSubTransaction(NULL
);
2036 /* Want to run inside function's memory context */
2037 MemoryContextSwitchTo(oldcontext
);
2044 /* Create a cursor for the query */
2045 plan
= SPI_prepare(query
, 0, NULL
);
2047 elog(ERROR
, "SPI_prepare() failed:%s",
2048 SPI_result_code_string(SPI_result
));
2050 portal
= SPI_cursor_open(NULL
, plan
, NULL
, NULL
, false);
2053 elog(ERROR
, "SPI_cursor_open() failed:%s",
2054 SPI_result_code_string(SPI_result
));
2055 cursor
= newSVstring(portal
->name
);
2057 /* Commit the inner transaction, return to outer xact context */
2058 ReleaseCurrentSubTransaction();
2059 MemoryContextSwitchTo(oldcontext
);
2060 CurrentResourceOwner
= oldowner
;
2063 * AtEOSubXact_SPI() should not have popped any SPI context, but just
2064 * in case it did, make sure we remain connected.
2066 SPI_restore_connection();
2072 /* Save error info */
2073 MemoryContextSwitchTo(oldcontext
);
2074 edata
= CopyErrorData();
2077 /* Abort the inner transaction */
2078 RollbackAndReleaseCurrentSubTransaction();
2079 MemoryContextSwitchTo(oldcontext
);
2080 CurrentResourceOwner
= oldowner
;
2083 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
2084 * have left us in a disconnected state. We need this hack to return
2085 * to connected state.
2087 SPI_restore_connection();
2089 /* Punt the error to Perl */
2090 croak("%s", edata
->message
);
2092 /* Can't get here, but keep compiler quiet */
2102 plperl_spi_fetchrow(char *cursor
)
2107 * Execute the FETCH inside a sub-transaction, so we can cope with errors
2110 MemoryContext oldcontext
= CurrentMemoryContext
;
2111 ResourceOwner oldowner
= CurrentResourceOwner
;
2113 BeginInternalSubTransaction(NULL
);
2114 /* Want to run inside function's memory context */
2115 MemoryContextSwitchTo(oldcontext
);
2119 Portal p
= SPI_cursor_find(cursor
);
2127 SPI_cursor_fetch(p
, true, 1);
2128 if (SPI_processed
== 0)
2130 SPI_cursor_close(p
);
2135 row
= plperl_hash_from_tuple(SPI_tuptable
->vals
[0],
2136 SPI_tuptable
->tupdesc
);
2138 SPI_freetuptable(SPI_tuptable
);
2141 /* Commit the inner transaction, return to outer xact context */
2142 ReleaseCurrentSubTransaction();
2143 MemoryContextSwitchTo(oldcontext
);
2144 CurrentResourceOwner
= oldowner
;
2147 * AtEOSubXact_SPI() should not have popped any SPI context, but just
2148 * in case it did, make sure we remain connected.
2150 SPI_restore_connection();
2156 /* Save error info */
2157 MemoryContextSwitchTo(oldcontext
);
2158 edata
= CopyErrorData();
2161 /* Abort the inner transaction */
2162 RollbackAndReleaseCurrentSubTransaction();
2163 MemoryContextSwitchTo(oldcontext
);
2164 CurrentResourceOwner
= oldowner
;
2167 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
2168 * have left us in a disconnected state. We need this hack to return
2169 * to connected state.
2171 SPI_restore_connection();
2173 /* Punt the error to Perl */
2174 croak("%s", edata
->message
);
2176 /* Can't get here, but keep compiler quiet */
2185 plperl_spi_cursor_close(char *cursor
)
2187 Portal p
= SPI_cursor_find(cursor
);
2190 SPI_cursor_close(p
);
2194 plperl_spi_prepare(char *query
, int argc
, SV
**argv
)
2196 plperl_query_desc
*qdesc
;
2197 plperl_query_entry
*hash_entry
;
2202 MemoryContext oldcontext
= CurrentMemoryContext
;
2203 ResourceOwner oldowner
= CurrentResourceOwner
;
2205 BeginInternalSubTransaction(NULL
);
2206 MemoryContextSwitchTo(oldcontext
);
2208 /************************************************************
2209 * Allocate the new querydesc structure
2210 ************************************************************/
2211 qdesc
= (plperl_query_desc
*) malloc(sizeof(plperl_query_desc
));
2212 MemSet(qdesc
, 0, sizeof(plperl_query_desc
));
2213 snprintf(qdesc
->qname
, sizeof(qdesc
->qname
), "%lx", (long) qdesc
);
2214 qdesc
->nargs
= argc
;
2215 qdesc
->argtypes
= (Oid
*) malloc(argc
* sizeof(Oid
));
2216 qdesc
->arginfuncs
= (FmgrInfo
*) malloc(argc
* sizeof(FmgrInfo
));
2217 qdesc
->argtypioparams
= (Oid
*) malloc(argc
* sizeof(Oid
));
2221 /************************************************************
2222 * Resolve argument type names and then look them up by oid
2223 * in the system cache, and remember the required information
2224 * for input conversion.
2225 ************************************************************/
2226 for (i
= 0; i
< argc
; i
++)
2233 parseTypeString(SvPV(argv
[i
], PL_na
), &typId
, &typmod
);
2235 getTypeInputInfo(typId
, &typInput
, &typIOParam
);
2237 qdesc
->argtypes
[i
] = typId
;
2238 perm_fmgr_info(typInput
, &(qdesc
->arginfuncs
[i
]));
2239 qdesc
->argtypioparams
[i
] = typIOParam
;
2242 /************************************************************
2243 * Prepare the plan and check for errors
2244 ************************************************************/
2245 plan
= SPI_prepare(query
, argc
, qdesc
->argtypes
);
2248 elog(ERROR
, "SPI_prepare() failed:%s",
2249 SPI_result_code_string(SPI_result
));
2251 /************************************************************
2252 * Save the plan into permanent memory (right now it's in the
2253 * SPI procCxt, which will go away at function end).
2254 ************************************************************/
2255 qdesc
->plan
= SPI_saveplan(plan
);
2256 if (qdesc
->plan
== NULL
)
2257 elog(ERROR
, "SPI_saveplan() failed: %s",
2258 SPI_result_code_string(SPI_result
));
2260 /* Release the procCxt copy to avoid within-function memory leak */
2263 /* Commit the inner transaction, return to outer xact context */
2264 ReleaseCurrentSubTransaction();
2265 MemoryContextSwitchTo(oldcontext
);
2266 CurrentResourceOwner
= oldowner
;
2269 * AtEOSubXact_SPI() should not have popped any SPI context, but just
2270 * in case it did, make sure we remain connected.
2272 SPI_restore_connection();
2278 free(qdesc
->argtypes
);
2279 free(qdesc
->arginfuncs
);
2280 free(qdesc
->argtypioparams
);
2283 /* Save error info */
2284 MemoryContextSwitchTo(oldcontext
);
2285 edata
= CopyErrorData();
2288 /* Abort the inner transaction */
2289 RollbackAndReleaseCurrentSubTransaction();
2290 MemoryContextSwitchTo(oldcontext
);
2291 CurrentResourceOwner
= oldowner
;
2294 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
2295 * have left us in a disconnected state. We need this hack to return
2296 * to connected state.
2298 SPI_restore_connection();
2300 /* Punt the error to Perl */
2301 croak("%s", edata
->message
);
2303 /* Can't get here, but keep compiler quiet */
2308 /************************************************************
2309 * Insert a hashtable entry for the plan and return
2310 * the key to the caller.
2311 ************************************************************/
2313 hash_entry
= hash_search(plperl_query_hash
, qdesc
->qname
,
2314 HASH_ENTER
, &found
);
2315 hash_entry
->query_data
= qdesc
;
2317 return newSVstring(qdesc
->qname
);
2321 plperl_spi_exec_prepared(char *query
, HV
*attr
, int argc
, SV
**argv
)
2330 plperl_query_desc
*qdesc
;
2331 plperl_query_entry
*hash_entry
;
2334 * Execute the query inside a sub-transaction, so we can cope with errors
2337 MemoryContext oldcontext
= CurrentMemoryContext
;
2338 ResourceOwner oldowner
= CurrentResourceOwner
;
2340 BeginInternalSubTransaction(NULL
);
2341 /* Want to run inside function's memory context */
2342 MemoryContextSwitchTo(oldcontext
);
2346 /************************************************************
2347 * Fetch the saved plan descriptor, see if it's o.k.
2348 ************************************************************/
2350 hash_entry
= hash_search(plperl_query_hash
, query
,
2352 if (hash_entry
== NULL
)
2353 elog(ERROR
, "spi_exec_prepared: Invalid prepared query passed");
2355 qdesc
= hash_entry
->query_data
;
2358 elog(ERROR
, "spi_exec_prepared: panic - plperl_query_hash value vanished");
2360 if (qdesc
->nargs
!= argc
)
2361 elog(ERROR
, "spi_exec_prepared: expected %d argument(s), %d passed",
2362 qdesc
->nargs
, argc
);
2364 /************************************************************
2365 * Parse eventual attributes
2366 ************************************************************/
2370 sv
= hv_fetch_string(attr
, "limit");
2371 if (*sv
&& SvIOK(*sv
))
2374 /************************************************************
2376 ************************************************************/
2379 nulls
= (char *) palloc(argc
);
2380 argvalues
= (Datum
*) palloc(argc
* sizeof(Datum
));
2388 for (i
= 0; i
< argc
; i
++)
2392 argvalues
[i
] = InputFunctionCall(&qdesc
->arginfuncs
[i
],
2393 SvPV(argv
[i
], PL_na
),
2394 qdesc
->argtypioparams
[i
],
2400 argvalues
[i
] = InputFunctionCall(&qdesc
->arginfuncs
[i
],
2402 qdesc
->argtypioparams
[i
],
2408 /************************************************************
2410 ************************************************************/
2411 spi_rv
= SPI_execute_plan(qdesc
->plan
, argvalues
, nulls
,
2412 current_call_data
->prodesc
->fn_readonly
, limit
);
2413 ret_hv
= plperl_spi_execute_fetch_result(SPI_tuptable
, SPI_processed
,
2421 /* Commit the inner transaction, return to outer xact context */
2422 ReleaseCurrentSubTransaction();
2423 MemoryContextSwitchTo(oldcontext
);
2424 CurrentResourceOwner
= oldowner
;
2427 * AtEOSubXact_SPI() should not have popped any SPI context, but just
2428 * in case it did, make sure we remain connected.
2430 SPI_restore_connection();
2436 /* Save error info */
2437 MemoryContextSwitchTo(oldcontext
);
2438 edata
= CopyErrorData();
2441 /* Abort the inner transaction */
2442 RollbackAndReleaseCurrentSubTransaction();
2443 MemoryContextSwitchTo(oldcontext
);
2444 CurrentResourceOwner
= oldowner
;
2447 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
2448 * have left us in a disconnected state. We need this hack to return
2449 * to connected state.
2451 SPI_restore_connection();
2453 /* Punt the error to Perl */
2454 croak("%s", edata
->message
);
2456 /* Can't get here, but keep compiler quiet */
2465 plperl_spi_query_prepared(char *query
, int argc
, SV
**argv
)
2470 plperl_query_desc
*qdesc
;
2471 plperl_query_entry
*hash_entry
;
2473 Portal portal
= NULL
;
2476 * Execute the query inside a sub-transaction, so we can cope with errors
2479 MemoryContext oldcontext
= CurrentMemoryContext
;
2480 ResourceOwner oldowner
= CurrentResourceOwner
;
2482 BeginInternalSubTransaction(NULL
);
2483 /* Want to run inside function's memory context */
2484 MemoryContextSwitchTo(oldcontext
);
2488 /************************************************************
2489 * Fetch the saved plan descriptor, see if it's o.k.
2490 ************************************************************/
2491 hash_entry
= hash_search(plperl_query_hash
, query
,
2493 if (hash_entry
== NULL
)
2494 elog(ERROR
, "spi_exec_prepared: Invalid prepared query passed");
2496 qdesc
= hash_entry
->query_data
;
2499 elog(ERROR
, "spi_query_prepared: panic - plperl_query_hash value vanished");
2501 if (qdesc
->nargs
!= argc
)
2502 elog(ERROR
, "spi_query_prepared: expected %d argument(s), %d passed",
2503 qdesc
->nargs
, argc
);
2505 /************************************************************
2507 ************************************************************/
2510 nulls
= (char *) palloc(argc
);
2511 argvalues
= (Datum
*) palloc(argc
* sizeof(Datum
));
2519 for (i
= 0; i
< argc
; i
++)
2523 argvalues
[i
] = InputFunctionCall(&qdesc
->arginfuncs
[i
],
2524 SvPV(argv
[i
], PL_na
),
2525 qdesc
->argtypioparams
[i
],
2531 argvalues
[i
] = InputFunctionCall(&qdesc
->arginfuncs
[i
],
2533 qdesc
->argtypioparams
[i
],
2539 /************************************************************
2541 ************************************************************/
2542 portal
= SPI_cursor_open(NULL
, qdesc
->plan
, argvalues
, nulls
,
2543 current_call_data
->prodesc
->fn_readonly
);
2550 elog(ERROR
, "SPI_cursor_open() failed:%s",
2551 SPI_result_code_string(SPI_result
));
2553 cursor
= newSVstring(portal
->name
);
2555 /* Commit the inner transaction, return to outer xact context */
2556 ReleaseCurrentSubTransaction();
2557 MemoryContextSwitchTo(oldcontext
);
2558 CurrentResourceOwner
= oldowner
;
2561 * AtEOSubXact_SPI() should not have popped any SPI context, but just
2562 * in case it did, make sure we remain connected.
2564 SPI_restore_connection();
2570 /* Save error info */
2571 MemoryContextSwitchTo(oldcontext
);
2572 edata
= CopyErrorData();
2575 /* Abort the inner transaction */
2576 RollbackAndReleaseCurrentSubTransaction();
2577 MemoryContextSwitchTo(oldcontext
);
2578 CurrentResourceOwner
= oldowner
;
2581 * If AtEOSubXact_SPI() popped any SPI context of the subxact, it will
2582 * have left us in a disconnected state. We need this hack to return
2583 * to connected state.
2585 SPI_restore_connection();
2587 /* Punt the error to Perl */
2588 croak("%s", edata
->message
);
2590 /* Can't get here, but keep compiler quiet */
2599 plperl_spi_freeplan(char *query
)
2602 plperl_query_desc
*qdesc
;
2603 plperl_query_entry
*hash_entry
;
2605 hash_entry
= hash_search(plperl_query_hash
, query
,
2607 if (hash_entry
== NULL
)
2608 elog(ERROR
, "spi_exec_prepared: Invalid prepared query passed");
2610 qdesc
= hash_entry
->query_data
;
2613 elog(ERROR
, "spi_exec_freeplan: panic - plperl_query_hash value vanished");
2616 * free all memory before SPI_freeplan, so if it dies, nothing will be
2619 hash_search(plperl_query_hash
, query
,
2623 free(qdesc
->argtypes
);
2624 free(qdesc
->arginfuncs
);
2625 free(qdesc
->argtypioparams
);
2632 * Create a new SV from a string assumed to be in the current database's
2636 newSVstring(const char *str
)
2640 sv
= newSVpv(str
, 0);
2641 #if PERL_BCDVERSION >= 0x5006000L
2642 if (GetDatabaseEncoding() == PG_UTF8
)
2649 * Store an SV into a hash table under a key that is a string assumed to be
2650 * in the current database's encoding.
2653 hv_store_string(HV
*hv
, const char *key
, SV
*val
)
2655 int32 klen
= strlen(key
);
2658 * This seems nowhere documented, but under Perl 5.8.0 and up, hv_store()
2659 * recognizes a negative klen parameter as meaning a UTF-8 encoded key. It
2660 * does not appear that hashes track UTF-8-ness of keys at all in Perl
2663 #if PERL_BCDVERSION >= 0x5008000L
2664 if (GetDatabaseEncoding() == PG_UTF8
)
2667 return hv_store(hv
, key
, klen
, val
, 0);
2671 * Fetch an SV from a hash table under a key that is a string assumed to be
2672 * in the current database's encoding.
2675 hv_fetch_string(HV
*hv
, const char *key
)
2677 int32 klen
= strlen(key
);
2679 /* See notes in hv_store_string */
2680 #if PERL_BCDVERSION >= 0x5008000L
2681 if (GetDatabaseEncoding() == PG_UTF8
)
2684 return hv_fetch(hv
, key
, klen
, 0);