LCOV - differential code coverage report
Current view: top level - src/include - funcapi.h (source / functions) Coverage Total Hit GNC ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 100.0 % 2 2 2 2
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 1 1 1 1
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a