1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * funcapi.h |
4 | * Definitions for functions which return composite type and/or sets |
5 | * or work on VARIADIC inputs. |
6 | * |
7 | * This file must be included by all Postgres modules that either define |
8 | * or call FUNCAPI-callable functions or macros. |
9 | * |
10 | * |
11 | * Copyright (c) 2002-2019, PostgreSQL Global Development Group |
12 | * |
13 | * src/include/funcapi.h |
14 | * |
15 | *------------------------------------------------------------------------- |
16 | */ |
17 | #ifndef FUNCAPI_H |
18 | #define FUNCAPI_H |
19 | |
20 | #include "fmgr.h" |
21 | #include "access/tupdesc.h" |
22 | #include "executor/executor.h" |
23 | #include "executor/tuptable.h" |
24 | |
25 | |
26 | /*------------------------------------------------------------------------- |
27 | * Support to ease writing Functions returning composite types |
28 | *------------------------------------------------------------------------- |
29 | * |
30 | * This struct holds arrays of individual attribute information |
31 | * needed to create a tuple from raw C strings. It also requires |
32 | * a copy of the TupleDesc. The information carried here |
33 | * is derived from the TupleDesc, but it is stored here to |
34 | * avoid redundant cpu cycles on each call to an SRF. |
35 | */ |
36 | typedef struct AttInMetadata |
37 | { |
38 | /* full TupleDesc */ |
39 | TupleDesc tupdesc; |
40 | |
41 | /* array of attribute type input function finfo */ |
42 | FmgrInfo *attinfuncs; |
43 | |
44 | /* array of attribute type i/o parameter OIDs */ |
45 | Oid *attioparams; |
46 | |
47 | /* array of attribute typmod */ |
48 | int32 *atttypmods; |
49 | } AttInMetadata; |
50 | |
51 | /*------------------------------------------------------------------------- |
52 | * Support struct to ease writing Set Returning Functions (SRFs) |
53 | *------------------------------------------------------------------------- |
54 | * |
55 | * This struct holds function context for Set Returning Functions. |
56 | * Use fn_extra to hold a pointer to it across calls |
57 | */ |
58 | typedef struct FuncCallContext |
59 | { |
60 | /* |
61 | * Number of times we've been called before |
62 | * |
63 | * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and |
64 | * incremented for you every time SRF_RETURN_NEXT() is called. |
65 | */ |
66 | uint64 call_cntr; |
67 | |
68 | /* |
69 | * OPTIONAL maximum number of calls |
70 | * |
71 | * max_calls is here for convenience only and setting it is optional. If |
72 | * not set, you must provide alternative means to know when the function |
73 | * is done. |
74 | */ |
75 | uint64 max_calls; |
76 | |
77 | /* |
78 | * OPTIONAL pointer to miscellaneous user-provided context information |
79 | * |
80 | * user_fctx is for use as a pointer to your own struct to retain |
81 | * arbitrary context information between calls of your function. |
82 | */ |
83 | void *user_fctx; |
84 | |
85 | /* |
86 | * OPTIONAL pointer to struct containing attribute type input metadata |
87 | * |
88 | * attinmeta is for use when returning tuples (i.e. composite data types) |
89 | * and is not used when returning base data types. It is only needed if |
90 | * you intend to use BuildTupleFromCStrings() to create the return tuple. |
91 | */ |
92 | AttInMetadata *attinmeta; |
93 | |
94 | /* |
95 | * memory context used for structures that must live for multiple calls |
96 | * |
97 | * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used |
98 | * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory |
99 | * context for any memory that is to be reused across multiple calls of |
100 | * the SRF. |
101 | */ |
102 | MemoryContext multi_call_memory_ctx; |
103 | |
104 | /* |
105 | * OPTIONAL pointer to struct containing tuple description |
106 | * |
107 | * tuple_desc is for use when returning tuples (i.e. composite data types) |
108 | * and is only needed if you are going to build the tuples with |
109 | * heap_form_tuple() rather than with BuildTupleFromCStrings(). Note that |
110 | * the TupleDesc pointer stored here should usually have been run through |
111 | * BlessTupleDesc() first. |
112 | */ |
113 | TupleDesc tuple_desc; |
114 | |
115 | } FuncCallContext; |
116 | |
117 | /*---------- |
118 | * Support to ease writing functions returning composite types |
119 | * |
120 | * External declarations: |
121 | * get_call_result_type: |
122 | * Given a function's call info record, determine the kind of datatype |
123 | * it is supposed to return. If resultTypeId isn't NULL, *resultTypeId |
124 | * receives the actual datatype OID (this is mainly useful for scalar |
125 | * result types). If resultTupleDesc isn't NULL, *resultTupleDesc |
126 | * receives a pointer to a TupleDesc when the result is of a composite |
127 | * type, or NULL when it's a scalar result or the rowtype could not be |
128 | * determined. NB: the tupledesc should be copied if it is to be |
129 | * accessed over a long period. |
130 | * get_expr_result_type: |
131 | * Given an expression node, return the same info as for |
132 | * get_call_result_type. Note: the cases in which rowtypes cannot be |
133 | * determined are different from the cases for get_call_result_type. |
134 | * get_func_result_type: |
135 | * Given only a function's OID, return the same info as for |
136 | * get_call_result_type. Note: the cases in which rowtypes cannot be |
137 | * determined are different from the cases for get_call_result_type. |
138 | * Do *not* use this if you can use one of the others. |
139 | * |
140 | * See also get_expr_result_tupdesc(), which is a convenient wrapper around |
141 | * get_expr_result_type() for use when the caller only cares about |
142 | * determinable-rowtype cases. |
143 | *---------- |
144 | */ |
145 | |
146 | /* Type categories for get_call_result_type and siblings */ |
147 | typedef enum TypeFuncClass |
148 | { |
149 | TYPEFUNC_SCALAR, /* scalar result type */ |
150 | TYPEFUNC_COMPOSITE, /* determinable rowtype result */ |
151 | TYPEFUNC_COMPOSITE_DOMAIN, /* domain over determinable rowtype result */ |
152 | TYPEFUNC_RECORD, /* indeterminate rowtype result */ |
153 | TYPEFUNC_OTHER /* bogus type, eg pseudotype */ |
154 | } TypeFuncClass; |
155 | |
156 | extern TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, |
157 | Oid *resultTypeId, |
158 | TupleDesc *resultTupleDesc); |
159 | extern TypeFuncClass get_expr_result_type(Node *expr, |
160 | Oid *resultTypeId, |
161 | TupleDesc *resultTupleDesc); |
162 | extern TypeFuncClass get_func_result_type(Oid functionId, |
163 | Oid *resultTypeId, |
164 | TupleDesc *resultTupleDesc); |
165 | |
166 | extern TupleDesc get_expr_result_tupdesc(Node *expr, bool noError); |
167 | |
168 | extern bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, |
169 | char *argmodes, |
170 | Node *call_expr); |
171 | |
172 | extern int get_func_arg_info(HeapTuple procTup, |
173 | Oid **p_argtypes, char ***p_argnames, |
174 | char **p_argmodes); |
175 | |
176 | extern int get_func_input_arg_names(Datum proargnames, Datum proargmodes, |
177 | char ***arg_names); |
178 | |
179 | extern int get_func_trftypes(HeapTuple procTup, Oid **p_trftypes); |
180 | extern char *get_func_result_name(Oid functionId); |
181 | |
182 | extern TupleDesc build_function_result_tupdesc_d(char prokind, |
183 | Datum proallargtypes, |
184 | Datum proargmodes, |
185 | Datum proargnames); |
186 | extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple); |
187 | |
188 | |
189 | /*---------- |
190 | * Support to ease writing functions returning composite types |
191 | * |
192 | * External declarations: |
193 | * TupleDesc BlessTupleDesc(TupleDesc tupdesc) - "Bless" a completed tuple |
194 | * descriptor so that it can be used to return properly labeled tuples. |
195 | * You need to call this if you are going to use heap_form_tuple directly. |
196 | * TupleDescGetAttInMetadata does it for you, however, so no need to call |
197 | * it if you call TupleDescGetAttInMetadata. |
198 | * AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) - Build an |
199 | * AttInMetadata struct based on the given TupleDesc. AttInMetadata can |
200 | * be used in conjunction with C strings to produce a properly formed |
201 | * tuple. |
202 | * HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) - |
203 | * build a HeapTuple given user data in C string form. values is an array |
204 | * of C strings, one for each attribute of the return tuple. |
205 | * Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple) - convert a |
206 | * HeapTupleHeader to a Datum. |
207 | * |
208 | * Macro declarations: |
209 | * HeapTupleGetDatum(HeapTuple tuple) - convert a HeapTuple to a Datum. |
210 | * |
211 | * Obsolete routines and macros: |
212 | * TupleDesc RelationNameGetTupleDesc(const char *relname) - Use to get a |
213 | * TupleDesc based on a named relation. |
214 | * TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) - Use to get a |
215 | * TupleDesc based on a type OID. |
216 | * TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum |
217 | * given a tuple and a slot. |
218 | *---------- |
219 | */ |
220 | |
221 | #define HeapTupleGetDatum(tuple) HeapTupleHeaderGetDatum((tuple)->t_data) |
222 | /* obsolete version of above */ |
223 | #define TupleGetDatum(_slot, _tuple) HeapTupleGetDatum(_tuple) |
224 | |
225 | extern TupleDesc RelationNameGetTupleDesc(const char *relname); |
226 | extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases); |
227 | |
228 | /* from execTuples.c */ |
229 | extern TupleDesc BlessTupleDesc(TupleDesc tupdesc); |
230 | extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc); |
231 | extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values); |
232 | extern Datum (HeapTupleHeader tuple); |
233 | |
234 | |
235 | /*---------- |
236 | * Support for Set Returning Functions (SRFs) |
237 | * |
238 | * The basic API for SRFs looks something like: |
239 | * |
240 | * Datum |
241 | * my_Set_Returning_Function(PG_FUNCTION_ARGS) |
242 | * { |
243 | * FuncCallContext *funcctx; |
244 | * Datum result; |
245 | * MemoryContext oldcontext; |
246 | * <user defined declarations> |
247 | * |
248 | * if (SRF_IS_FIRSTCALL()) |
249 | * { |
250 | * funcctx = SRF_FIRSTCALL_INIT(); |
251 | * // switch context when allocating stuff to be used in later calls |
252 | * oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); |
253 | * <user defined code> |
254 | * <if returning composite> |
255 | * <build TupleDesc, and perhaps AttInMetadata> |
256 | * <endif returning composite> |
257 | * <user defined code> |
258 | * // return to original context when allocating transient memory |
259 | * MemoryContextSwitchTo(oldcontext); |
260 | * } |
261 | * <user defined code> |
262 | * funcctx = SRF_PERCALL_SETUP(); |
263 | * <user defined code> |
264 | * |
265 | * if (funcctx->call_cntr < funcctx->max_calls) |
266 | * { |
267 | * <user defined code> |
268 | * <obtain result Datum> |
269 | * SRF_RETURN_NEXT(funcctx, result); |
270 | * } |
271 | * else |
272 | * SRF_RETURN_DONE(funcctx); |
273 | * } |
274 | * |
275 | *---------- |
276 | */ |
277 | |
278 | /* from funcapi.c */ |
279 | extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS); |
280 | extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS); |
281 | extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx); |
282 | |
283 | #define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL) |
284 | |
285 | #define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo) |
286 | |
287 | #define SRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo) |
288 | |
289 | #define SRF_RETURN_NEXT(_funcctx, _result) \ |
290 | do { \ |
291 | ReturnSetInfo *rsi; \ |
292 | (_funcctx)->call_cntr++; \ |
293 | rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ |
294 | rsi->isDone = ExprMultipleResult; \ |
295 | PG_RETURN_DATUM(_result); \ |
296 | } while (0) |
297 | |
298 | #define SRF_RETURN_NEXT_NULL(_funcctx) \ |
299 | do { \ |
300 | ReturnSetInfo *rsi; \ |
301 | (_funcctx)->call_cntr++; \ |
302 | rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ |
303 | rsi->isDone = ExprMultipleResult; \ |
304 | PG_RETURN_NULL(); \ |
305 | } while (0) |
306 | |
307 | #define SRF_RETURN_DONE(_funcctx) \ |
308 | do { \ |
309 | ReturnSetInfo *rsi; \ |
310 | end_MultiFuncCall(fcinfo, _funcctx); \ |
311 | rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ |
312 | rsi->isDone = ExprEndResult; \ |
313 | PG_RETURN_NULL(); \ |
314 | } while (0) |
315 | |
316 | /*---------- |
317 | * Support to ease writing of functions dealing with VARIADIC inputs |
318 | *---------- |
319 | * |
320 | * This function extracts a set of argument values, types and NULL markers |
321 | * for a given input function. This returns a set of data: |
322 | * - **values includes the set of Datum values extracted. |
323 | * - **types the data type OID for each element. |
324 | * - **nulls tracks if an element is NULL. |
325 | * |
326 | * variadic_start indicates the argument number where the VARIADIC argument |
327 | * starts. |
328 | * convert_unknown set to true will enforce the conversion of arguments |
329 | * with unknown data type to text. |
330 | * |
331 | * The return result is the number of elements stored, or -1 in the case of |
332 | * "VARIADIC NULL". |
333 | */ |
334 | extern int (FunctionCallInfo fcinfo, int variadic_start, |
335 | bool convert_unknown, Datum **values, |
336 | Oid **types, bool **nulls); |
337 | |
338 | #endif /* FUNCAPI_H */ |
339 | |