PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
funccache.c File Reference
#include "postgres.h"
#include "catalog/pg_proc.h"
#include "commands/event_trigger.h"
#include "commands/trigger.h"
#include "common/hashfn.h"
#include "funcapi.h"
#include "utils/funccache.h"
#include "utils/hsearch.h"
#include "utils/syscache.h"
Include dependency graph for funccache.c:

Go to the source code of this file.

Data Structures

struct  CachedFunctionHashEntry
 

Macros

#define FUNCS_PER_USER   128 /* initial table size */
 

Typedefs

typedef struct CachedFunctionHashEntry CachedFunctionHashEntry
 

Functions

static uint32 cfunc_hash (const void *key, Size keysize)
 
static int cfunc_match (const void *key1, const void *key2, Size keysize)
 
static void cfunc_hashtable_init (void)
 
static CachedFunctioncfunc_hashtable_lookup (CachedFunctionHashKey *func_key)
 
static void cfunc_hashtable_insert (CachedFunction *function, CachedFunctionHashKey *func_key)
 
static void cfunc_hashtable_delete (CachedFunction *function)
 
static void compute_function_hashkey (FunctionCallInfo fcinfo, Form_pg_proc procStruct, CachedFunctionHashKey *hashkey, Size cacheEntrySize, bool includeResultType, bool forValidator)
 
void cfunc_resolve_polymorphic_argtypes (int numargs, Oid *argtypes, char *argmodes, Node *call_expr, bool forValidator, const char *proname)
 
static void delete_function (CachedFunction *func)
 
CachedFunctioncached_function_compile (FunctionCallInfo fcinfo, CachedFunction *function, CachedFunctionCompileCallback ccallback, CachedFunctionDeleteCallback dcallback, Size cacheEntrySize, bool includeResultType, bool forValidator)
 

Variables

static HTABcfunc_hashtable = NULL
 

Macro Definition Documentation

◆ FUNCS_PER_USER

#define FUNCS_PER_USER   128 /* initial table size */

Definition at line 47 of file funccache.c.

Typedef Documentation

◆ CachedFunctionHashEntry

Function Documentation

◆ cached_function_compile()

CachedFunction * cached_function_compile ( FunctionCallInfo  fcinfo,
CachedFunction function,
CachedFunctionCompileCallback  ccallback,
CachedFunctionDeleteCallback  dcallback,
Size  cacheEntrySize,
bool  includeResultType,
bool  forValidator 
)

Definition at line 480 of file funccache.c.

