diff options
Diffstat (limited to 'src/pl')
| -rw-r--r-- | src/pl/plperl/plperl.c | 100 | ||||
| -rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 24 | ||||
| -rw-r--r-- | src/pl/plpgsql/src/pl_handler.c | 172 | ||||
| -rw-r--r-- | src/pl/plpgsql/src/plpgsql.h | 14 | ||||
| -rw-r--r-- | src/pl/tcl/pltcl.c | 92 |
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); |
