diff options
Diffstat (limited to 'src/pl/plpython/plpy_procedure.c')
-rw-r--r-- | src/pl/plpython/plpy_procedure.c | 43 |
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; } |