summaryrefslogtreecommitdiff
path: root/src/pl
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl')
-rw-r--r--src/pl/plperl/plperl.c100
-rw-r--r--src/pl/plpgsql/src/pl_exec.c24
-rw-r--r--src/pl/plpgsql/src/pl_handler.c172
-rw-r--r--src/pl/plpgsql/src/plpgsql.h14
-rw-r--r--src/pl/tcl/pltcl.c92
5 files changed, 186 insertions, 216 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 86ffbb265f9..b440be12de8 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -32,6 +32,9 @@
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.7 2000/05/28 17:56:26 tgl Exp $
+ *
**********************************************************************/
@@ -130,17 +133,15 @@ static Tcl_HashTable *plperl_query_hash = NULL;
static void plperl_init_all(void);
static void plperl_init_safe_interp(void);
-Datum plperl_call_handler(FmgrInfo *proinfo,
- FmgrValues *proargs, bool *isNull);
+Datum plperl_call_handler(PG_FUNCTION_ARGS);
-static Datum plperl_func_handler(FmgrInfo *proinfo,
- FmgrValues *proargs, bool *isNull);
+static Datum plperl_func_handler(PG_FUNCTION_ARGS);
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 HeapTuple plperl_trigger_handler(PG_FUNCTION_ARGS);
static int plperl_elog(ClientData cdata, Tcl_Interp *interp,
int argc, char *argv[]);
@@ -258,9 +259,7 @@ plperl_init_safe_interp(void)
/* keep non-static */
Datum
-plperl_call_handler(FmgrInfo *proinfo,
- FmgrValues *proargs,
- bool *isNull)
+plperl_call_handler(PG_FUNCTION_ARGS)
{
Datum retval;
@@ -285,13 +284,13 @@ plperl_call_handler(FmgrInfo *proinfo,
* call appropriate subhandler
************************************************************/
if (CurrentTriggerData == NULL)
- retval = plperl_func_handler(proinfo, proargs, isNull);
+ retval = plperl_func_handler(fcinfo);
else
{
elog(ERROR, "plperl: can't use perl in triggers yet.");
/*
- * retval = (Datum) plperl_trigger_handler(proinfo);
+ * retval = (Datum) plperl_trigger_handler(fcinfo);
*/
/* make the compiler happy */
retval = (Datum) 0;
@@ -390,7 +389,7 @@ plperl_init_shared_libs(void)
**********************************************************************/
static
SV *
-plperl_call_perl_func(plperl_proc_desc * desc, FmgrValues *pargs)
+plperl_call_perl_func(plperl_proc_desc * desc, FunctionCallInfo fcinfo)
{
dSP;
@@ -407,25 +406,34 @@ plperl_call_perl_func(plperl_proc_desc * desc, FmgrValues *pargs)
{
if (desc->arg_is_rel[i])
{
+ TupleTableSlot *slot = (TupleTableSlot *) fcinfo->arg[i];
+ SV *hashref;
+ Assert(slot != NULL && ! fcinfo->argnull[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);
-
+ hashref = plperl_build_tuple_argument(slot->val,
+ slot->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]);
-
- XPUSHs(sv_2mortal(newSVpv(tmp, 0)));
- pfree(tmp);
+ if (fcinfo->argnull[i])
+ {
+ XPUSHs(&PL_sv_undef);
+ }
+ else
+ {
+ char *tmp;
+
+ tmp = (*fmgr_faddr(&(desc->arg_out_func[i])))
+ (fcinfo->arg[i],
+ desc->arg_out_elem[i],
+ desc->arg_out_len[i]);
+ XPUSHs(sv_2mortal(newSVpv(tmp, 0)));
+ pfree(tmp);
+ }
}
}
PUTBACK;
@@ -466,14 +474,11 @@ plperl_call_perl_func(plperl_proc_desc * desc, FmgrValues *pargs)
* plperl_func_handler() - Handler for regular function calls
**********************************************************************/
static Datum
-plperl_func_handler(FmgrInfo *proinfo,
- FmgrValues *proargs,
- bool *isNull)
+plperl_func_handler(PG_FUNCTION_ARGS)
{
int i;
char internal_proname[512];
int proname_len;
- char *stroid;
plperl_proc_desc *prodesc;
SV *perlret;
Datum retval;
@@ -482,10 +487,7 @@ plperl_func_handler(FmgrInfo *proinfo,
/************************************************************
* Build our internal proc name from the functions Oid
************************************************************/
- stroid = oidout(proinfo->fn_oid);
- strcpy(internal_proname, "__PLperl_proc_");
- strcat(internal_proname, stroid);
- pfree(stroid);
+ sprintf(internal_proname, "__PLPerl_proc_%u", fcinfo->flinfo->fn_oid);
proname_len = strlen(internal_proname);
/************************************************************
@@ -518,14 +520,14 @@ plperl_func_handler(FmgrInfo *proinfo,
* Lookup the pg_proc tuple by Oid
************************************************************/
procTup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(proinfo->fn_oid),
+ ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
0, 0, 0);
if (!HeapTupleIsValid(procTup))
{
free(prodesc->proname);
free(prodesc);
elog(ERROR, "plperl: cache lookup for proc %u failed",
- proinfo->fn_oid);
+ fcinfo->flinfo->fn_oid);
}
procStruct = (Form_pg_proc) GETSTRUCT(procTup);
@@ -560,8 +562,8 @@ plperl_func_handler(FmgrInfo *proinfo,
* Get the required information for output conversion
* of all procedure arguments
************************************************************/
- prodesc->nargs = proinfo->fn_nargs;
- for (i = 0; i < proinfo->fn_nargs; i++)
+ prodesc->nargs = procStruct->pronargs;
+ for (i = 0; i < prodesc->nargs; i++)
{
typeTup = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(procStruct->proargtypes[i]),
@@ -639,7 +641,7 @@ plperl_func_handler(FmgrInfo *proinfo,
/************************************************************
* Call the Perl function
************************************************************/
- perlret = plperl_call_perl_func(prodesc, proargs);
+ perlret = plperl_call_perl_func(prodesc, fcinfo);
/************************************************************
* Disconnect from SPI manager and then create the return
@@ -650,10 +652,19 @@ plperl_func_handler(FmgrInfo *proinfo,
if (SPI_finish() != SPI_OK_FINISH)
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);
+ /* XXX is this the approved way to check for an undef result? */
+ if (perlret == &PL_sv_undef)
+ {
+ retval = (Datum) 0;
+ fcinfo->isnull = true;
+ }
+ else
+ {
+ retval = FunctionCall3(&prodesc->result_in_func,
+ PointerGetDatum(SvPV(perlret, na)),
+ ObjectIdGetDatum(prodesc->result_in_elem),
+ Int32GetDatum(prodesc->result_in_len));
+ }
SvREFCNT_dec(perlret);
@@ -674,7 +685,7 @@ plperl_func_handler(FmgrInfo *proinfo,
* plperl_trigger_handler() - Handler for trigger calls
**********************************************************************/
static HeapTuple
-plperl_trigger_handler(FmgrInfo *proinfo)
+plperl_trigger_handler(PG_FUNCTION_ARGS)
{
TriggerData *trigdata;
char internal_proname[512];
@@ -708,10 +719,7 @@ plperl_trigger_handler(FmgrInfo *proinfo)
/************************************************************
* Build our internal proc name from the functions Oid
************************************************************/
- stroid = oidout(proinfo->fn_oid);
- strcpy(internal_proname, "__PLTcl_proc_");
- strcat(internal_proname, stroid);
- pfree(stroid);
+ sprintf(internal_proname, "__PLPerl_proc_%u", fcinfo->flinfo->fn_oid);
/************************************************************
* Lookup the internal proc name in the hashtable
@@ -741,14 +749,14 @@ plperl_trigger_handler(FmgrInfo *proinfo)
* Lookup the pg_proc tuple by Oid
************************************************************/
procTup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(proinfo->fn_oid),
+ ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
0, 0, 0);
if (!HeapTupleIsValid(procTup))
{
free(prodesc->proname);
free(prodesc);
elog(ERROR, "plperl: cache lookup for proc %u failed",
- proinfo->fn_oid);
+ fcinfo->flinfo->fn_oid);
}
procStruct = (Form_pg_proc) GETSTRUCT(procTup);
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index a2565a43637..e587aecba60 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.21 2000/04/28 00:12:44 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.22 2000/05/28 17:56:28 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -141,8 +141,7 @@ static void exec_set_found(PLpgSQL_execstate * estate, bool state);
* ----------
*/
Datum
-plpgsql_exec_function(PLpgSQL_function * func,
- FmgrValues *args, bool *isNull)
+plpgsql_exec_function(PLpgSQL_function * func, FunctionCallInfo fcinfo)
{
PLpgSQL_execstate estate;
int i;
@@ -302,21 +301,22 @@ plpgsql_exec_function(PLpgSQL_function * func,
{
PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n];
- var->value = (Datum) (args->data[i]);
- var->isnull = *isNull;
+ var->value = fcinfo->arg[i];
+ var->isnull = fcinfo->argnull[i];
var->shouldfree = false;
}
break;
case PLPGSQL_DTYPE_ROW:
{
+ PLpgSQL_row *row = (PLpgSQL_row *) estate.datums[n];
+ TupleTableSlot *slot = (TupleTableSlot *) fcinfo->arg[i];
HeapTuple tup;
TupleDesc tupdesc;
- PLpgSQL_row *row = (PLpgSQL_row *) estate.datums[n];
-
- tup = ((TupleTableSlot *) (args->data[i]))->val;
- tupdesc = ((TupleTableSlot *) (args->data[i]))->ttc_tupleDescriptor;
+ Assert(slot != NULL && ! fcinfo->argnull[i]);
+ tup = slot->val;
+ tupdesc = slot->ttc_tupleDescriptor;
exec_move_row(&estate, NULL, row, tup, tupdesc);
}
break;
@@ -384,7 +384,7 @@ plpgsql_exec_function(PLpgSQL_function * func,
error_info_stmt = NULL;
error_info_text = "while casting return value to functions return type";
- *isNull = estate.retisnull;
+ fcinfo->isnull = estate.retisnull;
if (!estate.retistuple)
{
@@ -393,14 +393,14 @@ plpgsql_exec_function(PLpgSQL_function * func,
&(func->fn_retinput),
func->fn_rettypelem,
-1,
- isNull);
+ &fcinfo->isnull);
/* ----------
* If the functions return type isn't by value,
* copy the value into upper executor memory context.
* ----------
*/
- if (!*isNull && !func->fn_retbyval)
+ if (!fcinfo->isnull && !func->fn_retbyval)
{
int len;
Datum tmp;
diff --git a/src/pl/plpgsql/src/pl_handler.c b/src/pl/plpgsql/src/pl_handler.c
index 0215eea6bba..54ecb1f4e89 100644
--- a/src/pl/plpgsql/src/pl_handler.c
+++ b/src/pl/plpgsql/src/pl_handler.c
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.3 1999/07/15 15:21:48 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.4 2000/05/28 17:56:28 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -45,147 +45,107 @@
#include "plpgsql.h"
#include "pl.tab.h"
-#include "executor/spi.h"
-#include "commands/trigger.h"
-#include "utils/builtins.h"
-#include "fmgr.h"
#include "access/heapam.h"
-
-#include "utils/syscache.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
+#include "utils/builtins.h"
+#include "utils/syscache.h"
+/*
+ * Head of list of already-compiled functions
+ */
static PLpgSQL_function *compiled_functions = NULL;
-Datum plpgsql_call_handler(FmgrInfo *proinfo,
- FmgrValues *proargs, bool *isNull);
-
-static Datum plpgsql_func_handler(FmgrInfo *proinfo,
- FmgrValues *proargs, bool *isNull);
-
-static HeapTuple plpgsql_trigger_handler(FmgrInfo *proinfo);
-
-
/* ----------
- * plpgsql_call_handler - This is the only visible function
- * of the PL interpreter. The PostgreSQL
- * function manager and trigger manager
- * call this function for execution of
- * PL/pgSQL procedures.
+ * plpgsql_call_handler
+ *
+ * This is the only visible function of the PL interpreter.
+ * The PostgreSQL function manager and trigger manager
+ * call this function for execution of PL/pgSQL procedures.
* ----------
*/
Datum
-plpgsql_call_handler(FmgrInfo *proinfo,
- FmgrValues *proargs,
- bool *isNull)
+plpgsql_call_handler(PG_FUNCTION_ARGS)
{
+ TriggerData *trigdata;
+ bool isTrigger;
+ PLpgSQL_function *func;
Datum retval;
/* ----------
- * Connect to SPI manager
- * ----------
- */
- if (SPI_connect() != SPI_OK_CONNECT)
- elog(ERROR, "plpgsql: cannot connect to SPI manager");
-
- /* ----------
- * Determine if called as function or trigger and
- * call appropriate subhandler
- * ----------
- */
- if (CurrentTriggerData == NULL)
- retval = plpgsql_func_handler(proinfo, proargs, isNull);
- else
- retval = (Datum) plpgsql_trigger_handler(proinfo);
-
- /* ----------
- * Disconnect from SPI manager
+ * Save the current trigger data local
+ *
+ * XXX this should go away in favor of using fcinfo->context
* ----------
*/
- if (SPI_finish() != SPI_OK_FINISH)
- elog(ERROR, "plpgsql: SPI_finish() failed");
-
- return retval;
-}
-
-
-/* ----------
- * plpgsql_func_handler() - Handler for regular function calls
- * ----------
- */
-static Datum
-plpgsql_func_handler(FmgrInfo *proinfo,
- FmgrValues *proargs,
- bool *isNull)
-{
- PLpgSQL_function *func;
+ trigdata = CurrentTriggerData;
+ CurrentTriggerData = NULL;
+ isTrigger = (trigdata != NULL);
/* ----------
- * Check if we already compiled this function
+ * Connect to SPI manager
* ----------
*/
- for (func = compiled_functions; func != NULL; func = func->next)
- {
- if (proinfo->fn_oid == func->fn_oid)
- break;
- }
+ if (SPI_connect() != SPI_OK_CONNECT)
+ elog(ERROR, "plpgsql: cannot connect to SPI manager");
/* ----------
- * If not, do so and add it to the compiled ones
+ * Check if we already compiled this function and saved the pointer
+ * (ie, current FmgrInfo has been used before)
* ----------
*/
+ func = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
if (func == NULL)
{
- func = plpgsql_compile(proinfo->fn_oid, T_FUNCTION);
-
- func->next = compiled_functions;
- compiled_functions = func;
+ /* ----------
+ * Check if we already compiled this function
+ * ----------
+ */
+ Oid funcOid = fcinfo->flinfo->fn_oid;
+
+ for (func = compiled_functions; func != NULL; func = func->next)
+ {
+ if (funcOid == func->fn_oid)
+ break;
+ }
+
+ /* ----------
+ * If not, do so and add it to the compiled ones
+ * ----------
+ */
+ if (func == NULL)
+ {
+ func = plpgsql_compile(funcOid,
+ isTrigger ? T_TRIGGER : T_FUNCTION);
+ func->next = compiled_functions;
+ compiled_functions = func;
+ }
+
+ /* ----------
+ * Save pointer in FmgrInfo to avoid search on subsequent calls
+ * ----------
+ */
+ fcinfo->flinfo->fn_extra = (void *) func;
}
- return plpgsql_exec_function(func, proargs, isNull);
-}
-
-
-/* ----------
- * plpgsql_trigger_handler() - Handler for trigger calls
- * ----------
- */
-static HeapTuple
-plpgsql_trigger_handler(FmgrInfo *proinfo)
-{
- TriggerData *trigdata;
- PLpgSQL_function *func;
-
/* ----------
- * Save the current trigger data local
- * ----------
- */
- trigdata = CurrentTriggerData;
- CurrentTriggerData = NULL;
-
- /* ----------
- * Check if we already compiled this trigger procedure
+ * Determine if called as function or trigger and
+ * call appropriate subhandler
* ----------
*/
- for (func = compiled_functions; func != NULL; func = func->next)
- {
- if (proinfo->fn_oid == func->fn_oid)
- break;
- }
+ if (isTrigger)
+ retval = PointerGetDatum(plpgsql_exec_trigger(func, trigdata));
+ else
+ retval = plpgsql_exec_function(func, fcinfo);
/* ----------
- * If not, do so and add it to the compiled ones
+ * Disconnect from SPI manager
* ----------
*/
- if (func == NULL)
- {
- func = plpgsql_compile(proinfo->fn_oid, T_TRIGGER);
-
- func->next = compiled_functions;
- compiled_functions = func;
- }
+ if (SPI_finish() != SPI_OK_FINISH)
+ elog(ERROR, "plpgsql: SPI_finish() failed");
- return plpgsql_exec_trigger(func, trigdata);
+ return retval;
}
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 5efbccff8a0..f4246980fca 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.8 2000/01/20 05:44:34 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.9 2000/05/28 17:56:28 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -38,9 +38,10 @@
#define PLPGSQL_H
#include "postgres.h"
+
+#include "fmgr.h"
#include "executor/spi.h"
#include "commands/trigger.h"
-#include "fmgr.h"
/**********************************************************************
* Definitions
@@ -451,15 +452,20 @@ extern void plpgsql_adddatum(PLpgSQL_datum * new);
extern int plpgsql_add_initdatums(int **varnos);
extern void plpgsql_comperrinfo(void);
+/* ----------
+ * Functions in pl_handler.c
+ * ----------
+ */
+extern Datum plpgsql_call_handler(PG_FUNCTION_ARGS);
/* ----------
* Functions in pl_exec.c
* ----------
*/
extern Datum plpgsql_exec_function(PLpgSQL_function * func,
- FmgrValues *args, bool *isNull);
+ FunctionCallInfo fcinfo);
extern HeapTuple plpgsql_exec_trigger(PLpgSQL_function * func,
- TriggerData *trigdata);
+ TriggerData *trigdata);
/* ----------
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index a57812e20a4..c968471ed94 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -2,9 +2,6 @@
* pltcl.c - PostgreSQL support for Tcl as
* procedural language (PL)
*
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.22 2000/05/23 01:59:05 tgl Exp $
- *
* This software is copyrighted by Jan Wieck - Hamburg.
*
* The author hereby grants permission to use, copy, modify,
@@ -33,6 +30,9 @@
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.23 2000/05/28 17:56:29 tgl Exp $
+ *
**********************************************************************/
#include <tcl.h>
@@ -111,13 +111,11 @@ static void pltcl_init_load_unknown(void);
#endif /* PLTCL_UNKNOWN_SUPPORT */
-Datum pltcl_call_handler(FmgrInfo *proinfo,
- FmgrValues *proargs, bool *isNull);
+Datum pltcl_call_handler(PG_FUNCTION_ARGS);
-static Datum pltcl_func_handler(FmgrInfo *proinfo,
- FmgrValues *proargs, bool *isNull);
+static Datum pltcl_func_handler(PG_FUNCTION_ARGS);
-static HeapTuple pltcl_trigger_handler(FmgrInfo *proinfo);
+static HeapTuple pltcl_trigger_handler(PG_FUNCTION_ARGS);
static int pltcl_elog(ClientData cdata, Tcl_Interp *interp,
int argc, char *argv[]);
@@ -368,9 +366,7 @@ pltcl_init_load_unknown(void)
/* keep non-static */
Datum
-pltcl_call_handler(FmgrInfo *proinfo,
- FmgrValues *proargs,
- bool *isNull)
+pltcl_call_handler(PG_FUNCTION_ARGS)
{
Datum retval;
@@ -395,9 +391,9 @@ pltcl_call_handler(FmgrInfo *proinfo,
* call appropriate subhandler
************************************************************/
if (CurrentTriggerData == NULL)
- retval = pltcl_func_handler(proinfo, proargs, isNull);
+ retval = pltcl_func_handler(fcinfo);
else
- retval = (Datum) pltcl_trigger_handler(proinfo);
+ retval = (Datum) pltcl_trigger_handler(fcinfo);
pltcl_call_level--;
@@ -408,13 +404,10 @@ pltcl_call_handler(FmgrInfo *proinfo,
* pltcl_func_handler() - Handler for regular function calls
**********************************************************************/
static Datum
-pltcl_func_handler(FmgrInfo *proinfo,
- FmgrValues *proargs,
- bool *isNull)
+pltcl_func_handler(PG_FUNCTION_ARGS)
{
int i;
char internal_proname[512];
- char *stroid;
Tcl_HashEntry *hashent;
int hashnew;
pltcl_proc_desc *volatile prodesc;
@@ -427,10 +420,7 @@ pltcl_func_handler(FmgrInfo *proinfo,
/************************************************************
* Build our internal proc name from the functions Oid
************************************************************/
- stroid = oidout(proinfo->fn_oid);
- strcpy(internal_proname, "__PLTcl_proc_");
- strcat(internal_proname, stroid);
- pfree(stroid);
+ sprintf(internal_proname, "__PLTcl_proc_%u", fcinfo->flinfo->fn_oid);
/************************************************************
* Lookup the internal proc name in the hashtable
@@ -467,14 +457,14 @@ pltcl_func_handler(FmgrInfo *proinfo,
* Lookup the pg_proc tuple by Oid
************************************************************/
procTup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(proinfo->fn_oid),
+ ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
0, 0, 0);
if (!HeapTupleIsValid(procTup))
{
free(prodesc->proname);
free(prodesc);
elog(ERROR, "pltcl: cache lookup for proc %u failed",
- proinfo->fn_oid);
+ fcinfo->flinfo->fn_oid);
}
procStruct = (Form_pg_proc) GETSTRUCT(procTup);
@@ -508,9 +498,9 @@ pltcl_func_handler(FmgrInfo *proinfo,
* Get the required information for output conversion
* of all procedure arguments
************************************************************/
- prodesc->nargs = proinfo->fn_nargs;
+ prodesc->nargs = procStruct->pronargs;
proc_internal_args[0] = '\0';
- for (i = 0; i < proinfo->fn_nargs; i++)
+ for (i = 0; i < prodesc->nargs; i++)
{
typeTup = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(procStruct->proargtypes[i]),
@@ -564,7 +554,7 @@ pltcl_func_handler(FmgrInfo *proinfo,
Tcl_DStringAppend(&proc_internal_body, "upvar #0 ", -1);
Tcl_DStringAppend(&proc_internal_body, internal_proname, -1);
Tcl_DStringAppend(&proc_internal_body, " GD\n", -1);
- for (i = 0; i < proinfo->fn_nargs; i++)
+ for (i = 0; i < fcinfo->nargs; i++)
{
if (!prodesc->arg_is_rel[i])
continue;
@@ -640,10 +630,12 @@ pltcl_func_handler(FmgrInfo *proinfo,
/**************************************************
* For tuple values, add a list for 'array set ...'
**************************************************/
+ TupleTableSlot *slot = (TupleTableSlot *) fcinfo->arg[i];
+
+ Assert(slot != NULL && ! fcinfo->argnull[i]);
Tcl_DStringInit(&list_tmp);
- pltcl_build_tuple_argument(
- ((TupleTableSlot *) (proargs->data[i]))->val,
- ((TupleTableSlot *) (proargs->data[i]))->ttc_tupleDescriptor,
+ pltcl_build_tuple_argument(slot->val,
+ slot->ttc_tupleDescriptor,
&list_tmp);
Tcl_DStringAppendElement(&tcl_cmd, Tcl_DStringValue(&list_tmp));
Tcl_DStringFree(&list_tmp);
@@ -655,14 +647,21 @@ pltcl_func_handler(FmgrInfo *proinfo,
* Single values are added as string element
* of their external representation
**************************************************/
- char *tmp;
-
- tmp = (*fmgr_faddr(&(prodesc->arg_out_func[i])))
- (proargs->data[i],
- prodesc->arg_out_elem[i],
- prodesc->arg_out_len[i]);
- Tcl_DStringAppendElement(&tcl_cmd, tmp);
- pfree(tmp);
+ if (fcinfo->argnull[i])
+ {
+ Tcl_DStringAppendElement(&tcl_cmd, "");
+ }
+ else
+ {
+ char *tmp;
+
+ tmp = (*fmgr_faddr(&(prodesc->arg_out_func[i])))
+ (fcinfo->arg[i],
+ prodesc->arg_out_elem[i],
+ prodesc->arg_out_len[i]);
+ Tcl_DStringAppendElement(&tcl_cmd, tmp);
+ pfree(tmp);
+ }
}
}
Tcl_DStringFree(&list_tmp);
@@ -719,10 +718,10 @@ pltcl_func_handler(FmgrInfo *proinfo,
if (SPI_finish() != SPI_OK_FINISH)
elog(ERROR, "pltcl: SPI_finish() failed");
- retval = (Datum) (*fmgr_faddr(&prodesc->result_in_func))
- (pltcl_safe_interp->result,
- prodesc->result_in_elem,
- -1);
+ retval = FunctionCall3(&prodesc->result_in_func,
+ PointerGetDatum(pltcl_safe_interp->result),
+ ObjectIdGetDatum(prodesc->result_in_elem),
+ Int32GetDatum(-1));
memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart));
return retval;
@@ -733,7 +732,7 @@ pltcl_func_handler(FmgrInfo *proinfo,
* pltcl_trigger_handler() - Handler for trigger calls
**********************************************************************/
static HeapTuple
-pltcl_trigger_handler(FmgrInfo *proinfo)
+pltcl_trigger_handler(PG_FUNCTION_ARGS)
{
TriggerData *trigdata;
char internal_proname[512];
@@ -767,10 +766,7 @@ pltcl_trigger_handler(FmgrInfo *proinfo)
/************************************************************
* Build our internal proc name from the functions Oid
************************************************************/
- stroid = oidout(proinfo->fn_oid);
- strcpy(internal_proname, "__PLTcl_proc_");
- strcat(internal_proname, stroid);
- pfree(stroid);
+ sprintf(internal_proname, "__PLTcl_proc_%u", fcinfo->flinfo->fn_oid);
/************************************************************
* Lookup the internal proc name in the hashtable
@@ -800,14 +796,14 @@ pltcl_trigger_handler(FmgrInfo *proinfo)
* Lookup the pg_proc tuple by Oid
************************************************************/
procTup = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(proinfo->fn_oid),
+ ObjectIdGetDatum(fcinfo->flinfo->fn_oid),
0, 0, 0);
if (!HeapTupleIsValid(procTup))
{
free(prodesc->proname);
free(prodesc);
elog(ERROR, "pltcl: cache lookup for proc %u failed",
- proinfo->fn_oid);
+ fcinfo->flinfo->fn_oid);
}
procStruct = (Form_pg_proc) GETSTRUCT(procTup);