aboutsummaryrefslogtreecommitdiff
path: root/src/pl/plpython/plpy_procedure.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl/plpython/plpy_procedure.c')
-rw-r--r--src/pl/plpython/plpy_procedure.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/pl/plpython/plpy_procedure.c b/src/pl/plpython/plpy_procedure.c
index bd483012d35..858cecc64d2 100644
--- a/src/pl/plpython/plpy_procedure.c
+++ b/src/pl/plpython/plpy_procedure.c
@@ -10,9 +10,12 @@
#include "access/transam.h"
#include "funcapi.h"
#include "catalog/pg_proc.h"
+#include "catalog/pg_proc_fn.h"
#include "catalog/pg_type.h"
#include "utils/builtins.h"
#include "utils/hsearch.h"
+#include "utils/inval.h"
+#include "utils/memutils.h"
#include "utils/syscache.h"
#include "plpython.h"
@@ -26,6 +29,7 @@
static HTAB *PLy_procedure_cache = NULL;
static PLyProcedure *PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger);
+static void invalidate_procedure_caches(Datum arg, int cacheid, uint32 hashvalue);
static bool PLy_procedure_argument_valid(PLyTypeInfo *arg);
static bool PLy_procedure_valid(PLyProcedure *proc, HeapTuple procTup);
static char *PLy_procedure_munge_source(const char *name, const char *src);
@@ -41,6 +45,29 @@ init_procedure_caches(void)
hash_ctl.entrysize = sizeof(PLyProcedureEntry);
PLy_procedure_cache = hash_create("PL/Python procedures", 32, &hash_ctl,
HASH_ELEM | HASH_BLOBS);
+ CacheRegisterSyscacheCallback(TRFTYPELANG,
+ invalidate_procedure_caches,
+ (Datum) 0);
+}
+
+static void
+invalidate_procedure_caches(Datum arg, int cacheid, uint32 hashvalue)
+{
+ HASH_SEQ_STATUS status;
+ PLyProcedureEntry *hentry;
+
+ Assert(PLy_procedure_cache != NULL);
+
+ /* flush all entries */
+ hash_seq_init(&status, PLy_procedure_cache);
+
+ while ((hentry = (PLyProcedureEntry *) hash_seq_search(&status)))
+ {
+ if (hash_search(PLy_procedure_cache,
+ (void *) &hentry->key,
+ HASH_REMOVE, NULL) == NULL)
+ elog(ERROR, "hash table corrupted");
+ }
}
/*
@@ -165,6 +192,16 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
for (i = 0; i < FUNC_MAX_ARGS; i++)
PLy_typeinfo_init(&proc->args[i]);
proc->nargs = 0;
+ proc->langid = procStruct->prolang;
+ {
+ MemoryContext oldcxt;
+
+ Datum protrftypes_datum = SysCacheGetAttr(PROCOID, procTup,
+ Anum_pg_proc_protrftypes, &isnull);
+ oldcxt = MemoryContextSwitchTo(TopMemoryContext);
+ proc->trftypes = isnull ? NIL : oid_array_to_list(protrftypes_datum);
+ MemoryContextSwitchTo(oldcxt);
+ }
proc->code = proc->statics = NULL;
proc->globals = NULL;
proc->is_setof = procStruct->proretset;
@@ -219,7 +256,7 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
else
{
/* do the real work */
- PLy_output_datum_func(&proc->result, rvTypeTup);
+ PLy_output_datum_func(&proc->result, rvTypeTup, proc->langid, proc->trftypes);
}
ReleaseSysCache(rvTypeTup);
@@ -293,7 +330,9 @@ PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
default:
PLy_input_datum_func(&(proc->args[pos]),
types[i],
- argTypeTup);
+ argTypeTup,
+ proc->langid,
+ proc->trftypes);
break;
}