aboutsummaryrefslogtreecommitdiff
path: root/src/pl/plperl/plperl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl/plperl/plperl.c')
-rw-r--r--src/pl/plperl/plperl.c240
1 files changed, 129 insertions, 111 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 49b5a9f1d65..c66c4dd3779 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -4,7 +4,7 @@
* IDENTIFICATION
*
* This software is copyrighted by Mark Hollomon
- * but is shameless cribbed from pltcl.c by Jan Weick.
+ * but is shameless cribbed from pltcl.c by Jan Weick.
*
* The author hereby grants permission to use, copy, modify,
* distribute, and license this software and its documentation
@@ -90,7 +90,7 @@ typedef struct plperl_proc_desc
Oid arg_out_elem[FUNC_MAX_ARGS];
int arg_out_len[FUNC_MAX_ARGS];
int arg_is_rel[FUNC_MAX_ARGS];
- SV* reference;
+ SV *reference;
} plperl_proc_desc;
@@ -117,9 +117,11 @@ static int plperl_firstcall = 1;
static int plperl_call_level = 0;
static int plperl_restart_in_progress = 0;
static PerlInterpreter *plperl_safe_interp = NULL;
-static HV *plperl_proc_hash = NULL;
+static HV *plperl_proc_hash = NULL;
+
#if REALLYHAVEITONTHEBALL
static Tcl_HashTable *plperl_query_hash = NULL;
+
#endif
/**********************************************************************
@@ -129,31 +131,32 @@ static void plperl_init_all(void);
static void plperl_init_safe_interp(void);
Datum plperl_call_handler(FmgrInfo *proinfo,
- FmgrValues *proargs, bool *isNull);
+ FmgrValues *proargs, bool *isNull);
static Datum plperl_func_handler(FmgrInfo *proinfo,
- FmgrValues *proargs, bool *isNull);
+ FmgrValues *proargs, bool *isNull);
-static SV* plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc);
+static SV *plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc);
static void plperl_init_shared_libs(void);
#ifdef REALLYHAVEITONTHEBALL
static HeapTuple plperl_trigger_handler(FmgrInfo *proinfo);
static int plperl_elog(ClientData cdata, Tcl_Interp *interp,
- int argc, char *argv[]);
-static int plperl_quote(ClientData cdata, Tcl_Interp *interp,
int argc, char *argv[]);
+static int plperl_quote(ClientData cdata, Tcl_Interp *interp,
+ int argc, char *argv[]);
static int plperl_SPI_exec(ClientData cdata, Tcl_Interp *interp,
- int argc, char *argv[]);
+ int argc, char *argv[]);
static int plperl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
- int argc, char *argv[]);
+ int argc, char *argv[]);
static int plperl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
- int argc, char *argv[]);
+ int argc, char *argv[]);
static void plperl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
- int tupno, HeapTuple tuple, TupleDesc tupdesc);
+ int tupno, HeapTuple tuple, TupleDesc tupdesc);
+
#endif
@@ -187,18 +190,17 @@ plperl_init_all(void)
if (plperl_proc_hash != NULL)
{
hv_undef(plperl_proc_hash);
- SvREFCNT_dec((SV*) plperl_proc_hash);
+ SvREFCNT_dec((SV *) plperl_proc_hash);
plperl_proc_hash = NULL;
}
/************************************************************
* Free the prepared query hash table
************************************************************/
+
/*
- if (plperl_query_hash != NULL)
- {
- }
- */
+ * if (plperl_query_hash != NULL) { }
+ */
/************************************************************
* Now recreate a new safe interpreter
@@ -217,7 +219,7 @@ static void
plperl_init_safe_interp(void)
{
- char *embedding[] = { "", "-e", "use DynaLoader; require Safe; SPI::bootstrap()", "0" };
+ char *embedding[] = {"", "-e", "use DynaLoader; require Safe; SPI::bootstrap()", "0"};
plperl_safe_interp = perl_alloc();
if (!plperl_safe_interp)
@@ -227,12 +229,12 @@ plperl_init_safe_interp(void)
perl_parse(plperl_safe_interp, plperl_init_shared_libs, 3, embedding, NULL);
perl_run(plperl_safe_interp);
-
+
/************************************************************
* Initialize the proc and query hash tables
************************* ***********************************/
- plperl_proc_hash = newHV();
+ plperl_proc_hash = newHV();
}
@@ -249,8 +251,8 @@ plperl_init_safe_interp(void)
/* keep non-static */
Datum
plperl_call_handler(FmgrInfo *proinfo,
- FmgrValues *proargs,
- bool *isNull)
+ FmgrValues *proargs,
+ bool *isNull)
{
Datum retval;
@@ -276,11 +278,13 @@ plperl_call_handler(FmgrInfo *proinfo,
************************************************************/
if (CurrentTriggerData == NULL)
retval = plperl_func_handler(proinfo, proargs, isNull);
- else {
+ else
+ {
elog(ERROR, "plperl: can't use perl in triggers yet.");
+
/*
- retval = (Datum) plperl_trigger_handler(proinfo);
- */
+ * retval = (Datum) plperl_trigger_handler(proinfo);
+ */
/* make the compiler happy */
retval = (Datum) 0;
}
@@ -293,15 +297,16 @@ plperl_call_handler(FmgrInfo *proinfo,
/**********************************************************************
* plperl_create_sub() - calls the perl interpreter to
- * create the anonymous subroutine whose text is in the SV.
- * Returns the SV containing the RV to the closure.
+ * create the anonymous subroutine whose text is in the SV.
+ * Returns the SV containing the RV to the closure.
**********************************************************************/
static
SV *
-plperl_create_sub(SV *s) {
+plperl_create_sub(SV * s)
+{
dSP;
- SV* subref = NULL;
+ SV *subref = NULL;
ENTER;
SAVETMPS;
@@ -309,7 +314,8 @@ plperl_create_sub(SV *s) {
perl_eval_sv(s, G_SCALAR | G_EVAL | G_KEEPERR);
SPAGAIN;
- if (SvTRUE(GvSV(errgv))) {
+ if (SvTRUE(GvSV(errgv)))
+ {
POPs;
PUTBACK;
FREETMPS;
@@ -318,15 +324,17 @@ plperl_create_sub(SV *s) {
}
/*
- * need to make a deep copy of the return.
- * it comes off the stack as a temporary.
+ * need to make a deep copy of the return. it comes off the stack as a
+ * temporary.
*/
subref = newSVsv(POPs);
- if (!SvROK(subref)) {
+ if (!SvROK(subref))
+ {
PUTBACK;
FREETMPS;
LEAVE;
+
/*
* subref is our responsibility because it is not mortal
*/
@@ -341,22 +349,23 @@ plperl_create_sub(SV *s) {
}
/**********************************************************************
- * plperl_init_shared_libs() -
+ * plperl_init_shared_libs() -
*
* We cannot use the DynaLoader directly to get at the Opcode
* module (used by Safe.pm). So, we link Opcode into ourselves
* and do the initialization behind perl's back.
- *
+ *
**********************************************************************/
-extern void boot_DynaLoader _((CV* cv));
-extern void boot_Opcode _((CV* cv));
-extern void boot_SPI _((CV* cv));
+extern void boot_DynaLoader _((CV * cv));
+extern void boot_Opcode _((CV * cv));
+extern void boot_SPI _((CV * cv));
static void
plperl_init_shared_libs(void)
{
- char *file = __FILE__;
+ char *file = __FILE__;
+
newXS("DynaLoader::bootstrap", boot_DynaLoader, file);
newXS("Opcode::bootstrap", boot_Opcode, file);
newXS("SPI::bootstrap", boot_SPI, file);
@@ -367,35 +376,40 @@ plperl_init_shared_libs(void)
* stored in the prodesc structure. massages the input parms properly
**********************************************************************/
static
-SV*
-plperl_call_perl_func (plperl_proc_desc * desc, FmgrValues *pargs)
+SV *
+plperl_call_perl_func(plperl_proc_desc * desc, FmgrValues *pargs)
{
dSP;
- SV* retval;
- int i;
- int count;
+ SV *retval;
+ int i;
+ int count;
ENTER;
SAVETMPS;
PUSHMARK(sp);
- for (i = 0; i < desc->nargs; i++) {
- if (desc->arg_is_rel[i]) {
+ for (i = 0; i < desc->nargs; i++)
+ {
+ if (desc->arg_is_rel[i])
+ {
+
/*
- * plperl_build_tuple_argument better return a
- * mortal SV.
- */
- SV* hashref = plperl_build_tuple_argument(
- ((TupleTableSlot *) (pargs->data[i]))->val,
- ((TupleTableSlot *) (pargs->data[i]))->ttc_tupleDescriptor);
+ * plperl_build_tuple_argument better return a mortal SV.
+ */
+ SV *hashref = plperl_build_tuple_argument(
+ ((TupleTableSlot *) (pargs->data[i]))->val,
+ ((TupleTableSlot *) (pargs->data[i]))->ttc_tupleDescriptor);
+
XPUSHs(hashref);
- } else {
- char *tmp = (*fmgr_faddr(&(desc->arg_out_func[i])))
- (pargs->data[i],
- desc->arg_out_elem[i],
- desc->arg_out_len[i]);
+ }
+ else
+ {
+ char *tmp = (*fmgr_faddr(&(desc->arg_out_func[i])))
+ (pargs->data[i],
+ desc->arg_out_elem[i],
+ desc->arg_out_len[i]);
XPUSHs(sv_2mortal(newSVpv(tmp, 0)));
pfree(tmp);
@@ -406,17 +420,19 @@ plperl_call_perl_func (plperl_proc_desc * desc, FmgrValues *pargs)
SPAGAIN;
- if (count !=1) {
- PUTBACK ;
- FREETMPS ;
+ if (count != 1)
+ {
+ PUTBACK;
+ FREETMPS;
LEAVE;
elog(ERROR, "plperl : didn't get a return item from function");
}
- if (SvTRUE(GvSV(errgv))) {
+ if (SvTRUE(GvSV(errgv)))
+ {
POPs;
- PUTBACK ;
- FREETMPS ;
+ PUTBACK;
+ FREETMPS;
LEAVE;
elog(ERROR, "plperl : error from function : %s", SvPV(GvSV(errgv), na));
}
@@ -424,9 +440,9 @@ plperl_call_perl_func (plperl_proc_desc * desc, FmgrValues *pargs)
retval = newSVsv(POPs);
- PUTBACK ;
- FREETMPS ;
- LEAVE ;
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
return retval;
@@ -438,16 +454,16 @@ plperl_call_perl_func (plperl_proc_desc * desc, FmgrValues *pargs)
**********************************************************************/
static Datum
plperl_func_handler(FmgrInfo *proinfo,
- FmgrValues *proargs,
- bool *isNull)
+ FmgrValues *proargs,
+ bool *isNull)
{
int i;
char internal_proname[512];
- int proname_len;
+ int proname_len;
char *stroid;
plperl_proc_desc *prodesc;
- SV* perlret;
- Datum retval;
+ SV *perlret;
+ Datum retval;
sigjmp_buf save_restart;
/************************************************************
@@ -462,7 +478,7 @@ plperl_func_handler(FmgrInfo *proinfo,
/************************************************************
* Lookup the internal proc name in the hashtable
************************************************************/
- if (! hv_exists(plperl_proc_hash, internal_proname, proname_len))
+ if (!hv_exists(plperl_proc_hash, internal_proname, proname_len))
{
/************************************************************
* If we haven't found it in the hashtable, we analyze
@@ -476,7 +492,7 @@ plperl_func_handler(FmgrInfo *proinfo,
HeapTuple typeTup;
Form_pg_proc procStruct;
Form_pg_type typeStruct;
- SV * proc_internal_def;
+ SV *proc_internal_def;
char proc_internal_args[4096];
char *proc_source;
@@ -564,16 +580,17 @@ plperl_func_handler(FmgrInfo *proinfo,
*
************************************************************/
proc_source = textout(&(procStruct->prosrc));
+
/*
- * the string has been split for readbility.
- * please don't put commas between them. Hope everyone is ANSI
+ * the string has been split for readbility. please don't put
+ * commas between them. Hope everyone is ANSI
*/
proc_internal_def = newSVpvf(
- "$::x = new Safe;"
- "$::x->permit_only(':default');"
- "$::x->share(qw[&elog &DEBUG &NOTICE &NOIND &ERROR]);"
- "use strict;"
- "return $::x->reval( q[ sub { %s } ]);", proc_source);
+ "$::x = new Safe;"
+ "$::x->permit_only(':default');"
+ "$::x->share(qw[&elog &DEBUG &NOTICE &NOIND &ERROR]);"
+ "use strict;"
+ "return $::x->reval( q[ sub { %s } ]);", proc_source);
pfree(proc_source);
@@ -592,8 +609,8 @@ plperl_func_handler(FmgrInfo *proinfo,
/************************************************************
* Add the proc description block to the hashtable
************************************************************/
- hv_store(plperl_proc_hash, internal_proname, proname_len,
- newSViv((IV)prodesc), 0);
+ hv_store(plperl_proc_hash, internal_proname, proname_len,
+ newSViv((IV) prodesc), 0);
}
else
{
@@ -601,7 +618,7 @@ plperl_func_handler(FmgrInfo *proinfo,
* Found the proc description block in the hashtable
************************************************************/
prodesc = (plperl_proc_desc *) SvIV(*hv_fetch(plperl_proc_hash,
- internal_proname, proname_len, 0));
+ internal_proname, proname_len, 0));
}
@@ -632,17 +649,18 @@ plperl_func_handler(FmgrInfo *proinfo,
elog(ERROR, "plperl: SPI_finish() failed");
retval = (Datum) (*fmgr_faddr(&prodesc->result_in_func))
- (SvPV(perlret, na),
- prodesc->result_in_elem,
- prodesc->result_in_len);
+ (SvPV(perlret, na),
+ prodesc->result_in_elem,
+ prodesc->result_in_len);
SvREFCNT_dec(perlret);
memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
- if (plperl_restart_in_progress) {
- if (--plperl_call_level == 0 )
+ if (plperl_restart_in_progress)
+ {
+ if (--plperl_call_level == 0)
plperl_restart_in_progress = 0;
- siglongjmp(Warn_restart,1);
+ siglongjmp(Warn_restart, 1);
}
return retval;
@@ -651,7 +669,7 @@ plperl_func_handler(FmgrInfo *proinfo,
#ifdef REALLYHAVEITONTHEBALL
/**********************************************************************
- * plperl_trigger_handler() - Handler for trigger calls
+ * plperl_trigger_handler() - Handler for trigger calls
**********************************************************************/
static HeapTuple
plperl_trigger_handler(FmgrInfo *proinfo)
@@ -865,7 +883,7 @@ plperl_trigger_handler(FmgrInfo *proinfo)
/* Build the data list for the trigtuple */
plperl_build_tuple_argument(trigdata->tg_trigtuple,
- tupdesc, &tcl_trigtup);
+ tupdesc, &tcl_trigtup);
/*
* Now the command part of the event for TG_op and data for NEW and
@@ -894,7 +912,7 @@ plperl_trigger_handler(FmgrInfo *proinfo)
Tcl_DStringAppendElement(&tcl_cmd, "UPDATE");
plperl_build_tuple_argument(trigdata->tg_newtuple,
- tupdesc, &tcl_newtup);
+ tupdesc, &tcl_newtup);
Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_newtup));
Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&tcl_trigtup));
@@ -1090,7 +1108,7 @@ plperl_trigger_handler(FmgrInfo *proinfo)
**********************************************************************/
static int
plperl_elog(ClientData cdata, Tcl_Interp *interp,
- int argc, char *argv[])
+ int argc, char *argv[])
{
int level;
sigjmp_buf save_restart;
@@ -1156,7 +1174,7 @@ plperl_elog(ClientData cdata, Tcl_Interp *interp,
**********************************************************************/
static int
plperl_quote(ClientData cdata, Tcl_Interp *interp,
- int argc, char *argv[])
+ int argc, char *argv[])
{
char *tmp;
char *cp1;
@@ -1210,7 +1228,7 @@ plperl_quote(ClientData cdata, Tcl_Interp *interp,
**********************************************************************/
static int
plperl_SPI_exec(ClientData cdata, Tcl_Interp *interp,
- int argc, char *argv[])
+ int argc, char *argv[])
{
int spi_rc;
char buf[64];
@@ -1317,13 +1335,13 @@ plperl_SPI_exec(ClientData cdata, Tcl_Interp *interp,
case SPI_ERROR_ARGUMENT:
Tcl_SetResult(interp,
- "plperl: SPI_exec() failed - SPI_ERROR_ARGUMENT",
+ "plperl: SPI_exec() failed - SPI_ERROR_ARGUMENT",
TCL_VOLATILE);
return TCL_ERROR;
case SPI_ERROR_UNCONNECTED:
Tcl_SetResult(interp,
- "plperl: SPI_exec() failed - SPI_ERROR_UNCONNECTED",
+ "plperl: SPI_exec() failed - SPI_ERROR_UNCONNECTED",
TCL_VOLATILE);
return TCL_ERROR;
@@ -1341,13 +1359,13 @@ plperl_SPI_exec(ClientData cdata, Tcl_Interp *interp,
case SPI_ERROR_TRANSACTION:
Tcl_SetResult(interp,
- "plperl: SPI_exec() failed - SPI_ERROR_TRANSACTION",
+ "plperl: SPI_exec() failed - SPI_ERROR_TRANSACTION",
TCL_VOLATILE);
return TCL_ERROR;
case SPI_ERROR_OPUNKNOWN:
Tcl_SetResult(interp,
- "plperl: SPI_exec() failed - SPI_ERROR_OPUNKNOWN",
+ "plperl: SPI_exec() failed - SPI_ERROR_OPUNKNOWN",
TCL_VOLATILE);
return TCL_ERROR;
@@ -1442,7 +1460,7 @@ plperl_SPI_exec(ClientData cdata, Tcl_Interp *interp,
**********************************************************************/
static int
plperl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
- int argc, char *argv[])
+ int argc, char *argv[])
{
int nargs;
char **args;
@@ -1623,7 +1641,7 @@ plperl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
**********************************************************************/
static int
plperl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
- int argc, char *argv[])
+ int argc, char *argv[])
{
int spi_rc;
char buf[64];
@@ -1885,13 +1903,13 @@ plperl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
case SPI_ERROR_ARGUMENT:
Tcl_SetResult(interp,
- "plperl: SPI_exec() failed - SPI_ERROR_ARGUMENT",
+ "plperl: SPI_exec() failed - SPI_ERROR_ARGUMENT",
TCL_VOLATILE);
return TCL_ERROR;
case SPI_ERROR_UNCONNECTED:
Tcl_SetResult(interp,
- "plperl: SPI_exec() failed - SPI_ERROR_UNCONNECTED",
+ "plperl: SPI_exec() failed - SPI_ERROR_UNCONNECTED",
TCL_VOLATILE);
return TCL_ERROR;
@@ -1909,13 +1927,13 @@ plperl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
case SPI_ERROR_TRANSACTION:
Tcl_SetResult(interp,
- "plperl: SPI_exec() failed - SPI_ERROR_TRANSACTION",
+ "plperl: SPI_exec() failed - SPI_ERROR_TRANSACTION",
TCL_VOLATILE);
return TCL_ERROR;
case SPI_ERROR_OPUNKNOWN:
Tcl_SetResult(interp,
- "plperl: SPI_exec() failed - SPI_ERROR_OPUNKNOWN",
+ "plperl: SPI_exec() failed - SPI_ERROR_OPUNKNOWN",
TCL_VOLATILE);
return TCL_ERROR;
@@ -2008,7 +2026,7 @@ plperl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
**********************************************************************/
static void
plperl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
- int tupno, HeapTuple tuple, TupleDesc tupdesc)
+ int tupno, HeapTuple tuple, TupleDesc tupdesc)
{
int i;
char *outputstr;
@@ -2102,16 +2120,16 @@ plperl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
* plperl_build_tuple_argument() - Build a string for a ref to a hash
* from all attributes of a given tuple
**********************************************************************/
-static SV*
+static SV *
plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
{
int i;
- SV* output;
+ SV *output;
Datum attr;
bool isnull;
char *attname;
- char* outputstr;
+ char *outputstr;
HeapTuple typeTup;
Oid typoutput;
Oid typelem;
@@ -2163,9 +2181,9 @@ plperl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc)
sv_catpvf(output, "'%s' => '%s',", attname, outputstr);
pfree(outputstr);
- } else {
- sv_catpvf(output, "'%s' => undef,", attname);
}
+ else
+ sv_catpvf(output, "'%s' => undef,", attname);
}
sv_catpv(output, "}");
output = perl_eval_pv(SvPV(output, na), TRUE);