mirror of
https://github.com/postgres/postgres.git
synced 2025-07-20 05:03:10 +03:00
Add missing SRF file.
This commit is contained in:
122
src/backend/utils/fmgr/funcapi.c
Normal file
122
src/backend/utils/fmgr/funcapi.c
Normal file
@ -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);
|
||||||
|
}
|
Reference in New Issue
Block a user