| 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 | |