diff options
Diffstat (limited to 'src/pl/plpgsql')
| -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 |
3 files changed, 88 insertions, 122 deletions
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index a2565a4363..e587aecba6 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 0215eea6bb..54ecb1f4e8 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 5efbccff8a..f4246980fc 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); /* ---------- |
