32 #include "utils/fmgroids.h"
43 #define TEXTDOMAIN PG_TEXTDOMAIN("plperl")
47 #include "perlchunks.h"
50 #include "plperl_opmask.h"
127 #define increment_prodesc_refcount(prodesc) \
128 ((prodesc)->fn_refcount++)
129 #define decrement_prodesc_refcount(prodesc) \
131 Assert((prodesc)->fn_refcount > 0); \
132 if (--((prodesc)->fn_refcount) == 0) \
133 free_plperl_function(prodesc); \
237 static OP *(*pp_require_orig) (
pTHX) = NULL;
260 bool is_event_trigger);
276 int *ndims,
int *dims,
int cur_depth,
299 #if defined(WIN32) && PERL_VERSION_LT(5, 28, 0)
302 #define setlocale_perl(a,b) Perl_setlocale(a,b)
361 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."),
558 PerlInterpreter *interp = NULL;
572 interp_desc->
interp = NULL;
642 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
643 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")));
671 interp_desc->
interp = interp;
689 PERL_SET_CONTEXT(interp_desc->
interp);
704 static PerlInterpreter *
707 PerlInterpreter *plperl;
709 static char *embedding[3 + 2] = {
710 "",
"-e", PLC_PERLBOOT
744 save_collate = loc ?
pstrdup(loc) : NULL;
746 save_ctype = loc ?
pstrdup(loc) : NULL;
748 save_monetary = loc ?
pstrdup(loc) : NULL;
750 save_numeric = loc ?
pstrdup(loc) : NULL;
752 save_time = loc ?
pstrdup(loc) : NULL;
754 #define PLPERL_RESTORE_LOCALE(name, saved) \
756 if (saved != NULL) { setlocale_perl(name, saved); pfree(saved); } \
762 embedding[nargs++] =
"-e";
775 #if defined(PERL_SYS_INIT3) && !defined(MYMALLOC)
777 static int perl_sys_init_done;
780 if (!perl_sys_init_done)
782 char *dummy_env[1] = {NULL};
784 PERL_SYS_INIT3(&nargs, (
char ***) &embedding, (
char ***) &dummy_env);
797 perl_sys_init_done = 1;
804 plperl = perl_alloc();
806 elog(
ERROR,
"could not allocate Perl interpreter");
808 PERL_SET_CONTEXT(plperl);
809 perl_construct(plperl);
819 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
834 #ifdef PLPERL_ENABLE_OPMASK_EARLY
847 nargs, embedding, NULL) != 0)
849 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
851 errcontext(
"while parsing Perl initialization")));
853 if (perl_run(plperl) != 0)
855 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
857 errcontext(
"while running Perl initialization")));
859 #ifdef PLPERL_RESTORE_LOCALE
860 PLPERL_RESTORE_LOCALE(LC_COLLATE, save_collate);
861 PLPERL_RESTORE_LOCALE(LC_CTYPE, save_ctype);
862 PLPERL_RESTORE_LOCALE(LC_MONETARY, save_monetary);
863 PLPERL_RESTORE_LOCALE(LC_NUMERIC, save_numeric);
864 PLPERL_RESTORE_LOCALE(LC_TIME, save_time);
894 svp = hv_fetch(GvHVn(PL_incgv),
name,
len, 0);
898 DIE(
aTHX_ "Unable to load %s into plperl",
name);
920 if (interp && *interp)
935 if (PL_exit_flags & PERL_EXIT_DESTRUCT_END)
942 if (PL_endav && !PL_minus_c)
943 call_list(PL_scopestack_ix, PL_endav);
969 eval_pv(PLC_TRUSTED, FALSE);
972 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
981 eval_pv(
"my $a=chr(0x100); return $a =~ /\\xa9/i", FALSE);
984 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
1003 stash = gv_stashpv(
"DynaLoader", GV_ADDWARN);
1005 while ((sv = hv_iternextsv(stash, &
key, &klen)))
1009 SvREFCNT_dec(GvCV(sv));
1015 ++PL_sub_generation;
1016 hv_clear(PL_stashcache);
1027 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
1029 errcontext(
"while executing plperl.on_plperl_init")));
1050 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
1052 errcontext(
"while executing plperl.on_plperlu_init")));
1066 while (
len > 0 && isspace((
unsigned char)
res[
len - 1]))
1085 memset(nulls,
true,
sizeof(
bool) * td->
natts);
1087 hv_iterinit(perlhash);
1088 while ((he = hv_iternext(perlhash)))
1090 SV *
val = HeVAL(he);
1097 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1098 errmsg(
"Perl hash contains nonexistent column \"%s\"",
1102 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1103 errmsg(
"cannot set system attribute \"%s\"",
1116 hv_iterinit(perlhash);
1142 if (SvOK(sv) && SvROK(sv))
1144 if (SvTYPE(SvRV(sv)) == SVt_PVAV)
1146 else if (sv_isa(sv,
"PostgreSQL::InServer::ARRAY"))
1148 HV *hv = (HV *) SvRV(sv);
1151 if (*sav && SvOK(*sav) && SvROK(*sav) &&
1152 SvTYPE(SvRV(*sav)) == SVt_PVAV)
1155 elog(
ERROR,
"could not get array reference from PostgreSQL::InServer::ARRAY object");
1171 int *ndims,
int *dims,
int cur_depth,
1177 int len = av_len(
av) + 1;
1179 for (
i = 0;
i <
len;
i++)
1182 SV **svp = av_fetch(
av,
i, FALSE);
1190 AV *nav = (AV *) SvRV(sav);
1193 if (
i == 0 && *ndims == cur_depth)
1196 if (*astatep != NULL)
1198 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1199 errmsg(
"multidimensional arrays must have array expressions with matching dimensions")));
1201 if (cur_depth + 1 >
MAXDIM)
1203 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1204 errmsg(
"number of array dimensions exceeds the maximum allowed (%d)",
1207 dims[*ndims] = av_len(nav) + 1;
1210 else if (cur_depth >= *ndims ||
1211 av_len(nav) + 1 != dims[cur_depth])
1213 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1214 errmsg(
"multidimensional arrays must have array expressions with matching dimensions")));
1218 ndims, dims, cur_depth + 1,
1228 if (*ndims != cur_depth)
1230 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1231 errmsg(
"multidimensional arrays must have array expressions with matching dimensions")));
1242 if (*astatep == NULL)
1260 AV *nav = (AV *) SvRV(src);
1273 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1274 errmsg(
"cannot convert Perl array to non-array type %s",
1279 memset(dims, 0,
sizeof(dims));
1280 dims[0] = av_len(nav) + 1;
1285 &finfo, typioparam);
1291 for (
i = 0;
i < ndims;
i++)
1306 &typinput, typioparam);
1341 if (!sv || !SvOK(sv) || typid == VOIDOID)
1365 else if (SvTYPE(SvRV(sv)) == SVt_PVHV)
1374 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1375 errmsg(
"cannot convert Perl hash to non-composite type %s",
1382 isdomain = (typid != td->
tdtypeid);
1396 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1397 errmsg(
"function returning record called in context "
1398 "that cannot accept type record")));
1419 fcinfo, finfo, typioparam,
1457 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1458 errmsg(
"lookup failed for type %s", fqtypename)));
1469 &typoutput, &typisvarlena);
1491 Oid transform_funcid;
1508 &typdelim, &typioparam, &typoutputfunc);
1528 if (info->
ndims == 0)
1548 (void) hv_store(hv,
"array", 5,
av, 0);
1549 (void) hv_store(hv,
"typeoid", 7,
newSVuv(typid), 0);
1552 gv_stashpv(
"PostgreSQL::InServer::ARRAY", 0));
1574 if (nest >= info->
ndims - 1)
1578 for (
i = first;
i < last;
i += info->
nelems[nest + 1])
1583 av_push(result, ref);
1597 AV *result = newAV();
1599 for (
i = first;
i < last;
i++)
1607 av_push(result, newSV(0));
1725 when =
"INSTEAD OF";
1733 level =
"STATEMENT";
1778 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1779 errmsg(
"$_TD->{new} does not exist")));
1780 if (!SvOK(*svp) || !SvROK(*svp) || SvTYPE(SvRV(*svp)) != SVt_PVHV)
1782 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1783 errmsg(
"$_TD->{new} is not a hash reference")));
1784 hvNew = (HV *) SvRV(*svp);
1787 natts = tupdesc->
natts;
1790 modnulls = (
bool *)
palloc0(natts *
sizeof(
bool));
1791 modrepls = (
bool *)
palloc0(natts *
sizeof(
bool));
1794 while ((he = hv_iternext(hvNew)))
1797 SV *
val = HeVAL(he);
1803 (
errcode(ERRCODE_UNDEFINED_COLUMN),
1804 errmsg(
"Perl hash contains nonexistent column \"%s\"",
1808 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1809 errmsg(
"cannot set system attribute \"%s\"",
1811 if (attr->attgenerated)
1813 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1814 errmsg(
"cannot set generated column \"%s\"",
1823 &modnulls[attn - 1]);
1824 modrepls[attn - 1] =
true;
1860 MemSet(&this_call_data, 0,
sizeof(this_call_data));
1861 this_call_data.
fcinfo = fcinfo;
1906 MemSet(&this_call_data, 0,
sizeof(this_call_data));
1911 pl_error_context.
arg = NULL;
1920 MemSet(&flinfo, 0,
sizeof(flinfo));
1921 MemSet(&desc, 0,
sizeof(desc));
1922 fake_fcinfo->flinfo = &flinfo;
1926 desc.
proname =
"inline_code_block";
1940 this_call_data.
fcinfo = fake_fcinfo;
1941 this_call_data.
prodesc = &desc;
1951 elog(
ERROR,
"could not connect to SPI manager");
1958 elog(
ERROR,
"could not create internal procedure for anonymous code block");
1999 bool is_trigger =
false;
2000 bool is_event_trigger =
false;
2009 elog(
ERROR,
"cache lookup failed for function %u", funcoid);
2016 if (functyptype == TYPTYPE_PSEUDO)
2018 if (proc->prorettype == TRIGGEROID)
2020 else if (proc->prorettype == EVENT_TRIGGEROID)
2021 is_event_trigger =
true;
2022 else if (proc->prorettype != RECORDOID &&
2023 proc->prorettype != VOIDOID)
2025 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2026 errmsg(
"PL/Perl functions cannot return type %s",
2032 &argtypes, &argnames, &argmodes);
2033 for (
i = 0;
i < numargs;
i++)
2036 argtypes[
i] != RECORDOID)
2038 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2039 errmsg(
"PL/Perl functions cannot accept type %s",
2100 HV *pragma_hv = newHV();
2122 PUSHs(sv_2mortal(
cstr2sv(s)));
2130 count =
call_pv(
"PostgreSQL::InServer::mkfunc",
2131 G_SCALAR | G_EVAL | G_KEEPERR);
2136 SV *sub_rv = (SV *) POPs;
2138 if (sub_rv && SvROK(sub_rv) && SvTYPE(SvRV(sub_rv)) == SVt_PVCV)
2150 (
errcode(ERRCODE_SYNTAX_ERROR),
2155 (
errcode(ERRCODE_SYNTAX_ERROR),
2156 errmsg(
"didn't get a CODE reference from compiling function \"%s\"",
2170 char *file = __FILE__;
2173 newXS(
"PostgreSQL::InServer::Util::bootstrap",
2187 Oid *argtypes = NULL;
2194 EXTEND(sp, desc->
nargs);
2209 PUSHs(sv_2mortal(sv));
2230 PUSHs(sv_2mortal(sv));
2246 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2247 errmsg(
"didn't get a return item from function")));
2258 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2262 retval = newSVsv(POPs);
2287 TDsv =
get_sv(
"main::_TD", 0);
2290 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2291 errmsg(
"couldn't fetch $_TD")));
2297 EXTEND(sp, tg_trigger->
tgnargs);
2314 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2315 errmsg(
"didn't get a return item from trigger function")));
2326 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2330 retval = newSVsv(POPs);
2354 TDsv =
get_sv(
"main::_TD", 0);
2357 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2358 errmsg(
"couldn't fetch $_TD")));
2377 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2378 errmsg(
"didn't get a return item from trigger function")));
2389 (
errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
2393 retval = newSVsv(POPs);
2411 nonatomic = fcinfo->context &&
2416 elog(
ERROR,
"could not connect to SPI manager");
2435 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2436 errmsg(
"set-valued function called in context that cannot accept a set")));
2440 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2441 errmsg(
"materialize mode required, but it is not allowed in this context")));
2473 AV *rav = (AV *) SvRV(sav);
2475 while ((svp = av_fetch(rav,
i, FALSE)) != NULL)
2481 else if (SvOK(perlret))
2484 (
errcode(ERRCODE_DATATYPE_MISMATCH),
2485 errmsg(
"set-returning PL/Perl function must return "
2486 "reference to array or use return_next")));
2534 elog(
ERROR,
"could not connect to SPI manager");
2556 hvTD = (HV *) SvRV(svTD);
2567 if (perlret == NULL || !SvOK(perlret))
2605 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2606 errmsg(
"ignoring modified row in DELETE trigger")));
2613 (
errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
2614 errmsg(
"result of PL/Perl trigger function must be undef, "
2615 "\"SKIP\", or \"MODIFY\"")));
2642 elog(
ERROR,
"could not connect to SPI manager");
2673 if (proc_ptr && proc_ptr->
proc_ptr)
2732 elog(
ERROR,
"cache lookup failed for function %u", fn_oid);
2775 plperl_error_context.
arg =
NameStr(procStruct->proname);
2784 Datum protrftypes_datum;
2805 prodesc->
fn_cxt = proc_cxt;
2809 prodesc->
nargs = procStruct->pronargs;
2817 (procStruct->provolatile != PROVOLATILE_VOLATILE);
2821 Anum_pg_proc_protrftypes, &isnull);
2832 elog(
ERROR,
"cache lookup failed for language %u",
2833 procStruct->prolang);
2835 prodesc->
lang_oid = langStruct->oid;
2843 if (!is_trigger && !is_event_trigger)
2845 Oid rettype = procStruct->prorettype;
2849 elog(
ERROR,
"cache lookup failed for type %u", rettype);
2853 if (typeStruct->typtype == TYPTYPE_PSEUDO)
2855 if (rettype == VOIDOID ||
2856 rettype == RECORDOID)
2858 else if (rettype == TRIGGEROID ||
2859 rettype == EVENT_TRIGGEROID)
2861 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2862 errmsg(
"trigger functions can only be called "
2866 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2867 errmsg(
"PL/Perl functions cannot return type %s",
2888 if (!is_trigger && !is_event_trigger)
2892 for (
i = 0;
i < prodesc->
nargs;
i++)
2894 Oid argtype = procStruct->proargtypes.values[
i];
2898 elog(
ERROR,
"cache lookup failed for type %u", argtype);
2902 if (typeStruct->typtype == TYPTYPE_PSEUDO &&
2903 argtype != RECORDOID)
2905 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2906 errmsg(
"PL/Perl functions cannot accept type %s",
2920 if (IsTrueArrayType(typeStruct))
2935 Anum_pg_proc_prosrc);
2953 elog(
ERROR,
"could not create PL/Perl internal procedure");
3036 hv_ksplit(hv, tupdesc->
natts);
3038 for (
i = 0;
i < tupdesc->
natts;
i++)
3047 if (att->attisdropped)
3050 if (att->attgenerated)
3053 if (!include_generated)
3112 croak(
"SPI functions can not be used in END blocks");
3127 croak(
"SPI functions can not be used during function compilation");
3206 (processed > (uint64)
UV_MAX) ?
3207 newSVnv((
NV) processed) :
3210 if (status > 0 && tuptable)
3219 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3220 errmsg(
"query result has too many rows to fit in a Perl array")));
3223 av_extend(rows, processed);
3224 for (
i = 0;
i < processed;
i++)
3291 (
errcode(ERRCODE_SYNTAX_ERROR),
3292 errmsg(
"cannot use return_next in a non-SETOF function")));
3314 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3315 errmsg(
"function returning record called in context "
3316 "that cannot accept type record")));
3325 if (tupdesc == NULL || tupdesc->
natts != 1)
3326 elog(
ERROR,
"expected single-column result descriptor for non-composite SETOF result");
3353 "PL/Perl return_next temporary cxt",
3363 if (!(SvOK(sv) && SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV))
3365 (
errcode(ERRCODE_DATATYPE_MISMATCH),
3366 errmsg(
"SETOF-composite-returning PL/Perl function "
3367 "must call return_next with reference to hash")));
3438 elog(
ERROR,
"SPI_cursor_open() failed:%s",
3595 "PL/Perl spi_prepare query",
3601 qdesc->
nargs = argc;
3612 "PL/Perl spi_prepare workspace",
3621 for (
i = 0;
i < argc;
i++)
3749 if (hash_entry == NULL)
3750 elog(
ERROR,
"spi_exec_prepared: Invalid prepared query passed");
3754 elog(
ERROR,
"spi_exec_prepared: plperl query_hash value vanished");
3756 if (qdesc->
nargs != argc)
3757 elog(
ERROR,
"spi_exec_prepared: expected %d argument(s), %d passed",
3758 qdesc->
nargs, argc);
3767 if (sv && *sv && SvIOK(*sv))
3775 nulls = (
char *)
palloc(argc);
3784 for (
i = 0;
i < argc;
i++)
3795 nulls[
i] = isnull ?
'n' :
' ';
3872 if (hash_entry == NULL)
3873 elog(
ERROR,
"spi_query_prepared: Invalid prepared query passed");
3877 elog(
ERROR,
"spi_query_prepared: plperl query_hash value vanished");
3879 if (qdesc->
nargs != argc)
3880 elog(
ERROR,
"spi_query_prepared: expected %d argument(s), %d passed",
3881 qdesc->
nargs, argc);
3888 nulls = (
char *)
palloc(argc);
3897 for (
i = 0;
i < argc;
i++)
3908 nulls[
i] = isnull ?
'n' :
' ';
3922 elog(
ERROR,
"SPI_cursor_open() failed:%s",
3970 if (hash_entry == NULL)
3971 elog(
ERROR,
"spi_freeplan: Invalid prepared query passed");
3975 elog(
ERROR,
"spi_freeplan: plperl query_hash value vanished");
4057 char *
volatile cmsg = NULL;
4067 elog(level,
"%s", cmsg);
4106 hlen = -(int) strlen(hkey);
4107 ret = hv_store(hv, hkey, hlen,
val, 0);
4130 hlen = -(int) strlen(hkey);
4131 ret = hv_fetch(hv, hkey, hlen, 0);
4145 char *procname = (
char *)
arg;
4148 errcontext(
"PL/Perl function \"%s\"", procname);
4157 char *procname = (
char *)
arg;
4160 errcontext(
"compilation of PL/Perl function \"%s\"", procname);
4179 #if defined(WIN32) && PERL_VERSION_LT(5, 28, 0)
4188 #ifdef USE_LOCALE_CTYPE
4189 if (category == LC_CTYPE
4191 || category == LC_ALL
4198 if (category == LC_ALL)
4203 new_ctype(newctype);
4206 #ifdef USE_LOCALE_COLLATE
4207 if (category == LC_COLLATE
4209 || category == LC_ALL
4216 if (category == LC_ALL)
4221 new_collate(newcoll);
4225 #ifdef USE_LOCALE_NUMERIC
4226 if (category == LC_NUMERIC
4228 || category == LC_ALL
4235 if (category == LC_ALL)
4240 new_numeric(newnum);
#define DatumGetArrayTypeP(X)
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, int *dims, int *lbs, MemoryContext rcontext, bool release)
ArrayType * construct_empty_array(Oid elmtype)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
static Datum values[MAXATTR]
#define TextDatumGetCString(d)
#define PG_USED_FOR_ASSERTS_ONLY
#define MemSet(start, val, len)
#define OidIsValid(objectId)
const char * GetCommandTagName(CommandTag commandTag)
static void PGresult * res
elog(ERROR, "%s: %s", p2, msg)
void domain_check(Datum value, bool isnull, Oid domainType, void **extra, MemoryContext mcxt)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void * hash_seq_search(HASH_SEQ_STATUS *status)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
ErrorContextCallback * error_context_stack
void FlushErrorState(void)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
ErrorData * CopyErrorData(void)
#define ereport(elevel,...)
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
@ SFRM_Materialize_Random
bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid)
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
char * OidOutputFunctionCall(Oid functionId, Datum val)
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
#define OidFunctionCall1(functionId, arg1)
#define DatumGetHeapTupleHeader(X)
#define PG_GETARG_POINTER(n)
#define SizeForFunctionCallInfo(nargs)
#define DirectFunctionCall1(func, arg1)
#define LOCAL_FCINFO(name, nargs)
#define FunctionCall1(flinfo, arg1)
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
@ TYPEFUNC_COMPOSITE_DOMAIN
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
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)
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)
void MarkGUCPrefixReserved(const char *className)
bool check_function_bodies
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
#define HeapTupleIsValid(tuple)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define HeapTupleHeaderGetTypMod(tup)
#define HeapTupleHeaderGetTypeId(tup)
#define HeapTupleHeaderGetDatumLength(tup)
#define HeapTupleHeaderGetRawXmin(tup)
void on_proc_exit(pg_on_exit_callback function, Datum arg)
if(TABLE==NULL||TABLE_index==NULL)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Assert(fmt[strlen(fmt) - 1] !='\n')
Oid get_element_type(Oid typid)
bool type_is_rowtype(Oid typid)
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Oid get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Oid get_transform_tosql(Oid typid, Oid langid, List *trftypes)
void get_type_io_data(Oid typid, IOFuncSelector which_func, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *func)
char get_typtype(Oid typid)
Oid get_base_element_type(Oid typid)
Oid getTypeIOParam(HeapTuple typeTuple)
Oid get_transform_fromsql(Oid typid, Oid langid, List *trftypes)
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
char * pg_server_to_any(const char *s, int len, int encoding)
void MemoryContextReset(MemoryContext context)
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define ALLOCSET_SMALL_SIZES
#define CHECK_FOR_INTERRUPTS()
void pg_bindtextdomain(const char *domain)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
Datum oidout(PG_FUNCTION_ARGS)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
bool parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, Node *escontext)
FormData_pg_attribute * Form_pg_attribute
FormData_pg_language * Form_pg_language
List * oid_array_to_list(Datum datum)
FormData_pg_proc * Form_pg_proc
FormData_pg_type * Form_pg_type
static HTAB * plperl_interp_hash
static SV * plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo)
struct plperl_call_data plperl_call_data
static char plperl_opmask[MAXO]
static void plperl_event_trigger_handler(PG_FUNCTION_ARGS)
static bool plperl_use_strict
static void _sv_to_datum_finfo(Oid typid, FmgrInfo *finfo, Oid *typioparam)
static Datum plperl_func_handler(PG_FUNCTION_ARGS)
struct plperl_proc_key plperl_proc_key
SV * plperl_spi_query(char *query)
static HTAB * plperl_proc_hash
static void set_interp_require(bool trusted)
static bool plperl_ending
static void SvREFCNT_dec_current(SV *sv)
void plperl_return_next(SV *sv)
static SV * plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc, bool include_generated)
struct plperl_query_desc plperl_query_desc
SV * plperl_spi_query_prepared(char *query, int argc, SV **argv)
static plperl_interp_desc * plperl_active_interp
Datum plperlu_call_handler(PG_FUNCTION_ARGS)
static PerlInterpreter * plperl_held_interp
static HV * plperl_spi_execute_fetch_result(SPITupleTable *, uint64, int)
static void plperl_trusted_init(void)
static SV * make_array_ref(plperl_array_info *info, int first, int last)
HV * plperl_spi_exec(char *query, int limit)
void plperl_spi_rollback(void)
Datum plperl_inline_handler(PG_FUNCTION_ARGS)
static HeapTuple plperl_build_tuple_result(HV *perlhash, TupleDesc td)
struct plperl_proc_desc plperl_proc_desc
static void plperl_untrusted_init(void)
SV * plperl_spi_fetchrow(char *cursor)
static void plperl_create_sub(plperl_proc_desc *desc, const char *s, Oid fn_oid)
Datum plperl_validator(PG_FUNCTION_ARGS)
static void plperl_init_shared_libs(pTHX)
#define increment_prodesc_refcount(prodesc)
static char * hek2cstr(HE *he)
static void plperl_destroy_interp(PerlInterpreter **)
EXTERN_C void boot_DynaLoader(pTHX_ CV *cv)
static char * strip_trailing_ws(const char *msg)
static OP * pp_require_safe(pTHX)
HV * plperl_spi_exec_prepared(char *query, HV *attr, int argc, SV **argv)
#define setlocale_perl(a, b)
struct plperl_array_info plperl_array_info
char * plperl_sv_to_literal(SV *sv, char *fqtypename)
static void free_plperl_function(plperl_proc_desc *prodesc)
EXTERN_C void boot_PostgreSQL__InServer__Util(pTHX_ CV *cv)
static SV * plperl_event_trigger_build_args(FunctionCallInfo fcinfo)
static void check_spi_usage_allowed(void)
static SV * plperl_trigger_build_args(FunctionCallInfo fcinfo)
PG_FUNCTION_INFO_V1(plperl_call_handler)
SV * plperl_spi_prepare(char *query, int argc, SV **argv)
static SV * plperl_hash_from_datum(Datum attr)
static void select_perl_context(bool trusted)
static Datum plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod, FunctionCallInfo fcinfo, FmgrInfo *finfo, Oid typioparam, bool *isnull)
struct plperl_query_entry plperl_query_entry
static void plperl_fini(int code, Datum arg)
static void plperl_exec_callback(void *arg)
static void plperl_inline_callback(void *arg)
static SV * get_perl_array_ref(SV *sv)
static SV * plperl_call_perl_trigger_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo, SV *td)
static SV ** hv_fetch_string(HV *hv, const char *key)
#define decrement_prodesc_refcount(prodesc)
Datum plperlu_inline_handler(PG_FUNCTION_ARGS)
static void plperl_compile_callback(void *arg)
Datum plperlu_validator(PG_FUNCTION_ARGS)
void plperl_spi_freeplan(char *query)
static SV * plperl_ref_from_pg_array(Datum arg, Oid typid)
static Datum plperl_array_to_datum(SV *src, Oid typid, int32 typmod)
static char * plperl_on_init
static char * plperl_on_plperl_init
static SV * split_array(plperl_array_info *info, int first, int last, int nest)
static Datum plperl_trigger_handler(PG_FUNCTION_ARGS)
Datum plperl_call_handler(PG_FUNCTION_ARGS)
static SV ** hv_store_string(HV *hv, const char *key, SV *val)
static plperl_call_data * current_call_data
void plperl_util_elog(int level, SV *msg)
void plperl_spi_cursor_close(char *cursor)
static plperl_proc_desc * compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger)
static OP *(* pp_require_orig)(pTHX)
static HeapTuple plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup)
static void plperl_return_next_internal(SV *sv)
struct plperl_proc_ptr plperl_proc_ptr
struct plperl_interp_desc plperl_interp_desc
static bool validate_plperl_function(plperl_proc_ptr *proc_ptr, HeapTuple procTup)
static void plperl_call_perl_event_trigger_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo, SV *td)
static PerlInterpreter * plperl_init_interp(void)
static void array_to_datum_internal(AV *av, ArrayBuildState **astatep, int *ndims, int *dims, int cur_depth, Oid elemtypid, int32 typmod, FmgrInfo *finfo, Oid typioparam)
EXTERN_C void boot_PostgreSQL__InServer__SPI(pTHX_ CV *cv)
static char * plperl_on_plperlu_init
static Datum plperl_hash_to_datum(SV *src, TupleDesc td)
void plperl_spi_commit(void)
static void activate_interpreter(plperl_interp_desc *interp_desc)
static SV * cstr2sv(const char *str)
static void croak_cstr(const char *str)
static char * sv2cstr(SV *sv)
int pg_strcasecmp(const char *s1, const char *s2)
pqsigfunc pqsignal(int signo, pqsigfunc func)
void PinPortal(Portal portal)
void UnpinPortal(Portal portal)
void FloatExceptionHandler(SIGNAL_ARGS)
void check_stack_depth(void)
static Datum PointerGetDatum(const void *X)
static char * DatumGetCString(Datum X)
static Datum ObjectIdGetDatum(Oid X)
static Pointer DatumGetPointer(Datum X)
static Datum CStringGetDatum(const char *X)
#define PERL_UNUSED_VAR(x)
Datum regtypein(PG_FUNCTION_ARGS)
ResourceOwner CurrentResourceOwner
char * SPI_getrelname(Relation rel)
int SPI_fnumber(TupleDesc tupdesc, const char *fname)
int SPI_freeplan(SPIPlanPtr plan)
SPITupleTable * SPI_tuptable
Portal SPI_cursor_find(const char *name)
const char * SPI_result_code_string(int code)
void SPI_cursor_fetch(Portal portal, bool forward, long count)
int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount)
int SPI_register_trigger_data(TriggerData *tdata)
void SPI_freetuptable(SPITupleTable *tuptable)
Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only)
SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes)
int SPI_keepplan(SPIPlanPtr plan)
void SPI_cursor_close(Portal portal)
char * SPI_getnspname(Relation rel)
int SPI_connect_ext(int options)
int SPI_execute(const char *src, bool read_only, long tcount)
#define SPI_OPT_NONATOMIC
#define SPI_ERROR_NOATTRIBUTE
struct ErrorContextCallback * previous
void(* callback)(void *arg)
MemoryContext ecxt_per_query_memory
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
SetFunctionReturnMode returnMode
Tuplestorestate * setResult
plperl_proc_desc * prodesc
Tuplestorestate * tuple_store
unsigned long fn_refcount
plperl_interp_desc * interp
plperl_proc_desc * proc_ptr
char query_name[NAMEDATALEN]
plperl_query_desc * query_data
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
#define TRIGGER_FIRED_FOR_STATEMENT(event)
#define TRIGGER_FIRED_BY_DELETE(event)
#define TRIGGER_FIRED_BEFORE(event)
#define CALLED_AS_TRIGGER(fcinfo)
#define TRIGGER_FIRED_FOR_ROW(event)
#define TRIGGER_FIRED_AFTER(event)
#define TRIGGER_FIRED_BY_TRUNCATE(event)
#define TRIGGER_FIRED_BY_INSERT(event)
#define TRIGGER_FIRED_BY_UPDATE(event)
#define TRIGGER_FIRED_INSTEAD(event)
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
#define ReleaseTupleDesc(tupdesc)
#define TupleDescAttr(tupdesc, i)
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, bool noError)
void BeginInternalSubTransaction(const char *name)
void RollbackAndReleaseCurrentSubTransaction(void)
void ReleaseCurrentSubTransaction(void)