1 /*-------------------------------------------------------------------------
4 * Definitions for functions which return composite type and/or sets
6 * This file must be included by all Postgres modules that either define
7 * or call FUNCAPI-callable functions or macros.
10 * Copyright (c) 2002, PostgreSQL Global Development Group
12 * $Id: funcapi.h,v 1.8 2002/09/04 20:31:36 momjian Exp $
14 *-------------------------------------------------------------------------
20 #include "access/tupdesc.h"
21 #include "executor/executor.h"
22 #include "executor/tuptable.h"
25 /*-------------------------------------------------------------------------
26 * Support to ease writing Functions returning composite types
27 *-------------------------------------------------------------------------
29 * This struct holds arrays of individual attribute information
30 * needed to create a tuple from raw C strings. It also requires
31 * a copy of the TupleDesc. The information carried here
32 * is derived from the TupleDesc, but it is stored here to
33 * avoid redundant cpu cycles on each call to an SRF.
35 typedef struct AttInMetadata
40 /* array of attribute type input function finfo */
43 /* array of attribute type typelem */
46 /* array of attribute typmod */
50 /*-------------------------------------------------------------------------
51 * Support struct to ease writing Set Returning Functions (SRFs)
52 *-------------------------------------------------------------------------
54 * This struct holds function context for Set Returning Functions.
55 * Use fn_extra to hold a pointer to it across calls
57 typedef struct FuncCallContext
60 * Number of times we've been called before.
62 * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and
63 * incremented for you every time SRF_RETURN_NEXT() is called.
68 * OPTIONAL maximum number of calls
70 * max_calls is here for convenience ONLY and setting it is OPTIONAL. If
71 * not set, you must provide alternative means to know when the
77 * OPTIONAL pointer to result slot
79 * slot is for use when returning tuples (i.e. composite data types) and
80 * is not needed when returning base (i.e. scalar) data types.
85 * OPTIONAL pointer to misc user provided context info
87 * user_fctx is for use as a pointer to your own struct to retain
88 * arbitrary context information between calls for your function.
93 * OPTIONAL pointer to struct containing arrays of attribute type
96 * attinmeta is for use when returning tuples (i.e. composite data types)
97 * and is not needed when returning base (i.e. scalar) data types. It
98 * is ONLY needed if you intend to use BuildTupleFromCStrings() to
99 * create the return tuple.
101 AttInMetadata *attinmeta;
104 * memory context used for structures which must live for multiple
107 * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used
108 * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory
109 * context for any memory that is to be re-used across multiple calls
112 MemoryContext multi_call_memory_ctx;
117 * Support to ease writing Functions returning composite types
119 * External declarations:
120 * TupleDesc RelationNameGetTupleDesc(const char *relname) - Use to get a
121 * TupleDesc based on a specified relation.
122 * TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) - Use to get a
123 * TupleDesc based on a type OID. This can be used to get
124 * a TupleDesc for a base (scalar) or composite (relation) type.
125 * TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc) - Initialize a slot
127 * AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) - Build an
128 * AttInMetadata struct based on the given TupleDesc. AttInMetadata can
129 * be used in conjunction with C strings to produce a properly formed
130 * tuple. Store the metadata here for use across calls to avoid redundant
132 * HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) -
133 * build a HeapTuple given user data in C string form. values is an array
134 * of C strings, one for each attribute of the return tuple.
136 * Macro declarations:
137 * TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum
138 * given a tuple and a slot.
143 extern TupleDesc RelationNameGetTupleDesc(const char *relname);
144 extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases);
146 /* from execTuples.c */
147 extern TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc);
148 extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc);
149 extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values);
152 * Note we pass shouldFree = false; this is needed because the tuple will
153 * typically be in a shorter-lived memory context than the TupleTableSlot.
155 #define TupleGetDatum(_slot, _tuple) \
156 PointerGetDatum(ExecStoreTuple(_tuple, _slot, InvalidBuffer, false))
160 * Support for Set Returning Functions (SRFs)
162 * The basic API for SRFs looks something like:
165 * my_Set_Returning_Function(PG_FUNCTION_ARGS)
167 * FuncCallContext *funcctx;
169 * MemoryContext oldcontext;
170 * <user defined declarations>
172 * if (SRF_IS_FIRSTCALL())
174 * funcctx = SRF_FIRSTCALL_INIT();
175 * // switch context when allocating stuff to be used in later calls
176 * oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
177 * <user defined code>
178 * <if returning composite>
180 * funcctx->slot = slot;
181 * <endif returning composite>
182 * <user defined code>
183 * // return to original context when allocating transient memory
184 * MemoryContextSwitchTo(oldcontext);
186 * <user defined code>
187 * funcctx = SRF_PERCALL_SETUP();
188 * <user defined code>
190 * if (funcctx->call_cntr < funcctx->max_calls)
192 * <user defined code>
193 * <obtain result Datum>
194 * SRF_RETURN_NEXT(funcctx, result);
197 * SRF_RETURN_DONE(funcctx);
204 extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS);
205 extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS);
206 extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx);
208 #define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL)
210 #define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo)
212 #define SRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo)
214 #define SRF_RETURN_NEXT(_funcctx, _result) \
216 ReturnSetInfo *rsi; \
217 (_funcctx)->call_cntr++; \
218 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
219 rsi->isDone = ExprMultipleResult; \
220 PG_RETURN_DATUM(_result); \
223 #define SRF_RETURN_DONE(_funcctx) \
225 ReturnSetInfo *rsi; \
226 end_MultiFuncCall(fcinfo, _funcctx); \
227 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
228 rsi->isDone = ExprEndResult; \
232 #endif /* FUNCAPI_H */