PostgreSQL Source Code git master
Data Structures | Typedefs | Functions
funccache.h File Reference
#include "access/htup_details.h"
#include "fmgr.h"
#include "storage/itemptr.h"
Include dependency graph for funccache.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

 
struct   CachedFunction
 

Typedefs

typedef void(*  CachedFunctionCompileCallback) (FunctionCallInfo fcinfo, HeapTuple procTup, const struct CachedFunctionHashKey *hashkey, struct CachedFunction *function, bool forValidator)
 
typedef void(*  CachedFunctionDeleteCallback) (struct CachedFunction *cfunc)
 
 
typedef struct CachedFunction  CachedFunction
 

Functions

CachedFunctioncached_function_compile (FunctionCallInfo fcinfo, CachedFunction *function, CachedFunctionCompileCallback ccallback, CachedFunctionDeleteCallback dcallback, 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)
 

Typedef Documentation

CachedFunction

CachedFunctionCompileCallback

typedef void(* CachedFunctionCompileCallback) (FunctionCallInfo fcinfo, HeapTuple procTup, const struct CachedFunctionHashKey *hashkey, struct CachedFunction *function, bool forValidator)

Definition at line 35 of file funccache.h.

CachedFunctionDeleteCallback

typedef void(* CachedFunctionDeleteCallback) (struct CachedFunction *cfunc)

Definition at line 45 of file funccache.h.

CachedFunctionHashKey

Function Documentation

cached_function_compile()

CachedFunction * cached_function_compile ( FunctionCallInfo  fcinfo,
CachedFunctionfunction,
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 bool new_function = false;
495
496 /*
497 * Lookup the pg_proc tuple by Oid; we'll need it in any case
498 */
499 procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
500 if (!HeapTupleIsValid(procTup))
501 elog(ERROR, "cache lookup failed for function %u", funcOid);
502 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
503
504 /*
505 * Do we already have a cache entry for the current FmgrInfo? If not, try
506 * to find one in the hash table.
507 */
508recheck:
509 if (!function)
510 {
511 /* Compute hashkey using function signature and actual arg types */
512 compute_function_hashkey(fcinfo, procStruct, &hashkey,
513 cacheEntrySize, includeResultType,
514 forValidator);
515 hashkey_valid = true;
516
517 /* And do the lookup */
519 }
520
521 if (function)
522 {
523 /* We have a compiled function, but is it still valid? */
524 if (function->fn_xmin == HeapTupleHeaderGetRawXmin(procTup->t_data) &&
525 ItemPointerEquals(&function->fn_tid, &procTup->t_self))
526 function_valid = true;
527 else
528 {
529 /*
530 * Nope, so remove it from hashtable and try to drop associated
531 * storage (if not done already).
532 */
534
535 /*
536 * If the function isn't in active use then we can overwrite the
537 * func struct with new data, allowing any other existing fn_extra
538 * pointers to make use of the new definition on their next use.
539 * If it is in use then just leave it alone and make a new one.
540 * (The active invocations will run to completion using the
541 * previous definition, and then the cache entry will just be
542 * leaked; doesn't seem worth adding code to clean it up, given
543 * what a corner case this is.)
544 *
545 * If we found the function struct via fn_extra then it's possible
546 * a replacement has already been made, so go back and recheck the
547 * hashtable.
548 */
549 if (function->use_count != 0)
550 {
551 function = NULL;
552 if (!hashkey_valid)
553 goto recheck;
554 }
555 }
556 }
557
558 /*
559 * If the function wasn't found or was out-of-date, we have to compile it.
560 */
561 if (!function_valid)
562 {
563 /*
564 * Calculate hashkey if we didn't already; we'll need it to store the
565 * completed function.
566 */
567 if (!hashkey_valid)
568 compute_function_hashkey(fcinfo, procStruct, &hashkey,
569 cacheEntrySize, includeResultType,
570 forValidator);
571
572 /*
573 * Create the new function struct, if not done already. The function
574 * cache entry will be kept for the life of the backend, so put it in
575 * TopMemoryContext.
576 */
577 Assert(cacheEntrySize >= sizeof(CachedFunction));
578 if (function == NULL)
579 {
582 new_function = true;
583 }
584 else
585 {
586 /* re-using a previously existing struct, so clear it out */
587 memset(function, 0, cacheEntrySize);
588 }
589
590 /*
591 * However, if function compilation fails, we'd like not to leak the
592 * function struct, so use a PG_TRY block to prevent that. (It's up
593 * to the compile callback function to avoid its own internal leakage
594 * in such cases.) Unfortunately, freeing the struct is only safe if
595 * we just allocated it: otherwise there are probably fn_extra
596 * pointers to it.
597 */
598 PG_TRY();
599 {
600 /*
601 * Do the hard, language-specific part.
602 */
603 ccallback(fcinfo, procTup, &hashkey, function, forValidator);
604 }
605 PG_CATCH();
606 {
607 if (new_function)
609 PG_RE_THROW();
610 }
611 PG_END_TRY();
612
613 /*
614 * Fill in the CachedFunction part. (We do this last to prevent the
615 * function from looking valid before it's fully built.) fn_hashkey
616 * will be set by cfunc_hashtable_insert; use_count remains zero.
617 */
618 function->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data);
619 function->fn_tid = procTup->t_self;
620 function->dcallback = dcallback;
621
622 /*
623 * Add the completed struct to the hash table.
624 */
626 }
627
628 ReleaseSysCache(procTup);
629
630 /*
631 * Finally return the compiled function
632 */
633 return function;
634}
#define PG_RE_THROW()
Definition: elog.h:405
#define PG_TRY(...)
Definition: elog.h:372
#define PG_END_TRY(...)
Definition: elog.h:397
#define ERROR
Definition: elog.h:39
#define PG_CATCH(...)
Definition: elog.h:382
#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:1263
void pfree(void *pointer)
Definition: mcxt.c:1594
MemoryContext TopMemoryContext
Definition: mcxt.c:166
on_exit_nicely_callback function
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
unsigned int Oid
Definition: postgres_ext.h:32
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:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220

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(), pfree(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, ReleaseSysCache(), SearchSysCache1(), HeapTupleData::t_data, HeapTupleData::t_self, and TopMemoryContext.

Referenced by init_sql_fcache(), and plpgsql_compile().

cfunc_resolve_polymorphic_argtypes()

void cfunc_resolve_polymorphic_argtypes ( int  numargs,
Oidargtypes,
char *  argmodes,
Nodecall_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:774
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ereport(elevel,...)
Definition: elog.h:150
Oid get_call_expr_argtype(Node *expr, int argnum)
Definition: fmgr.c:1894
bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, Node *call_expr)
Definition: funcapi.c:1064
i
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().

AltStyle によって変換されたページ (->オリジナル) /