487{
488 Oid funcOid = fcinfo->flinfo->fn_oid;
489 HeapTuple procTup;
490 Form_pg_proc procStruct;
491 CachedFunctionHashKey hashkey;
492 bool function_valid = false;
493 bool hashkey_valid = false;
494
495 /*
496 * Lookup the pg_proc tuple by Oid; we'll need it in any case
497 */
498 procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
499 if (!HeapTupleIsValid(procTup))
500 elog(ERROR, "cache lookup failed for function %u", funcOid);
501 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
502
503 /*
504 * Do we already have a cache entry for the current FmgrInfo? If not, try
505 * to find one in the hash table.
506 */
507recheck:
508 if (!function)
509 {
510 /* Compute hashkey using function signature and actual arg types */
511 compute_function_hashkey(fcinfo, procStruct, &hashkey,
512 cacheEntrySize, includeResultType,
513 forValidator);
514 hashkey_valid = true;
515
516 /* And do the lookup */
518 }
519
520 if (function)
521 {
522 /* We have a compiled function, but is it still valid? */
523 if (function->fn_xmin == HeapTupleHeaderGetRawXmin(procTup->t_data) &&
524 ItemPointerEquals(&function->fn_tid, &procTup->t_self))
525 function_valid = true;
526 else
527 {
528 /*
529 * Nope, so remove it from hashtable and try to drop associated
530 * storage (if not done already).
531 */
533
534 /*
535 * If the function isn't in active use then we can overwrite the
536 * func struct with new data, allowing any other existing fn_extra
537 * pointers to make use of the new definition on their next use.
538 * If it is in use then just leave it alone and make a new one.
539 * (The active invocations will run to completion using the
540 * previous definition, and then the cache entry will just be
541 * leaked; doesn't seem worth adding code to clean it up, given
542 * what a corner case this is.)
543 *
544 * If we found the function struct via fn_extra then it's possible
545 * a replacement has already been made, so go back and recheck the
546 * hashtable.
547 */
548 if (function->use_count != 0)
549 {
550 function = NULL;
551 if (!hashkey_valid)
552 goto recheck;
553 }
554 }
555 }
556
557 /*
558 * If the function wasn't found or was out-of-date, we have to compile it.
559 */
560 if (!function_valid)
561 {
562 /*
563 * Calculate hashkey if we didn't already; we'll need it to store the
564 * completed function.
565 */
566 if (!hashkey_valid)
567 compute_function_hashkey(fcinfo, procStruct, &hashkey,
568 cacheEntrySize, includeResultType,
569 forValidator);
570
571 /*
572 * Create the new function struct, if not done already. The function
573 * structs are never thrown away, so keep them in TopMemoryContext.
574 */
575 Assert(cacheEntrySize >= sizeof(CachedFunction));
576 if (function == NULL)
577 {
580 }
581 else
582 {
583 /* re-using a previously existing struct, so clear it out */
584 memset(function, 0, cacheEntrySize);
585 }
586
587 /*
588 * Fill in the CachedFunction part. fn_hashkey and use_count remain
589 * zeroes for now.
590 */
591 function->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data);
592 function->fn_tid = procTup->t_self;
593 function->dcallback = dcallback;
594
595 /*
596 * Do the hard, language-specific part.
597 */
598 ccallback(fcinfo, procTup, &hashkey, function, forValidator);
599
600 /*
601 * Add the completed struct to the hash table.
602 */
604 }
605
606 ReleaseSysCache(procTup);
607
608 /*
609 * Finally return the compiled function
610 */
611 return function;
612}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
static void compute_function_hashkey(FunctionCallInfo fcinfo, Form_pg_proc procStruct, CachedFunctionHashKey *hashkey, Size cacheEntrySize, bool includeResultType, bool forValidator)
Definition: funccache.c:247
static void cfunc_hashtable_insert(CachedFunction *function, CachedFunctionHashKey *func_key)
Definition: funccache.c:167
static CachedFunction * cfunc_hashtable_lookup(CachedFunctionHashKey *func_key)
Definition: funccache.c:146
static void delete_function(CachedFunction *func)
Definition: funccache.c:433
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static TransactionId HeapTupleHeaderGetRawXmin(const HeapTupleHeaderData *tup)
Definition: htup_details.h:318
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:35
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1290
MemoryContext TopMemoryContext
Definition: mcxt.c:165
on_exit_nicely_callback function
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
unsigned int Oid
Definition: postgres_ext.h:30
Oid fn_oid
Definition: fmgr.h:59
FmgrInfo * flinfo
Definition: fmgr.h:87
ItemPointerData t_self
Definition: htup.h:65
HeapTupleHeader t_data
Definition: htup.h:68
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221

References Assert(), cfunc_hashtable_insert(), cfunc_hashtable_lookup(), compute_function_hashkey(), delete_function(), elog, ERROR, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_oid, function, GETSTRUCT(), HeapTupleHeaderGetRawXmin(), HeapTupleIsValid, ItemPointerEquals(), MemoryContextAllocZero(), ObjectIdGetDatum(), ReleaseSysCache(), SearchSysCache1(), HeapTupleData::t_data, HeapTupleData::t_self, and TopMemoryContext.

Referenced by init_sql_fcache(), and plpgsql_compile().

◆ cfunc_hash()

static uint32 cfunc_hash ( const void *  key,
Size  keysize 
)
static

Definition at line 85 of file funccache.c.

