mirror of https://github.com/postgres/postgres
Add missing SRF file.
This commit is contained in:
parent
95712b15b1
commit
27bce57766
|
@ -0,0 +1,122 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* funcapi.c
|
||||
* Utility and convenience functions for fmgr functions that return
|
||||
* sets and/or composite types.
|
||||
*
|
||||
* Copyright (c) 2002, PostgreSQL Global Development Group
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "funcapi.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
/*
|
||||
* init_MultiFuncCall
|
||||
* Create an empty FuncCallContext data structure
|
||||
* and do some other basic Multi-function call setup
|
||||
* and error checking
|
||||
*/
|
||||
FuncCallContext *
|
||||
init_MultiFuncCall(PG_FUNCTION_ARGS)
|
||||
{
|
||||
FuncCallContext *retval;
|
||||
|
||||
/*
|
||||
* Bail if we're called in the wrong context
|
||||
*/
|
||||
if (fcinfo->resultinfo == NULL || !IsA(fcinfo->resultinfo, ReturnSetInfo))
|
||||
elog(ERROR, "function called in context that does not accept a set result");
|
||||
|
||||
if (fcinfo->flinfo->fn_extra == NULL)
|
||||
{
|
||||
/*
|
||||
* First call
|
||||
*/
|
||||
MemoryContext oldcontext;
|
||||
|
||||
/* switch to the appropriate memory context */
|
||||
oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
|
||||
|
||||
/*
|
||||
* allocate space and zero it
|
||||
*/
|
||||
retval = (FuncCallContext *) palloc(sizeof(FuncCallContext));
|
||||
MemSet(retval, 0, sizeof(FuncCallContext));
|
||||
|
||||
/*
|
||||
* initialize the elements
|
||||
*/
|
||||
retval->call_cntr = 0;
|
||||
retval->max_calls = 0;
|
||||
retval->slot = NULL;
|
||||
retval->fctx = NULL;
|
||||
retval->attinmeta = NULL;
|
||||
retval->fmctx = fcinfo->flinfo->fn_mcxt;
|
||||
|
||||
/*
|
||||
* save the pointer for cross-call use
|
||||
*/
|
||||
fcinfo->flinfo->fn_extra = retval;
|
||||
|
||||
/* back to the original memory context */
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
}
|
||||
else /* second and subsequent calls */
|
||||
{
|
||||
elog(ERROR, "init_MultiFuncCall may not be called more than once");
|
||||
|
||||
/* never reached, but keep compiler happy */
|
||||
retval = NULL;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* end_MultiFuncCall
|
||||
* Clean up after init_MultiFuncCall
|
||||
*/
|
||||
void
|
||||
end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx)
|
||||
{
|
||||
MemoryContext oldcontext;
|
||||
|
||||
/* unbind from fcinfo */
|
||||
fcinfo->flinfo->fn_extra = NULL;
|
||||
|
||||
/*
|
||||
* Caller is responsible to free up memory for individual
|
||||
* struct elements other than att_in_funcinfo and elements.
|
||||
*/
|
||||
oldcontext = MemoryContextSwitchTo(funcctx->fmctx);
|
||||
|
||||
if (funcctx->attinmeta != NULL)
|
||||
pfree(funcctx->attinmeta);
|
||||
|
||||
pfree(funcctx);
|
||||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
}
|
||||
|
||||
void
|
||||
get_type_metadata(Oid typeid, Oid *attinfuncid, Oid *attelem)
|
||||
{
|
||||
HeapTuple typeTuple;
|
||||
Form_pg_type typtup;
|
||||
|
||||
typeTuple = SearchSysCache(TYPEOID,
|
||||
ObjectIdGetDatum(typeid),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(typeTuple))
|
||||
elog(ERROR, "get_type_metadata: Cache lookup of type %u failed", typeid);
|
||||
|
||||
typtup = (Form_pg_type) GETSTRUCT(typeTuple);
|
||||
|
||||
*attinfuncid = typtup->typinput;
|
||||
*attelem = typtup->typelem;
|
||||
|
||||
ReleaseSysCache(typeTuple);
|
||||
}
|
Loading…
Reference in New Issue