1 /*-------------------------------------------------------------------------
4 * Utility and convenience functions for fmgr functions that return
5 * sets and/or composite types.
7 * Copyright (c) 2002, PostgreSQL Global Development Group
10 * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/funcapi.c,v 1.4 2002/08/29 17:14:33 tgl Exp $
12 *-------------------------------------------------------------------------
17 #include "catalog/pg_type.h"
18 #include "utils/syscache.h"
23 * Create an empty FuncCallContext data structure
24 * and do some other basic Multi-function call setup
28 init_MultiFuncCall(PG_FUNCTION_ARGS)
30 FuncCallContext *retval;
33 * Bail if we're called in the wrong context
35 if (fcinfo->resultinfo == NULL || !IsA(fcinfo->resultinfo, ReturnSetInfo))
36 elog(ERROR, "function called in context that does not accept a set result");
38 if (fcinfo->flinfo->fn_extra == NULL)
43 * Allocate suitably long-lived space and zero it
45 retval = (FuncCallContext *)
46 MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
47 sizeof(FuncCallContext));
48 MemSet(retval, 0, sizeof(FuncCallContext));
51 * initialize the elements
53 retval->call_cntr = 0;
54 retval->max_calls = 0;
56 retval->user_fctx = NULL;
57 retval->attinmeta = NULL;
58 retval->multi_call_memory_ctx = fcinfo->flinfo->fn_mcxt;
61 * save the pointer for cross-call use
63 fcinfo->flinfo->fn_extra = retval;
65 else /* second and subsequent calls */
67 elog(ERROR, "init_MultiFuncCall may not be called more than once");
69 /* never reached, but keep compiler happy */
79 * Do Multi-function per-call setup
82 per_MultiFuncCall(PG_FUNCTION_ARGS)
84 FuncCallContext *retval = (FuncCallContext *) fcinfo->flinfo->fn_extra;
86 /* make sure we start with a fresh slot */
87 if(retval->slot != NULL)
88 ExecClearTuple(retval->slot);
95 * Clean up after init_MultiFuncCall
98 end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx)
100 /* unbind from fcinfo */
101 fcinfo->flinfo->fn_extra = NULL;
104 * Caller is responsible to free up memory for individual
105 * struct elements other than att_in_funcinfo and elements.
107 if (funcctx->attinmeta != NULL)
108 pfree(funcctx->attinmeta);