86{
88 uint32 h;
89
90 Assert(keysize == sizeof(CachedFunctionHashKey));
91 /* Hash all the fixed fields except callResultType */
92 h = DatumGetUInt32(hash_any((const unsigned char *) k,
93 offsetof(CachedFunctionHashKey, callResultType)));
94 /* Incorporate input argument types */
95 if (k->nargs > 0)
96 h = hash_combine(h,
97 DatumGetUInt32(hash_any((const unsigned char *) k->argtypes,
98 k->nargs * sizeof(Oid))));
99 /* Incorporate callResultType if present */
100 if (k->callResultType)
101 h = hash_combine(h, hashRowType(k->callResultType));
102 return h;
103}
uint32_t uint32
Definition: c.h:502
static uint32 hash_combine(uint32 a, uint32 b)
Definition: hashfn.h:68
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:227
uint32 hashRowType(TupleDesc desc)
Definition: tupdesc.c:806

References CachedFunctionHashKey::argtypes, Assert(), CachedFunctionHashKey::callResultType, DatumGetUInt32(), hash_any(), hash_combine(), hashRowType(), sort-test::key, and CachedFunctionHashKey::nargs.

Referenced by cfunc_hashtable_init().

◆ cfunc_hashtable_delete()

static void cfunc_hashtable_delete ( CachedFunction function)
static

Definition at line 207 of file funccache.c.

208{
210 TupleDesc tupdesc;
211
212 /* do nothing if not in table */
213 if (function->fn_hashkey == NULL)
214 return;
215
216 /*
217 * We need to free the callResultType if present, which is slightly tricky
218 * because it has to be valid during the hashtable search. Fortunately,
219 * because we have the hashkey back-link, we can grab that pointer before
220 * deleting the hashtable entry.
221 */
222 tupdesc = function->fn_hashkey->callResultType;
223
225 function->fn_hashkey,
227 NULL);
228 if (hentry == NULL)
229 elog(WARNING, "trying to delete function that does not exist");
230
231 /* Remove back link, which no longer points to allocated storage */
232 function->fn_hashkey = NULL;
233
234 /* Release the callResultType if present */
235 if (tupdesc)
236 FreeTupleDesc(tupdesc);
237}
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
#define WARNING
Definition: elog.h:36
static HTAB * cfunc_hashtable
Definition: funccache.c:39
@ HASH_REMOVE
Definition: hsearch.h:115
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:495

References cfunc_hashtable, elog, FreeTupleDesc(), function, HASH_REMOVE, hash_search(), and WARNING.

Referenced by delete_function().

◆ cfunc_hashtable_init()

static void cfunc_hashtable_init ( void  )
static

Definition at line 59 of file funccache.c.

60{
62
63 /* don't allow double-initialization */
64 Assert(cfunc_hashtable == NULL);
65
66 ctl.keysize = sizeof(CachedFunctionHashKey);
67 ctl.entrysize = sizeof(CachedFunctionHashEntry);
68 ctl.hash = cfunc_hash;
69 ctl.match = cfunc_match;
70 cfunc_hashtable = hash_create("Cached function hash",
72 &ctl,
74}
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
#define FUNCS_PER_USER
Definition: funccache.c:47
static uint32 cfunc_hash(const void *key, Size keysize)
Definition: funccache.c:85
static int cfunc_match(const void *key1, const void *key2, Size keysize)
Definition: funccache.c:109
struct CachedFunctionHashEntry CachedFunctionHashEntry
struct CachedFunctionHashKey CachedFunctionHashKey
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_COMPARE
Definition: hsearch.h:99
#define HASH_FUNCTION
Definition: hsearch.h:98
tree ctl
Definition: radixtree.h:1838

References Assert(), cfunc_hash(), cfunc_hashtable, cfunc_match(), ctl, FUNCS_PER_USER, HASH_COMPARE, hash_create(), HASH_ELEM, and HASH_FUNCTION.

Referenced by cfunc_hashtable_insert().

◆ cfunc_hashtable_insert()

static void cfunc_hashtable_insert ( CachedFunction function,
CachedFunctionHashKey func_key 
)
static

Definition at line 167 of file funccache.c.

169{
171 bool found;
172
173 if (cfunc_hashtable == NULL)
175
177 func_key,
179 &found);
180 if (found)
181 elog(WARNING, "trying to insert a function that already exists");
182
183 /*
184 * If there's a callResultType, copy it into TopMemoryContext. If we're
185 * unlucky enough for that to fail, leave the entry with null
186 * callResultType, which will probably never match anything.
187 */
188 if (func_key->callResultType)
189 {
191
192 hentry->key.callResultType = NULL;
194 MemoryContextSwitchTo(oldcontext);
195 }
196
197 hentry->function = function;
198
199 /* Set back-link from function to hashtable key */
200 function->fn_hashkey = &hentry->key;
201}
static void cfunc_hashtable_init(void)
Definition: funccache.c:59
@ HASH_ENTER
Definition: hsearch.h:114
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
CachedFunctionHashKey key
Definition: funccache.c:43
CachedFunction * function
Definition: funccache.c:44
TupleDesc callResultType
Definition: funccache.h:92
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:245

