Header And Logo

PostgreSQL
| The world's most advanced open source database.

funcapi.h

Go to the documentation of this file.
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 */