37 #include "utils/fmgroids.h"
48 #define TEXTDOMAIN PG_TEXTDOMAIN("plperl")
55 #include "perlchunks.h"
57 #include "plperl_opmask.h"
132 #define increment_prodesc_refcount(prodesc) \
133 ((prodesc)->refcount++)
134 #define decrement_prodesc_refcount(prodesc) \
136 if (--((prodesc)->refcount) <= 0) \
137 free_plperl_function(prodesc); \
262 bool is_event_trigger);
277 int *ndims,
int *dims,
int cur_depth,
300 static char *setlocale_perl(
int category,
char *
locale);
344 sv = HeSVKEY_force(he);
390 static bool inited =
false;
405 gettext_noop(
"If true, trusted and untrusted Perl code will be compiled in strict mode."),
419 gettext_noop(
"Perl initialization code to execute when a Perl interpreter is initialized."),
441 gettext_noop(
"Perl initialization code to execute once when plperl is first used."),
449 gettext_noop(
"Perl initialization code to execute once when plperlu is first used."),
461 memset(&hash_ctl, 0,
sizeof(hash_ctl));
464 plperl_interp_hash =
hash_create(
"PL/Perl interpreters",
469 memset(&hash_ctl, 0,
sizeof(hash_ctl));
472 plperl_proc_hash =
hash_create(
"PL/Perl procedures",
560 PerlInterpreter *interp =
NULL;
568 interp_desc =
hash_search(plperl_interp_hash, &user_id,
583 memset(&hash_ctl, 0,
sizeof(hash_ctl));
634 plperl_active_interp =
NULL;
645 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
646 errmsg(
"cannot allocate multiple Perl interpreters on this platform")));
659 newXS(
"PostgreSQL::InServer::SPI::bootstrap",
662 eval_pv(
"PostgreSQL::InServer::SPI::bootstrap()",
FALSE);
665 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
667 errcontext(
"while executing PostgreSQL::InServer::SPI::bootstrap")));
670 interp_desc->
interp = interp;
673 plperl_active_interp = interp_desc;
685 if (interp_desc && plperl_active_interp != interp_desc)
688 PERL_SET_CONTEXT(interp_desc->
interp);
691 plperl_active_interp = interp_desc;
703 static PerlInterpreter *
706 PerlInterpreter *plperl;
708 static char *embedding[3 + 2] = {
709 "",
"-e", PLC_PERLBOOT
742 loc = setlocale(LC_COLLATE,
NULL);
744 loc = setlocale(LC_CTYPE,
NULL);
746 loc = setlocale(LC_MONETARY,
NULL);
748 loc = setlocale(LC_NUMERIC,
NULL);
750 loc = setlocale(LC_TIME,
NULL);
753 #define PLPERL_RESTORE_LOCALE(name, saved) \
755 if (saved != NULL) { setlocale_perl(name, saved); pfree(saved); } \
761 embedding[nargs++] =
"-e";
774 #if defined(PERL_SYS_INIT3) && !defined(MYMALLOC)
776 static int perl_sys_init_done;
779 if (!perl_sys_init_done)
781 char *dummy_env[1] = {
NULL};
783 PERL_SYS_INIT3(&nargs, (
char ***) &embedding, (
char ***) &dummy_env);
796 perl_sys_init_done = 1;
803 plperl = perl_alloc();
805 elog(
ERROR,
"could not allocate Perl interpreter");
807 PERL_SET_CONTEXT(plperl);
808 perl_construct(plperl);
811 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
826 #ifdef PLPERL_ENABLE_OPMASK_EARLY
838 nargs, embedding,
NULL) != 0)
840 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
842 errcontext(
"while parsing Perl initialization")));
844 if (perl_run(plperl) != 0)
846 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
848 errcontext(
"while running Perl initialization")));
850 #ifdef PLPERL_RESTORE_LOCALE
851 PLPERL_RESTORE_LOCALE(LC_COLLATE, save_collate);
852 PLPERL_RESTORE_LOCALE(LC_CTYPE, save_ctype);
853 PLPERL_RESTORE_LOCALE(LC_MONETARY, save_monetary);
854 PLPERL_RESTORE_LOCALE(LC_NUMERIC, save_numeric);
855 PLPERL_RESTORE_LOCALE(LC_TIME, save_time);
880 name = SvPV(sv, len);
881 if (!(name && len > 0 && *name))
884 svp = hv_fetch(GvHVn(PL_incgv), name, len, 0);
888 DIE(
aTHX_ "Unable to load %s into plperl", name);
910 if (interp && *interp)
924 if (PL_exit_flags & PERL_EXIT_DESTRUCT_END)
931 if (PL_endav && !PL_minus_c)
932 call_list(PL_scopestack_ix, PL_endav);
960 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
969 eval_pv(
"my $a=chr(0x100); return $a =~ /\\xa9/i",
FALSE);
972 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
991 stash = gv_stashpv(
"DynaLoader", GV_ADDWARN);
993 while ((sv = hv_iternextsv(stash, &key, &klen)))
997 SvREFCNT_dec(GvCV(sv));
1003 ++PL_sub_generation;
1004 hv_clear(PL_stashcache);
1015 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
1017 errcontext(
"while executing plperl.on_plperl_init")));
1036 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
1038 errcontext(
"while executing plperl.on_plperlu_init")));
1050 int len = strlen(res);
1052 while (len > 0 && isspace((
unsigned char) res[len - 1]))
1070 memset(nulls,
true,
sizeof(
bool) * td->
natts);
1072 hv_iterinit(perlhash);
1073 while ((he = hv_iternext(perlhash)))
1075 SV *
val = HeVAL(he);
1079 if (attn <= 0 || td->attrs[attn - 1]->attisdropped)
1081 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1082 errmsg(
"Perl hash contains nonexistent column \"%s\"",
1086 td->
attrs[attn - 1]->atttypid,
1087 td->
attrs[attn - 1]->atttypmod,
1095 hv_iterinit(perlhash);
1119 if (SvOK(sv) && SvROK(sv))
1121 if (SvTYPE(SvRV(sv)) == SVt_PVAV)
1123 else if (sv_isa(sv,
"PostgreSQL::InServer::ARRAY"))
1125 HV *hv = (HV *) SvRV(sv);
1128 if (*sav && SvOK(*sav) && SvROK(*sav) &&
1129 SvTYPE(SvRV(*sav)) == SVt_PVAV)
1132 elog(
ERROR,
"could not get array reference from PostgreSQL::InServer::ARRAY object");
1143 int *ndims,
int *dims,
int cur_depth,
1148 int len = av_len(av) + 1;
1150 for (i = 0; i < len; i++)
1153 SV **svp = av_fetch(av, i,
FALSE);
1161 AV *nav = (AV *) SvRV(sav);
1164 if (cur_depth + 1 >
MAXDIM)
1166 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1167 errmsg(
"number of array dimensions (%d) exceeds the maximum allowed (%d)",
1168 cur_depth + 1,
MAXDIM)));
1171 if (i == 0 && *ndims == cur_depth)
1173 dims[*ndims] = av_len(nav) + 1;
1176 else if (av_len(nav) + 1 != dims[cur_depth])
1178 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1179 errmsg(
"multidimensional arrays must have array expressions with matching dimensions")));
1183 ndims, dims, cur_depth + 1,
1184 arraytypid, elemtypid, typmod,
1193 if (*ndims != cur_depth)
1195 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1196 errmsg(
"multidimensional arrays must have array expressions with matching dimensions")));
1230 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1231 errmsg(
"cannot convert Perl array to non-array type %s",
1238 memset(dims, 0,
sizeof(dims));
1239 dims[0] = av_len((AV *) SvRV(src)) + 1;
1243 typid, elemtypid, typmod,
1244 &finfo, typioparam);
1250 for (i = 0; i < ndims; i++)
1265 &typinput, typioparam);
1300 if (!sv || !SvOK(sv) || typid ==
VOIDOID)
1324 else if (SvTYPE(SvRV(sv)) == SVt_PVHV)
1332 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1333 errmsg(
"cannot convert Perl hash to non-composite type %s",
1340 if (fcinfo ==
NULL ||
1343 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1344 errmsg(
"function returning record called in context "
1345 "that cannot accept type record")));
1358 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1359 errmsg(
"PL/Perl function must return reference to hash or array")));
1395 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1396 errmsg(
"lookup failed for type %s", fqtypename)));
1407 &typoutput, &typisvarlena);
1428 Oid transform_funcid;
1440 &typlen, &typbyval, &typalign,
1441 &typdelim, &typioparam, &typoutputfunc);
1455 if (info->
ndims == 0)
1467 info->
nelems[0] = nitems;
1468 for (i = 1; i < info->
ndims; i++)
1475 (void) hv_store(hv,
"array", 5, av, 0);
1476 (void) hv_store(hv,
"typeoid", 7,
newSVuv(typid), 0);
1479 gv_stashpv(
"PostgreSQL::InServer::ARRAY", 0));
1500 if (nest >= info->
ndims - 1)
1504 for (i = first; i < last; i += info->
nelems[nest + 1])
1509 av_push(result, ref);
1522 AV *result = newAV();
1524 for (i = first; i < last; i++)
1532 av_push(result, newSV(0));
1547 av_push(result,
cstr2sv(val));
1643 when =
"INSTEAD OF";
1651 level =
"STATEMENT";
1698 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1699 errmsg(
"$_TD->{new} does not exist")));
1700 if (!SvOK(*svp) || !SvROK(*svp) || SvTYPE(SvRV(*svp)) != SVt_PVHV)
1702 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1703 errmsg(
"$_TD->{new} is not a hash reference")));
1704 hvNew = (HV *) SvRV(*svp);
1712 while ((he = hv_iternext(hvNew)))
1716 SV *
val = HeVAL(he);
1719 if (attn <= 0 || tupdesc->attrs[attn - 1]->attisdropped)
1721 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1722 errmsg(
"Perl hash contains nonexistent column \"%s\"",
1726 tupdesc->
attrs[attn - 1]->atttypid,
1727 tupdesc->
attrs[attn - 1]->atttypmod,
1733 modnulls[slotsused] = isnull ?
'n' :
' ';
1734 modattrs[slotsused] = attn;
1742 modattrs, modvalues, modnulls);
1749 elog(
ERROR,
"SPI_modifytuple failed: %s",
1776 MemSet(&this_call_data, 0,
sizeof(this_call_data));
1777 this_call_data.
fcinfo = fcinfo;
1781 current_call_data = &this_call_data;
1796 current_call_data = save_call_data;
1804 current_call_data = save_call_data;
1827 MemSet(&this_call_data, 0,
sizeof(this_call_data));
1840 MemSet(&fake_fcinfo, 0,
sizeof(fake_fcinfo));
1841 MemSet(&flinfo, 0,
sizeof(flinfo));
1842 MemSet(&desc, 0,
sizeof(desc));
1843 fake_fcinfo.
flinfo = &flinfo;
1847 desc.
proname =
"inline_code_block";
1861 this_call_data.
fcinfo = &fake_fcinfo;
1862 this_call_data.
prodesc = &desc;
1869 current_call_data = &this_call_data;
1872 elog(
ERROR,
"could not connect to SPI manager");
1879 elog(
ERROR,
"could not create internal procedure for anonymous code block");
1883 SvREFCNT_dec(perlret);
1892 current_call_data = save_call_data;
1901 current_call_data = save_call_data;
1927 bool is_trigger =
false;
1928 bool is_event_trigger =
false;
1937 elog(
ERROR,
"cache lookup failed for function %u", funcoid);
1948 (proc->prorettype ==
OPAQUEOID && proc->pronargs == 0))
1951 is_event_trigger =
true;
1952 else if (proc->prorettype !=
RECORDOID &&
1955 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1956 errmsg(
"PL/Perl functions cannot return type %s",
1962 &argtypes, &argnames, &argmodes);
1963 for (i = 0; i < numargs; i++)
1968 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1969 errmsg(
"PL/Perl functions cannot accept type %s",
2029 HV *pragma_hv = newHV();
2033 sprintf(subname,
"%s__%u", prodesc->
proname, fn_oid);
2042 PUSHs(sv_2mortal(
cstr2sv(subname)));
2051 PUSHs(sv_2mortal(
cstr2sv(s)));
2059 count = perl_call_pv(
"PostgreSQL::InServer::mkfunc",
2060 G_SCALAR | G_EVAL | G_KEEPERR);
2065 SV *sub_rv = (SV *) POPs;
2067 if (sub_rv && SvROK(sub_rv) && SvTYPE(SvRV(sub_rv)) == SVt_PVCV)
2079 (
errcode(ERRCODE_SYNTAX_ERROR),
2084 (
errcode(ERRCODE_SYNTAX_ERROR),
2085 errmsg(
"didn't get a CODE reference from compiling function \"%s\"",
2101 char *file = __FILE__;
2104 newXS(
"PostgreSQL::InServer::Util::bootstrap",
2124 EXTEND(sp, desc->
nargs);
2131 for (i = 0; i < desc->
nargs; i++)
2139 PUSHs(sv_2mortal(sv));
2160 PUSHs(sv_2mortal(sv));
2166 count = perl_call_sv(desc->
reference, G_SCALAR | G_EVAL);
2176 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2177 errmsg(
"didn't get a return item from function")));
2188 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2192 retval = newSVsv(POPs);
2216 TDsv =
get_sv(
"main::_TD", 0);
2219 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2220 errmsg(
"couldn't fetch $_TD")));
2226 EXTEND(sp, tg_trigger->
tgnargs);
2228 for (i = 0; i < tg_trigger->
tgnargs; i++)
2233 count = perl_call_sv(desc->
reference, G_SCALAR | G_EVAL);
2243 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2244 errmsg(
"didn't get a return item from trigger function")));
2255 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2259 retval = newSVsv(POPs);
2282 TDsv =
get_sv(
"main::_TD", 0);
2285 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2286 errmsg(
"couldn't fetch $_TD")));
2295 count = perl_call_sv(desc->
reference, G_SCALAR | G_EVAL);
2305 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2306 errmsg(
"didn't get a return item from trigger function")));
2317 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2321 retval = newSVsv(POPs);
2341 elog(
ERROR,
"could not connect to SPI manager");
2344 current_call_data->
prodesc = prodesc;
2362 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2363 errmsg(
"set-valued function called in context that "
2364 "cannot accept a set")));
2395 AV *rav = (AV *) SvRV(sav);
2397 while ((svp = av_fetch(rav, i,
FALSE)) !=
NULL)
2403 else if (SvOK(perlret))
2406 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2407 errmsg(
"set-returning PL/Perl function must return "
2408 "reference to array or use return_next")));
2436 SvREFCNT_dec(perlret);
2454 elog(
ERROR,
"could not connect to SPI manager");
2458 current_call_data->
prodesc = prodesc;
2471 hvTD = (HV *) SvRV(svTD);
2482 if (perlret ==
NULL || !SvOK(perlret))
2520 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2521 errmsg(
"ignoring modified row in DELETE trigger")));
2528 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2529 errmsg(
"result of PL/Perl trigger function must be undef, "
2530 "\"SKIP\", or \"MODIFY\"")));
2542 SvREFCNT_dec(perlret);
2557 elog(
ERROR,
"could not connect to SPI manager");
2561 current_call_data->
prodesc = prodesc;
2590 if (proc_ptr && proc_ptr->
proc_ptr)
2653 elog(
ERROR,
"cache lookup failed for function %u", fn_oid);
2659 plperl_error_context.
arg =
NameStr(procStruct->proname);
2667 proc_ptr =
hash_search(plperl_proc_hash, &proc_key,
2676 proc_ptr =
hash_search(plperl_proc_hash, &proc_key,
2690 if (prodesc ==
NULL)
2696 Datum protrftypes_datum;
2705 if (prodesc ==
NULL)
2707 (
errcode(ERRCODE_OUT_OF_MEMORY),
2708 errmsg(
"out of memory")));
2717 (
errcode(ERRCODE_OUT_OF_MEMORY),
2718 errmsg(
"out of memory")));
2745 elog(
ERROR,
"cache lookup failed for language %u",
2746 procStruct->prolang);
2757 if (!is_trigger && !is_event_trigger)
2765 elog(
ERROR,
"cache lookup failed for type %u",
2766 procStruct->prorettype);
2773 if (procStruct->prorettype ==
VOIDOID ||
2776 else if (procStruct->prorettype ==
TRIGGEROID ||
2781 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2782 errmsg(
"trigger functions can only be called "
2789 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2790 errmsg(
"PL/Perl functions cannot return type %s",
2795 prodesc->
result_oid = procStruct->prorettype;
2801 (typeStruct->typlen == -1 && typeStruct->typelem);
2813 if (!is_trigger && !is_event_trigger)
2815 prodesc->
nargs = procStruct->pronargs;
2816 for (i = 0; i < prodesc->
nargs; i++)
2823 elog(
ERROR,
"cache lookup failed for type %u",
2824 procStruct->proargtypes.values[i]);
2830 procStruct->proargtypes.values[i] !=
RECORDOID)
2834 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2835 errmsg(
"PL/Perl functions cannot accept type %s",
2840 procStruct->proargtypes.values[i] ==
RECORDOID)
2850 if (typeStruct->typelem != 0 && typeStruct->typlen == -1)
2886 elog(
ERROR,
"could not create PL/Perl internal procedure");
2894 proc_ptr =
hash_search(plperl_proc_hash, &proc_key,
2947 hv_ksplit(hv, tupdesc->
natts);
2949 for (i = 0; i < tupdesc->
natts; i++)
2957 if (tupdesc->
attrs[i]->attisdropped)
2995 &typoutput, &typisvarlena);
3016 croak(
"SPI functions can not be used in END blocks");
3107 (processed > (uint64)
UV_MAX) ?
3108 newSVnv((
NV) processed) :
3111 if (status > 0 && tuptable)
3120 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3121 errmsg(
"query result has too many rows to fit in a Perl array")));
3124 av_extend(rows, processed);
3125 for (i = 0; i < processed; i++)
3159 prodesc = current_call_data->
prodesc;
3160 fcinfo = current_call_data->
fcinfo;
3165 (
errcode(ERRCODE_SYNTAX_ERROR),
3166 errmsg(
"cannot use return_next in a non-SETOF function")));
3203 if (!current_call_data->
tmp_cxt)
3207 "PL/Perl return_next temporary cxt",
3219 if (!(SvOK(sv) && SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV))
3221 (
errcode(ERRCODE_DATATYPE_MISMATCH),
3222 errmsg(
"SETOF-composite-returning PL/Perl function "
3223 "must call return_next with reference to hash")));
3287 elog(
ERROR,
"SPI_cursor_open() failed:%s",
3462 "PL/Perl spi_prepare query",
3470 qdesc->
nargs = argc;
3481 "PL/Perl spi_prepare workspace",
3492 for (i = 0; i < argc; i++)
3631 if (hash_entry ==
NULL)
3632 elog(
ERROR,
"spi_exec_prepared: Invalid prepared query passed");
3636 elog(
ERROR,
"spi_exec_prepared: plperl query_hash value vanished");
3638 if (qdesc->
nargs != argc)
3639 elog(
ERROR,
"spi_exec_prepared: expected %d argument(s), %d passed",
3640 qdesc->
nargs, argc);
3649 if (sv && *sv && SvIOK(*sv))
3657 nulls = (
char *)
palloc(argc);
3666 for (i = 0; i < argc; i++)
3677 nulls[
i] = isnull ?
'n' :
' ';
3767 if (hash_entry ==
NULL)
3768 elog(
ERROR,
"spi_query_prepared: Invalid prepared query passed");
3772 elog(
ERROR,
"spi_query_prepared: plperl query_hash value vanished");
3774 if (qdesc->
nargs != argc)
3775 elog(
ERROR,
"spi_query_prepared: expected %d argument(s), %d passed",
3776 qdesc->
nargs, argc);
3783 nulls = (
char *)
palloc(argc);
3792 for (i = 0; i < argc; i++)
3803 nulls[
i] = isnull ?
'n' :
' ';
3817 elog(
ERROR,
"SPI_cursor_open() failed:%s",
3876 if (hash_entry ==
NULL)
3877 elog(
ERROR,
"spi_freeplan: Invalid prepared query passed");
3881 elog(
ERROR,
"spi_freeplan: plperl query_hash value vanished");
3913 hlen = -(int) strlen(hkey);
3914 ret = hv_store(hv, hkey, hlen, val, 0);
3936 hlen = -(int) strlen(hkey);
3937 ret = hv_fetch(hv, hkey, hlen, 0);
3951 char *procname = (
char *) arg;
3954 errcontext(
"PL/Perl function \"%s\"", procname);
3963 char *procname = (
char *) arg;
3966 errcontext(
"compilation of PL/Perl function \"%s\"", procname);
3985 setlocale_perl(
int category,
char *
locale)
3987 char *RETVAL = setlocale(category, locale);
3991 #ifdef USE_LOCALE_CTYPE
3992 if (category == LC_CTYPE
3994 || category == LC_ALL
4001 if (category == LC_ALL)
4002 newctype = setlocale(LC_CTYPE,
NULL);
4006 new_ctype(newctype);
4009 #ifdef USE_LOCALE_COLLATE
4010 if (category == LC_COLLATE
4012 || category == LC_ALL
4019 if (category == LC_ALL)
4020 newcoll = setlocale(LC_COLLATE,
NULL);
4024 new_collate(newcoll);
4028 #ifdef USE_LOCALE_NUMERIC
4029 if (category == LC_NUMERIC
4031 || category == LC_ALL
4038 if (category == LC_ALL)
4039 newnum = setlocale(LC_NUMERIC,
NULL);
4043 new_numeric(newnum);
int SPI_fnumber(TupleDesc tupdesc, const char *fname)
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)
static SV * plperl_ref_from_pg_array(Datum arg, Oid typid)
EXTERN_C void boot_PostgreSQL__InServer__SPI(pTHX_ CV *cv)
bool arg_is_rowtype[FUNC_MAX_ARGS]
Oid get_transform_fromsql(Oid typid, Oid langid, List *trftypes)
static char plperl_opmask[MAXO]
static PerlInterpreter * plperl_init_interp(void)
static bool validate_plperl_function(plperl_proc_ptr *proc_ptr, HeapTuple procTup)
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
static Datum plperl_func_handler(PG_FUNCTION_ARGS)
#define IsA(nodeptr, _type_)
void MemoryContextDelete(MemoryContext context)
static HTAB * plperl_proc_hash
#define decrement_prodesc_refcount(prodesc)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
struct plperl_call_data plperl_call_data
static SV * get_perl_array_ref(SV *sv)
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
static char * hek2cstr(HE *he)
static Datum plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod, FunctionCallInfo fcinfo, FmgrInfo *finfo, Oid typioparam, bool *isnull)
static Datum plperl_array_to_datum(SV *src, Oid typid, int32 typmod)
static char * plperl_on_init
static void plperl_init_shared_libs(pTHX)
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
static bool plperl_ending
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
static void select_perl_context(bool trusted)
EXTERN_C void boot_DynaLoader(pTHX_ CV *cv)
SV * plperl_spi_query(char *query)
static HeapTuple plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup)
#define TYPTYPE_COMPOSITE
void on_proc_exit(pg_on_exit_callback function, Datum arg)
ErrorData * CopyErrorData(void)
Oid get_element_type(Oid typid)
struct plperl_proc_desc plperl_proc_desc
#define PointerGetDatum(X)
ResourceOwner CurrentResourceOwner
char * pstrdup(const char *in)
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
void ReleaseCurrentSubTransaction(void)
static void set_interp_require(bool trusted)
struct plperl_interp_desc plperl_interp_desc
Form_pg_attribute * attrs
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define Anum_pg_proc_prosrc
Oid get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
FmgrInfo arg_out_func[FUNC_MAX_ARGS]
SV * plperl_spi_fetchrow(char *cursor)
SPITupleTable * SPI_tuptable
int errcode(int sqlerrcode)
static SV ** hv_fetch_string(HV *hv, const char *key)
char get_typtype(Oid typid)
#define MemSet(start, val, len)
static SV * plperl_hash_from_datum(Datum attr)
#define Anum_pg_proc_protrftypes
void plperl_spi_cursor_close(char *cursor)
static plperl_interp_desc * plperl_active_interp
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define PG_GETARG_POINTER(n)
void MemoryContextReset(MemoryContext context)
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
#define DirectFunctionCall1(func, arg1)
int pg_strcasecmp(const char *s1, const char *s2)
struct plperl_query_desc plperl_query_desc
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
FormData_pg_type * Form_pg_type
bool check_function_bodies
static SV ** hv_store_string(HV *hv, const char *key, SV *val)
#define TRIGGER_FIRED_AFTER(event)
Datum oidout(PG_FUNCTION_ARGS)
struct ErrorContextCallback * previous
#define OidIsValid(objectId)
#define DatumGetHeapTupleHeader(X)
SV * plperl_spi_prepare(char *query, int argc, SV **argv)
void FlushErrorState(void)
#define TRIGGER_FIRED_FOR_STATEMENT(event)
#define ALLOCSET_DEFAULT_MINSIZE
#define SearchSysCache1(cacheId, key1)
static void plperl_event_trigger_handler(PG_FUNCTION_ARGS)
#define ALLOCSET_SMALL_MINSIZE
char * pg_server_to_any(const char *s, int len, int encoding)
#define PERL_UNUSED_VAR(x)
static SV * split_array(plperl_array_info *info, int first, int last, int nest)
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Portal SPI_cursor_find(const char *name)
static void plperl_call_perl_event_trigger_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo, SV *td)
ErrorContextCallback * error_context_stack
#define HeapTupleHeaderGetTypMod(tup)
void plperl_spi_freeplan(char *query)
List * oid_array_to_list(Datum datum)
static void plperl_untrusted_init(void)
static Datum plperl_trigger_handler(PG_FUNCTION_ARGS)
void pfree(void *pointer)
static SV * make_array_ref(plperl_array_info *info, int first, int last)
#define TRIGGER_FIRED_BY_TRUNCATE(event)
#define ObjectIdGetDatum(X)
plperl_proc_desc * proc_ptr
#define DatumGetCString(X)
bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
void EmitWarningsOnPlaceholders(const char *className)
int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
#define OidFunctionCall1(functionId, arg1)
const char * SPI_result_code_string(int code)
void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
static plperl_proc_desc * compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger)
char query_name[NAMEDATALEN]
static OP *(* pp_require_orig)(pTHX)
int SPI_keepplan(SPIPlanPtr plan)
Datum plperl_call_handler(PG_FUNCTION_ARGS)
static void plperl_trusted_init(void)
void RollbackAndReleaseCurrentSubTransaction(void)
void check_stack_depth(void)
static void plperl_fini(int code, Datum arg)
#define CStringGetDatum(X)
static void activate_interpreter(plperl_interp_desc *interp_desc)
static Datum plperl_hash_to_datum(SV *src, TupleDesc td)
bool argnull[FUNC_MAX_ARGS]
MemoryContext CurrentMemoryContext
TupleDesc lookup_rowtype_tupdesc_noerror(Oid type_id, int32 typmod, bool noError)
bool type_is_rowtype(Oid typid)
static void plperl_exec_callback(void *arg)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum, Datum *Values, const char *Nulls)
#define increment_prodesc_refcount(prodesc)
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
#define ereport(elevel, rest)
MemoryContext TopMemoryContext
static void perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
char * plperl_sv_to_literal(SV *sv, char *fqtypename)
#define PROVOLATILE_VOLATILE
static SV * plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc)
#define ALLOCSET_SMALL_INITSIZE
#define heap_getattr(tup, attnum, tupleDesc, isnull)
void SPI_freetuptable(SPITupleTable *tuptable)
#define TRIGGER_FIRED_BY_DELETE(event)
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
#define TextDatumGetCString(d)
Datum regtypein(PG_FUNCTION_ARGS)
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
void * palloc0(Size size)
void DefineCustomStringVariable(const char *name, const char *short_desc, const char *long_desc, char **valueAddr, const char *bootValue, GucContext context, int flags, GucStringCheckHook check_hook, GucStringAssignHook assign_hook, GucShowHook show_hook)
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
SV * plperl_spi_query_prepared(char *query, int argc, SV **argv)
void ReleaseSysCache(HeapTuple tuple)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
static void free_plperl_function(plperl_proc_desc *prodesc)
static void croak_cstr(const char *str)
#define HeapTupleHeaderGetTypeId(tup)
Tuplestorestate * tuple_store
static void plperl_destroy_interp(PerlInterpreter **)
FormData_pg_proc * Form_pg_proc
static SV * cstr2sv(const char *str)
void parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok)
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
char * SPI_getrelname(Relation rel)
static void plperl_create_sub(plperl_proc_desc *desc, char *s, Oid fn_oid)
static void plperl_inline_callback(void *arg)
pqsigfunc pqsignal(int signum, pqsigfunc handler)
static SV * plperl_trigger_build_args(FunctionCallInfo fcinfo)
EXTERN_C void boot_PostgreSQL__InServer__Util(pTHX_ CV *cv)
SetFunctionReturnMode returnMode
#define HeapTupleIsValid(tuple)
static char * plperl_on_plperl_init
#define CALLED_AS_TRIGGER(fcinfo)
#define Assert(condition)
static bool plperl_use_strict
char * SPI_getnspname(Relation rel)
Oid arg_arraytype[FUNC_MAX_ARGS]
void BeginInternalSubTransaction(char *name)
void plperl_return_next(SV *sv)
static SV * plperl_event_trigger_build_args(FunctionCallInfo fcinfo)
#define HeapTupleHeaderGetRawXmin(tup)
static char * strip_trailing_ws(const char *msg)
#define HeapTupleGetDatum(tuple)
void * hash_seq_search(HASH_SEQ_STATUS *status)
static char * plperl_on_plperlu_init
MemoryContext ecxt_per_query_memory
struct plperl_proc_key plperl_proc_key
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
static HeapTuple plperl_build_tuple_result(HV *perlhash, TupleDesc td)
Oid get_transform_tosql(Oid typid, Oid langid, List *trftypes)
Tuplestorestate * setResult
#define DatumGetPointer(X)
static void check_spi_usage_allowed(void)
PG_FUNCTION_INFO_V1(plperl_call_handler)
#define TRIGGER_FIRED_BEFORE(event)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
static void plperl_compile_callback(void *arg)
int SPI_freeplan(SPIPlanPtr plan)
static Datum values[MAXATTR]
void SPI_cursor_close(Portal portal)
#define TRIGGER_FIRED_INSTEAD(event)
static PerlInterpreter * plperl_held_interp
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Oid get_base_element_type(Oid typid)
void SPI_restore_connection(void)
static OP * pp_require_safe(pTHX)
static HTAB * plperl_interp_hash
#define TRIGGER_FIRED_BY_INSERT(event)
void(* callback)(void *arg)
char * OidOutputFunctionCall(Oid functionId, Datum val)
#define ALLOCSET_SMALL_MAXSIZE
FormData_pg_language * Form_pg_language
Datum plperlu_validator(PG_FUNCTION_ARGS)
int errmsg(const char *fmt,...)
void list_free(List *list)
#define ALLOCSET_DEFAULT_INITSIZE
Datum plperl_inline_handler(PG_FUNCTION_ARGS)
void FloatExceptionHandler(SIGNAL_ARGS)
Oid getTypeIOParam(HeapTuple typeTuple)
void pg_bindtextdomain(const char *domain)
#define FunctionCall1(flinfo, arg1)
static HV * plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int)
struct plperl_query_entry plperl_query_entry
void SPI_cursor_fetch(Portal portal, bool forward, long count)
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
#define ALLOCSET_DEFAULT_MAXSIZE
plperl_proc_desc * prodesc
#define CHECK_FOR_INTERRUPTS()
HV * plperl_spi_exec(char *query, int limit)
static void _sv_to_datum_finfo(Oid typid, FmgrInfo *finfo, Oid *typioparam)
static void array_to_datum_internal(AV *av, ArrayBuildState *astate, int *ndims, int *dims, int cur_depth, Oid arraytypid, Oid elemtypid, int32 typmod, FmgrInfo *finfo, Oid typioparam)
#define HeapTupleGetOid(tuple)
static void static void status(const char *fmt,...) pg_attribute_printf(1
#define ReleaseTupleDesc(tupdesc)
plperl_interp_desc * interp
#define TRIGGER_FIRED_FOR_ROW(event)
struct plperl_array_info plperl_array_info
void DefineCustomBoolVariable(const char *name, const char *short_desc, const char *long_desc, bool *valueAddr, bool bootValue, GucContext context, int flags, GucBoolCheckHook check_hook, GucBoolAssignHook assign_hook, GucShowHook show_hook)
Datum plperl_validator(PG_FUNCTION_ARGS)
static plperl_call_data * current_call_data
#define TRIGGER_FIRED_BY_UPDATE(event)
Datum plperlu_call_handler(PG_FUNCTION_ARGS)
Datum plperlu_inline_handler(PG_FUNCTION_ARGS)
HV * plperl_spi_exec_prepared(char *query, HV *attr, int argc, SV **argv)
static SV * plperl_call_perl_trigger_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo, SV *td)
static char * sv2cstr(SV *sv)
static SV * plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
int SPI_execute(const char *src, bool read_only, long tcount)
struct plperl_proc_ptr plperl_proc_ptr
#define HeapTupleHeaderGetDatumLength(tup)
#define DatumGetArrayTypeP(X)
void get_type_io_data(Oid typid, IOFuncSelector which_func, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *func)
plperl_query_desc * query_data