References CachedFunctionHashKey::callResultType, cfunc_hashtable, cfunc_hashtable_init(), CreateTupleDescCopy(), elog, CachedFunctionHashEntry::function, function, HASH_ENTER, hash_search(), CachedFunctionHashEntry::key, MemoryContextSwitchTo(), TopMemoryContext, and WARNING.

Referenced by cached_function_compile().

◆ cfunc_hashtable_lookup()

static CachedFunction * cfunc_hashtable_lookup ( CachedFunctionHashKey func_key)
static

Definition at line 146 of file funccache.c.

147{
149
150 if (cfunc_hashtable == NULL)
151 return NULL;
152
154 func_key,
155 HASH_FIND,
156 NULL);
157 if (hentry)
158 return hentry->function;
159 else
160 return NULL;
161}
@ HASH_FIND
Definition: hsearch.h:113

References cfunc_hashtable, CachedFunctionHashEntry::function, HASH_FIND, and hash_search().

Referenced by cached_function_compile().

◆ cfunc_match()

static int cfunc_match ( const void *  key1,
const void *  key2,
Size  keysize 
)
static

Definition at line 109 of file funccache.c.

110{
111 const CachedFunctionHashKey *k1 = (const CachedFunctionHashKey *) key1;
112 const CachedFunctionHashKey *k2 = (const CachedFunctionHashKey *) key2;
113
114 Assert(keysize == sizeof(CachedFunctionHashKey));
115 /* Compare all the fixed fields except callResultType */
116 if (memcmp(k1, k2, offsetof(CachedFunctionHashKey, callResultType)) != 0)
117 return 1; /* not equal */
118 /* Compare input argument types (we just verified that nargs matches) */
119 if (k1->nargs > 0 &&
120 memcmp(k1->argtypes, k2->argtypes, k1->nargs * sizeof(Oid)) != 0)
121 return 1; /* not equal */
122 /* Compare callResultType */
123 if (k1->callResultType)
124 {
125 if (k2->callResultType)
126 {
128 return 1; /* not equal */
129 }
130 else
131 return 1; /* not equal */
132 }
133 else
134 {
135 if (k2->callResultType)
136 return 1; /* not equal */
137 }
138 return 0; /* equal */
139}
Oid argtypes[FUNC_MAX_ARGS]
Definition: funccache.h:98
bool equalRowTypes(TupleDesc tupdesc1, TupleDesc tupdesc2)
Definition: tupdesc.c:770

References CachedFunctionHashKey::argtypes, Assert(), CachedFunctionHashKey::callResultType, equalRowTypes(), and CachedFunctionHashKey::nargs.

Referenced by cfunc_hashtable_init().

◆ cfunc_resolve_polymorphic_argtypes()

void cfunc_resolve_polymorphic_argtypes ( int  numargs,
Oid argtypes,
char *  argmodes,
Node call_expr,
bool  forValidator,
const char *  proname 
)

Definition at line 348 of file funccache.c.

