summaryrefslogtreecommitdiff
path: root/src/pl
diff options
context:
space:
mode:
authorTom Lane2000-05-28 17:56:29 +0000
committerTom Lane2000-05-28 17:56:29 +0000
commit0a7fb4e9184539afcb6fed0f1d2bc0abddc2b0a6 (patch)
treeaffcce1c5b6367468fb6dcfd2790585f2e967629 /src/pl
parent5005bb060b3f3a82cd1bd662c7f8946c9be59db5 (diff)
First round of changes for new fmgr interface. fmgr itself and the
key call sites are changed, but most called functions are still oldstyle. An exception is that the PL managers are updated (so, for example, NULL handling now behaves as expected in plperl and plpgsql functions). NOTE initdb is forced due to added column in pg_proc.
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);