1 /*-------------------------------------------------------------------------
4 * Utility and convenience functions for fmgr functions that return
5 * sets and/or composite types.
7 * Copyright (c) 2002-2003, PostgreSQL Global Development Group
10 * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/funcapi.c,v 1.11 2003/09/15 20:03:37 petere 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))
37 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
38 errmsg("set-valued function called in context that cannot accept a set")));
40 if (fcinfo->flinfo->fn_extra == NULL)
45 * Allocate suitably long-lived space and zero it
47 retval = (FuncCallContext *)
48 MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
49 sizeof(FuncCallContext));
50 MemSet(retval, 0, sizeof(FuncCallContext));
53 * initialize the elements
55 retval->call_cntr = 0;
56 retval->max_calls = 0;
58 retval->user_fctx = NULL;
59 retval->attinmeta = NULL;
60 retval->multi_call_memory_ctx = fcinfo->flinfo->fn_mcxt;
63 * save the pointer for cross-call use
65 fcinfo->flinfo->fn_extra = retval;
69 /* second and subsequent calls */
70 elog(ERROR, "init_MultiFuncCall may not be called more than once");
72 /* never reached, but keep compiler happy */
82 * Do Multi-function per-call setup
85 per_MultiFuncCall(PG_FUNCTION_ARGS)
87 FuncCallContext *retval = (FuncCallContext *) fcinfo->flinfo->fn_extra;
90 * Clear the TupleTableSlot, if present. This is for safety's sake:
91 * the Slot will be in a long-lived context (it better be, if the
92 * FuncCallContext is pointing to it), but in most usage patterns the
93 * tuples stored in it will be in the function's per-tuple context. So
94 * at the beginning of each call, the Slot will hold a dangling
95 * pointer to an already-recycled tuple. We clear it out here. (See
96 * also the definition of TupleGetDatum() in funcapi.h!)
98 if (retval->slot != NULL)
99 ExecClearTuple(retval->slot);
106 * Clean up after init_MultiFuncCall
109 end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx)
111 /* unbind from fcinfo */
112 fcinfo->flinfo->fn_extra = NULL;
115 * Caller is responsible to free up memory for individual struct
116 * elements other than att_in_funcinfo and elements.
118 if (funcctx->attinmeta != NULL)
119 pfree(funcctx->attinmeta);