352{
353 int i;
354
355 if (!forValidator)
356 {
357 int inargno;
358
359 /* normal case, pass to standard routine */
360 if (!resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
361 call_expr))
363 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
364 errmsg("could not determine actual argument "
365 "type for polymorphic function \"%s\"",
366 proname)));
367 /* also, treat RECORD inputs (but not outputs) as polymorphic */
368 inargno = 0;
369 for (i = 0; i < numargs; i++)
370 {
371 char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
372
373 if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE)
374 continue;
375 if (argtypes[i] == RECORDOID || argtypes[i] == RECORDARRAYOID)
376 {
377 Oid resolvedtype = get_call_expr_argtype(call_expr,
378 inargno);
379
380 if (OidIsValid(resolvedtype))
381 argtypes[i] = resolvedtype;
382 }
383 inargno++;
384 }
385 }
386 else
387 {
388 /* special validation case (no need to do anything for RECORD) */
389 for (i = 0; i < numargs; i++)
390 {
391 switch (argtypes[i])
392 {
393 case ANYELEMENTOID:
394 case ANYNONARRAYOID:
395 case ANYENUMOID: /* XXX dubious */
396 case ANYCOMPATIBLEOID:
397 case ANYCOMPATIBLENONARRAYOID:
398 argtypes[i] = INT4OID;
399 break;
400 case ANYARRAYOID:
401 case ANYCOMPATIBLEARRAYOID:
402 argtypes[i] = INT4ARRAYOID;
403 break;
404 case ANYRANGEOID:
405 case ANYCOMPATIBLERANGEOID:
406 argtypes[i] = INT4RANGEOID;
407 break;
408 case ANYMULTIRANGEOID:
409 argtypes[i] = INT4MULTIRANGEOID;
410 break;
411 default:
412 break;
413 }
414 }
415 }
416}
#define OidIsValid(objectId)
Definition: c.h:746
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ereport(elevel,...)
Definition: elog.h:149
Oid get_call_expr_argtype(Node *expr, int argnum)
Definition: fmgr.c:1929
bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr)
Definition: funcapi.c:1064
int i
Definition: isn.c:77
NameData proname
Definition: pg_proc.h:35

References ereport, errcode(), errmsg(), ERROR, get_call_expr_argtype(), i, OidIsValid, proname, and resolve_polymorphic_argtypes().

Referenced by compute_function_hashkey(), and plpgsql_compile_callback().

◆ compute_function_hashkey()

static void compute_function_hashkey ( FunctionCallInfo  fcinfo,
Form_pg_proc  procStruct,
CachedFunctionHashKey hashkey,
Size  cacheEntrySize,
bool  includeResultType,
bool  forValidator 
)
static

Definition at line 247 of file funccache.c.

