Commit b837c992 authored by Tom Lane's avatar Tom Lane

Support polymorphic functions in plpgsql. Along the way, replace

linked-list search of function cache with hash-table lookup.
By Joe Conway.
parent cc300231
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.12 2002/08/30 00:28:41 tgl Exp $ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.13 2003/07/01 21:47:09 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -45,15 +45,6 @@ ...@@ -45,15 +45,6 @@
#include "utils/syscache.h" #include "utils/syscache.h"
/*
* Head of list of already-compiled functions
*/
static PLpgSQL_function *compiled_functions = NULL;
static bool func_up_to_date(PLpgSQL_function * func);
/* ---------- /* ----------
* plpgsql_call_handler * plpgsql_call_handler
* *
...@@ -67,8 +58,6 @@ PG_FUNCTION_INFO_V1(plpgsql_call_handler); ...@@ -67,8 +58,6 @@ PG_FUNCTION_INFO_V1(plpgsql_call_handler);
Datum Datum
plpgsql_call_handler(PG_FUNCTION_ARGS) plpgsql_call_handler(PG_FUNCTION_ARGS)
{ {
bool isTrigger = CALLED_AS_TRIGGER(fcinfo);
Oid funcOid = fcinfo->flinfo->fn_oid;
PLpgSQL_function *func; PLpgSQL_function *func;
Datum retval; Datum retval;
...@@ -78,55 +67,14 @@ plpgsql_call_handler(PG_FUNCTION_ARGS) ...@@ -78,55 +67,14 @@ plpgsql_call_handler(PG_FUNCTION_ARGS)
if (SPI_connect() != SPI_OK_CONNECT) if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "plpgsql: cannot connect to SPI manager"); elog(ERROR, "plpgsql: cannot connect to SPI manager");
/* /* Find or compile the function */
* Check if we already compiled this function and saved the pointer func = plpgsql_compile(fcinfo);
* (ie, current FmgrInfo has been used before)
*/
func = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
if (func != NULL)
{
Assert(func->fn_oid == funcOid);
/*
* But is the function still up to date?
*/
if (!func_up_to_date(func))
func = NULL;
}
if (func == NULL)
{
/*
* Check if we already compiled this function for another caller
*/
for (func = compiled_functions; func != NULL; func = func->next)
{
if (funcOid == func->fn_oid && func_up_to_date(func))
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;
}
/* /*
* Determine if called as function or trigger and call appropriate * Determine if called as function or trigger and call appropriate
* subhandler * subhandler
*/ */
if (isTrigger) if (CALLED_AS_TRIGGER(fcinfo))
retval = PointerGetDatum(plpgsql_exec_trigger(func, retval = PointerGetDatum(plpgsql_exec_trigger(func,
(TriggerData *) fcinfo->context)); (TriggerData *) fcinfo->context));
else else
...@@ -140,30 +88,3 @@ plpgsql_call_handler(PG_FUNCTION_ARGS) ...@@ -140,30 +88,3 @@ plpgsql_call_handler(PG_FUNCTION_ARGS)
return retval; return retval;
} }
/*
* Check to see if a compiled function is still up-to-date. This
* is needed because CREATE OR REPLACE FUNCTION can modify the
* function's pg_proc entry without changing its OID.
*/
static bool
func_up_to_date(PLpgSQL_function * func)
{
HeapTuple procTup;
bool result;
procTup = SearchSysCache(PROCOID,
ObjectIdGetDatum(func->fn_oid),
0, 0, 0);
if (!HeapTupleIsValid(procTup))
elog(ERROR, "plpgsql: cache lookup for proc %u failed",
func->fn_oid);
result = (func->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&
func->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data));
ReleaseSysCache(procTup);
return result;
}
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.36 2003/05/05 16:46:28 tgl Exp $ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.37 2003/07/01 21:47:09 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -487,6 +487,18 @@ typedef struct ...@@ -487,6 +487,18 @@ typedef struct
} PLpgSQL_stmt_dynexecute; } PLpgSQL_stmt_dynexecute;
typedef struct PLpgSQL_func_hashkey
{ /* Hash lookup key for functions */
Oid funcOid;
/*
* We include actual argument types in the hash key to support
* polymorphic PLpgSQL functions. Be careful that extra positions
* are zeroed!
*/
Oid argtypes[FUNC_MAX_ARGS];
} PLpgSQL_func_hashkey;
typedef struct PLpgSQL_function typedef struct PLpgSQL_function
{ /* Complete compiled function */ { /* Complete compiled function */
char *fn_name; char *fn_name;
...@@ -494,6 +506,7 @@ typedef struct PLpgSQL_function ...@@ -494,6 +506,7 @@ typedef struct PLpgSQL_function
TransactionId fn_xmin; TransactionId fn_xmin;
CommandId fn_cmin; CommandId fn_cmin;
int fn_functype; int fn_functype;
PLpgSQL_func_hashkey *fn_hashkey; /* back-link to hashtable key */
Oid fn_rettype; Oid fn_rettype;
int fn_rettyplen; int fn_rettyplen;
...@@ -519,8 +532,6 @@ typedef struct PLpgSQL_function ...@@ -519,8 +532,6 @@ typedef struct PLpgSQL_function
int ndatums; int ndatums;
PLpgSQL_datum **datums; PLpgSQL_datum **datums;
PLpgSQL_stmt_block *action; PLpgSQL_stmt_block *action;
struct PLpgSQL_function *next; /* for chaining list of functions */
} PLpgSQL_function; } PLpgSQL_function;
...@@ -588,7 +599,7 @@ extern PLpgSQL_function *plpgsql_curr_compile; ...@@ -588,7 +599,7 @@ extern PLpgSQL_function *plpgsql_curr_compile;
* Functions in pl_comp.c * Functions in pl_comp.c
* ---------- * ----------
*/ */
extern PLpgSQL_function *plpgsql_compile(Oid fn_oid, int functype); extern PLpgSQL_function *plpgsql_compile(FunctionCallInfo fcinfo);
extern int plpgsql_parse_word(char *word); extern int plpgsql_parse_word(char *word);
extern int plpgsql_parse_dblword(char *word); extern int plpgsql_parse_dblword(char *word);
extern int plpgsql_parse_tripword(char *word); extern int plpgsql_parse_tripword(char *word);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment