summaryrefslogtreecommitdiff
path: root/src/pl/plpgsql
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/plpgsql
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/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 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);
/* ----------