00001 /*------------------------------------------------------------------------- 00002 * 00003 * funcapi.h 00004 * Definitions for functions which return composite type and/or sets 00005 * 00006 * This file must be included by all Postgres modules that either define 00007 * or call FUNCAPI-callable functions or macros. 00008 * 00009 * 00010 * Copyright (c) 2002-2013, PostgreSQL Global Development Group 00011 * 00012 * src/include/funcapi.h 00013 * 00014 *------------------------------------------------------------------------- 00015 */ 00016 #ifndef FUNCAPI_H 00017 #define FUNCAPI_H 00018 00019 #include "fmgr.h" 00020 #include "access/tupdesc.h" 00021 #include "executor/executor.h" 00022 #include "executor/tuptable.h" 00023 00024 00025 /*------------------------------------------------------------------------- 00026 * Support to ease writing Functions returning composite types 00027 *------------------------------------------------------------------------- 00028 * 00029 * This struct holds arrays of individual attribute information 00030 * needed to create a tuple from raw C strings. It also requires 00031 * a copy of the TupleDesc. The information carried here 00032 * is derived from the TupleDesc, but it is stored here to 00033 * avoid redundant cpu cycles on each call to an SRF. 00034 */ 00035 typedef struct AttInMetadata 00036 { 00037 /* full TupleDesc */ 00038 TupleDesc tupdesc; 00039 00040 /* array of attribute type input function finfo */ 00041 FmgrInfo *attinfuncs; 00042 00043 /* array of attribute type i/o parameter OIDs */ 00044 Oid *attioparams; 00045 00046 /* array of attribute typmod */ 00047 int32 *atttypmods; 00048 } AttInMetadata; 00049 00050 /*------------------------------------------------------------------------- 00051 * Support struct to ease writing Set Returning Functions (SRFs) 00052 *------------------------------------------------------------------------- 00053 * 00054 * This struct holds function context for Set Returning Functions. 00055 * Use fn_extra to hold a pointer to it across calls 00056 */ 00057 typedef struct FuncCallContext 00058 { 00059 /* 00060 * Number of times we've been called before 00061 * 00062 * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and 00063 * incremented for you every time SRF_RETURN_NEXT() is called. 00064 */ 00065 uint32 call_cntr; 00066 00067 /* 00068 * OPTIONAL maximum number of calls 00069 * 00070 * max_calls is here for convenience only and setting it is optional. If 00071 * not set, you must provide alternative means to know when the function 00072 * is done. 00073 */ 00074 uint32 max_calls; 00075 00076 /* 00077 * OPTIONAL pointer to result slot 00078 * 00079 * This is obsolete and only present for backwards compatibility, viz, 00080 * user-defined SRFs that use the deprecated TupleDescGetSlot(). 00081 */ 00082 TupleTableSlot *slot; 00083 00084 /* 00085 * OPTIONAL pointer to miscellaneous user-provided context information 00086 * 00087 * user_fctx is for use as a pointer to your own struct to retain 00088 * arbitrary context information between calls of your function. 00089 */ 00090 void *user_fctx; 00091 00092 /* 00093 * OPTIONAL pointer to struct containing attribute type input metadata 00094 * 00095 * attinmeta is for use when returning tuples (i.e. composite data types) 00096 * and is not used when returning base data types. It is only needed if 00097 * you intend to use BuildTupleFromCStrings() to create the return tuple. 00098 */ 00099 AttInMetadata *attinmeta; 00100 00101 /* 00102 * memory context used for structures that must live for multiple calls 00103 * 00104 * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used 00105 * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory 00106 * context for any memory that is to be reused across multiple calls of 00107 * the SRF. 00108 */ 00109 MemoryContext multi_call_memory_ctx; 00110 00111 /* 00112 * OPTIONAL pointer to struct containing tuple description 00113 * 00114 * tuple_desc is for use when returning tuples (i.e. composite data types) 00115 * and is only needed if you are going to build the tuples with 00116 * heap_form_tuple() rather than with BuildTupleFromCStrings(). Note that 00117 * the TupleDesc pointer stored here should usually have been run through 00118 * BlessTupleDesc() first. 00119 */ 00120 TupleDesc tuple_desc; 00121 00122 } FuncCallContext; 00123 00124 /*---------- 00125 * Support to ease writing functions returning composite types 00126 * 00127 * External declarations: 00128 * get_call_result_type: 00129 * Given a function's call info record, determine the kind of datatype 00130 * it is supposed to return. If resultTypeId isn't NULL, *resultTypeId 00131 * receives the actual datatype OID (this is mainly useful for scalar 00132 * result types). If resultTupleDesc isn't NULL, *resultTupleDesc 00133 * receives a pointer to a TupleDesc when the result is of a composite 00134 * type, or NULL when it's a scalar result or the rowtype could not be 00135 * determined. NB: the tupledesc should be copied if it is to be 00136 * accessed over a long period. 00137 * get_expr_result_type: 00138 * Given an expression node, return the same info as for 00139 * get_call_result_type. Note: the cases in which rowtypes cannot be 00140 * determined are different from the cases for get_call_result_type. 00141 * get_func_result_type: 00142 * Given only a function's OID, return the same info as for 00143 * get_call_result_type. Note: the cases in which rowtypes cannot be 00144 * determined are different from the cases for get_call_result_type. 00145 * Do *not* use this if you can use one of the others. 00146 *---------- 00147 */ 00148 00149 /* Type categories for get_call_result_type and siblings */ 00150 typedef enum TypeFuncClass 00151 { 00152 TYPEFUNC_SCALAR, /* scalar result type */ 00153 TYPEFUNC_COMPOSITE, /* determinable rowtype result */ 00154 TYPEFUNC_RECORD, /* indeterminate rowtype result */ 00155 TYPEFUNC_OTHER /* bogus type, eg pseudotype */ 00156 } TypeFuncClass; 00157 00158 extern TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, 00159 Oid *resultTypeId, 00160 TupleDesc *resultTupleDesc); 00161 extern TypeFuncClass get_expr_result_type(Node *expr, 00162 Oid *resultTypeId, 00163 TupleDesc *resultTupleDesc); 00164 extern TypeFuncClass get_func_result_type(Oid functionId, 00165 Oid *resultTypeId, 00166 TupleDesc *resultTupleDesc); 00167 00168 extern bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, 00169 char *argmodes, 00170 Node *call_expr); 00171 00172 extern int get_func_arg_info(HeapTuple procTup, 00173 Oid **p_argtypes, char ***p_argnames, 00174 char **p_argmodes); 00175 00176 extern int get_func_input_arg_names(Datum proargnames, Datum proargmodes, 00177 char ***arg_names); 00178 00179 extern char *get_func_result_name(Oid functionId); 00180 00181 extern TupleDesc build_function_result_tupdesc_d(Datum proallargtypes, 00182 Datum proargmodes, 00183 Datum proargnames); 00184 extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple); 00185 00186 00187 /*---------- 00188 * Support to ease writing functions returning composite types 00189 * 00190 * External declarations: 00191 * TupleDesc BlessTupleDesc(TupleDesc tupdesc) - "Bless" a completed tuple 00192 * descriptor so that it can be used to return properly labeled tuples. 00193 * You need to call this if you are going to use heap_form_tuple directly. 00194 * TupleDescGetAttInMetadata does it for you, however, so no need to call 00195 * it if you call TupleDescGetAttInMetadata. 00196 * AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) - Build an 00197 * AttInMetadata struct based on the given TupleDesc. AttInMetadata can 00198 * be used in conjunction with C strings to produce a properly formed 00199 * tuple. 00200 * HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) - 00201 * build a HeapTuple given user data in C string form. values is an array 00202 * of C strings, one for each attribute of the return tuple. 00203 * 00204 * Macro declarations: 00205 * HeapTupleGetDatum(HeapTuple tuple) - convert a HeapTuple to a Datum. 00206 * 00207 * Obsolete routines and macros: 00208 * TupleDesc RelationNameGetTupleDesc(const char *relname) - Use to get a 00209 * TupleDesc based on a named relation. 00210 * TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) - Use to get a 00211 * TupleDesc based on a type OID. 00212 * TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc) - Builds a 00213 * TupleTableSlot, which is not needed anymore. 00214 * TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum 00215 * given a tuple and a slot. 00216 *---------- 00217 */ 00218 00219 #define HeapTupleGetDatum(_tuple) PointerGetDatum((_tuple)->t_data) 00220 /* obsolete version of above */ 00221 #define TupleGetDatum(_slot, _tuple) PointerGetDatum((_tuple)->t_data) 00222 00223 extern TupleDesc RelationNameGetTupleDesc(const char *relname); 00224 extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases); 00225 00226 /* from execTuples.c */ 00227 extern TupleDesc BlessTupleDesc(TupleDesc tupdesc); 00228 extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc); 00229 extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values); 00230 extern TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc); 00231 00232 00233 /*---------- 00234 * Support for Set Returning Functions (SRFs) 00235 * 00236 * The basic API for SRFs looks something like: 00237 * 00238 * Datum 00239 * my_Set_Returning_Function(PG_FUNCTION_ARGS) 00240 * { 00241 * FuncCallContext *funcctx; 00242 * Datum result; 00243 * MemoryContext oldcontext; 00244 * <user defined declarations> 00245 * 00246 * if (SRF_IS_FIRSTCALL()) 00247 * { 00248 * funcctx = SRF_FIRSTCALL_INIT(); 00249 * // switch context when allocating stuff to be used in later calls 00250 * oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); 00251 * <user defined code> 00252 * <if returning composite> 00253 * <build TupleDesc, and perhaps AttInMetaData> 00254 * <endif returning composite> 00255 * <user defined code> 00256 * // return to original context when allocating transient memory 00257 * MemoryContextSwitchTo(oldcontext); 00258 * } 00259 * <user defined code> 00260 * funcctx = SRF_PERCALL_SETUP(); 00261 * <user defined code> 00262 * 00263 * if (funcctx->call_cntr < funcctx->max_calls) 00264 * { 00265 * <user defined code> 00266 * <obtain result Datum> 00267 * SRF_RETURN_NEXT(funcctx, result); 00268 * } 00269 * else 00270 * SRF_RETURN_DONE(funcctx); 00271 * } 00272 * 00273 *---------- 00274 */ 00275 00276 /* from funcapi.c */ 00277 extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS); 00278 extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS); 00279 extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx); 00280 00281 #define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL) 00282 00283 #define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo) 00284 00285 #define SRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo) 00286 00287 #define SRF_RETURN_NEXT(_funcctx, _result) \ 00288 do { \ 00289 ReturnSetInfo *rsi; \ 00290 (_funcctx)->call_cntr++; \ 00291 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ 00292 rsi->isDone = ExprMultipleResult; \ 00293 PG_RETURN_DATUM(_result); \ 00294 } while (0) 00295 00296 #define SRF_RETURN_DONE(_funcctx) \ 00297 do { \ 00298 ReturnSetInfo *rsi; \ 00299 end_MultiFuncCall(fcinfo, _funcctx); \ 00300 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ 00301 rsi->isDone = ExprEndResult; \ 00302 PG_RETURN_NULL(); \ 00303 } while (0) 00304 00305 #endif /* FUNCAPI_H */