253{
254 /* Make sure pad bytes within fixed part of the struct are zero */
255 memset(hashkey, 0, offsetof(CachedFunctionHashKey, argtypes));
256
257 /* get function OID */
258 hashkey->funcOid = fcinfo->flinfo->fn_oid;
259
260 /* get call context */
261 hashkey->isTrigger = CALLED_AS_TRIGGER(fcinfo);
262 hashkey->isEventTrigger = CALLED_AS_EVENT_TRIGGER(fcinfo);
263
264 /* record cacheEntrySize so multiple languages can share hash table */
265 hashkey->cacheEntrySize = cacheEntrySize;
266
267 /*
268 * If DML trigger, include trigger's OID in the hash, so that each trigger
269 * usage gets a different hash entry, allowing for e.g. different relation
270 * rowtypes or transition table names. In validation mode we do not know
271 * what relation or transition table names are intended to be used, so we
272 * leave trigOid zero; the hash entry built in this case will never be
273 * used for any actual calls.
274 *
275 * We don't currently need to distinguish different event trigger usages
276 * in the same way, since the special parameter variables don't vary in
277 * type in that case.
278 */
279 if (hashkey->isTrigger && !forValidator)
280 {
281 TriggerData *trigdata = (TriggerData *) fcinfo->context;
282
283 hashkey->trigOid = trigdata->tg_trigger->tgoid;
284 }
285
286 /* get input collation, if known */
287 hashkey->inputCollation = fcinfo->fncollation;
288
289 /*
290 * We include only input arguments in the hash key, since output argument
291 * types can be deduced from those, and it would require extra cycles to
292 * include the output arguments. But we have to resolve any polymorphic
293 * argument types to the real types for the call.
294 */
295 if (procStruct->pronargs > 0)
296 {
297 hashkey->nargs = procStruct->pronargs;
298 memcpy(hashkey->argtypes, procStruct->proargtypes.values,
299 procStruct->pronargs * sizeof(Oid));
300 cfunc_resolve_polymorphic_argtypes(procStruct->pronargs,
301 hashkey->argtypes,
302 NULL, /* all args are inputs */
303 fcinfo->flinfo->fn_expr,
304 forValidator,
305 NameStr(procStruct->proname));
306 }
307
308 /*
309 * While regular OUT arguments are sufficiently represented by the
310 * resolved input arguments, a function returning composite has additional
311 * variability: ALTER TABLE/ALTER TYPE could affect what it returns. Also,
312 * a function returning RECORD may depend on a column definition list to
313 * determine its output rowtype. If the caller needs the exact result
314 * type to be part of the hash lookup key, we must run
315 * get_call_result_type() to find that out.
316 */
317 if (includeResultType)
318 {
319 Oid resultTypeId;
320 TupleDesc tupdesc;
321
322 switch (get_call_result_type(fcinfo, &resultTypeId, &tupdesc))
323 {
326 hashkey->callResultType = tupdesc;
327 break;
328 default:
329 /* scalar result, or indeterminate rowtype */
330 break;
331 }
332 }
333}
#define NameStr(name)
Definition: c.h:717
#define CALLED_AS_EVENT_TRIGGER(fcinfo)
Definition: event_trigger.h:49
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:276
@ TYPEFUNC_COMPOSITE
Definition: funcapi.h:149
@ TYPEFUNC_COMPOSITE_DOMAIN
Definition: funcapi.h:150
void cfunc_resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr, bool forValidator, const char *proname)
Definition: funccache.c:348
fmNodePtr fn_expr
Definition: fmgr.h:66
fmNodePtr context
Definition: fmgr.h:88
Trigger * tg_trigger
Definition: trigger.h:38
Oid tgoid
Definition: reltrigger.h:25
#define CALLED_AS_TRIGGER(fcinfo)
Definition: trigger.h:26

References CachedFunctionHashKey::argtypes, CachedFunctionHashKey::cacheEntrySize, CALLED_AS_EVENT_TRIGGER, CALLED_AS_TRIGGER, CachedFunctionHashKey::callResultType, cfunc_resolve_polymorphic_argtypes(), FunctionCallInfoBaseData::context, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_expr, FmgrInfo::fn_oid, FunctionCallInfoBaseData::fncollation, CachedFunctionHashKey::funcOid, get_call_result_type(), CachedFunctionHashKey::inputCollation, CachedFunctionHashKey::isEventTrigger, CachedFunctionHashKey::isTrigger, NameStr, CachedFunctionHashKey::nargs, TriggerData::tg_trigger, Trigger::tgoid, CachedFunctionHashKey::trigOid, TYPEFUNC_COMPOSITE, and TYPEFUNC_COMPOSITE_DOMAIN.

Referenced by cached_function_compile().

◆ delete_function()

static void delete_function ( CachedFunction func)
static

Definition at line 433 of file funccache.c.

434{
435 /* remove function from hash table (might be done already) */
437
438 /* release the function's storage if safe and not done already */
439 if (func->use_count == 0 &&
440 func->dcallback != NULL)
441 {
442 func->dcallback(func);
443 func->dcallback = NULL;
444 }
445}
static void cfunc_hashtable_delete(CachedFunction *function)
Definition: funccache.c:207
CachedFunctionDeleteCallback dcallback
Definition: funccache.h:114
uint64 use_count
Definition: funccache.h:117

References cfunc_hashtable_delete(), CachedFunction::dcallback, and CachedFunction::use_count.

Referenced by cached_function_compile().

Variable Documentation

◆ cfunc_hashtable

HTAB* cfunc_hashtable = NULL
static