summaryrefslogtreecommitdiff
path: root/src/pl/plpgsql
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl/plpgsql')
-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
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);
/* ----------