]> granicus.if.org Git - postgresql/blob - src/include/funcapi.h
Make Win32 build use our port/snprintf.c routines, instead of depending
[postgresql] / src / include / funcapi.h
1 /*-------------------------------------------------------------------------
2  *
3  * funcapi.h
4  *        Definitions for functions which return composite type and/or sets
5  *
6  * This file must be included by all Postgres modules that either define
7  * or call FUNCAPI-callable functions or macros.
8  *
9  *
10  * Copyright (c) 2002-2005, PostgreSQL Global Development Group
11  *
12  * $PostgreSQL: pgsql/src/include/funcapi.h,v 1.21 2005/11/22 18:17:29 momjian Exp $
13  *
14  *-------------------------------------------------------------------------
15  */
16 #ifndef FUNCAPI_H
17 #define FUNCAPI_H
18
19 #include "fmgr.h"
20 #include "access/tupdesc.h"
21 #include "executor/executor.h"
22 #include "executor/tuptable.h"
23
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         uint32          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         uint32          max_calls;
75
76         /*
77          * OPTIONAL pointer to result slot
78          *
79          * This is obsolete and only present for backwards compatibility, viz,
80          * user-defined SRFs that use the deprecated TupleDescGetSlot().
81          */
82         TupleTableSlot *slot;
83
84         /*
85          * OPTIONAL pointer to miscellaneous user-provided context information
86          *
87          * user_fctx is for use as a pointer to your own struct to retain
88          * arbitrary context information between calls of your function.
89          */
90         void       *user_fctx;
91
92         /*
93          * OPTIONAL pointer to struct containing attribute type input metadata
94          *
95          * attinmeta is for use when returning tuples (i.e. composite data types)
96          * and is not used when returning base data types. It is only needed if
97          * you intend to use BuildTupleFromCStrings() to create the return tuple.
98          */
99         AttInMetadata *attinmeta;
100
101         /*
102          * memory context used for structures that must live for multiple calls
103          *
104          * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used
105          * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory
106          * context for any memory that is to be reused across multiple calls of
107          * the SRF.
108          */
109         MemoryContext multi_call_memory_ctx;
110
111         /*
112          * OPTIONAL pointer to struct containing tuple description
113          *
114          * tuple_desc is for use when returning tuples (i.e. composite data types)
115          * and is only needed if you are going to build the tuples with
116          * heap_formtuple() rather than with BuildTupleFromCStrings().  Note that
117          * the TupleDesc pointer stored here should usually have been run through
118          * BlessTupleDesc() first.
119          */
120         TupleDesc       tuple_desc;
121
122 } FuncCallContext;
123
124 /*----------
125  *      Support to ease writing functions returning composite types
126  *
127  * External declarations:
128  * get_call_result_type:
129  *              Given a function's call info record, determine the kind of datatype
130  *              it is supposed to return.  If resultTypeId isn't NULL, *resultTypeId
131  *              receives the actual datatype OID (this is mainly useful for scalar
132  *              result types).  If resultTupleDesc isn't NULL, *resultTupleDesc
133  *              receives a pointer to a TupleDesc when the result is of a composite
134  *              type, or NULL when it's a scalar result or the rowtype could not be
135  *              determined.  NB: the tupledesc should be copied if it is to be
136  *              accessed over a long period.
137  * get_expr_result_type:
138  *              Given an expression node, return the same info as for
139  *              get_call_result_type.  Note: the cases in which rowtypes cannot be
140  *              determined are different from the cases for get_call_result_type.
141  * get_func_result_type:
142  *              Given only a function's OID, return the same info as for
143  *              get_call_result_type.  Note: the cases in which rowtypes cannot be
144  *              determined are different from the cases for get_call_result_type.
145  *              Do *not* use this if you can use one of the others.
146  *----------
147  */
148
149 /* Type categories for get_call_result_type and siblings */
150 typedef enum TypeFuncClass
151 {
152         TYPEFUNC_SCALAR,                        /* scalar result type */
153         TYPEFUNC_COMPOSITE,                     /* determinable rowtype result */
154         TYPEFUNC_RECORD,                        /* indeterminate rowtype result */
155         TYPEFUNC_OTHER                          /* bogus type, eg pseudotype */
156 } TypeFuncClass;
157
158 extern TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,
159                                          Oid *resultTypeId,
160                                          TupleDesc *resultTupleDesc);
161 extern TypeFuncClass get_expr_result_type(Node *expr,
162                                          Oid *resultTypeId,
163                                          TupleDesc *resultTupleDesc);
164 extern TypeFuncClass get_func_result_type(Oid functionId,
165                                          Oid *resultTypeId,
166                                          TupleDesc *resultTupleDesc);
167
168 extern char *get_func_result_name(Oid functionId);
169
170 extern bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes,
171                                                          char *argmodes,
172                                                          Node *call_expr);
173
174 extern TupleDesc build_function_result_tupdesc_d(Datum proallargtypes,
175                                                                 Datum proargmodes,
176                                                                 Datum proargnames);
177 extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple);
178
179
180 /*----------
181  *      Support to ease writing functions returning composite types
182  *
183  * External declarations:
184  * TupleDesc BlessTupleDesc(TupleDesc tupdesc) - "Bless" a completed tuple
185  *              descriptor so that it can be used to return properly labeled tuples.
186  *              You need to call this if you are going to use heap_formtuple directly.
187  *              TupleDescGetAttInMetadata does it for you, however, so no need to call
188  *              it if you call TupleDescGetAttInMetadata.
189  * AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) - Build an
190  *              AttInMetadata struct based on the given TupleDesc. AttInMetadata can
191  *              be used in conjunction with C strings to produce a properly formed
192  *              tuple.
193  * HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) -
194  *              build a HeapTuple given user data in C string form. values is an array
195  *              of C strings, one for each attribute of the return tuple.
196  *
197  * Macro declarations:
198  * HeapTupleGetDatum(HeapTuple tuple) - convert a HeapTuple to a Datum.
199  *
200  * Obsolete routines and macros:
201  * TupleDesc RelationNameGetTupleDesc(const char *relname) - Use to get a
202  *              TupleDesc based on a named relation.
203  * TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) - Use to get a
204  *              TupleDesc based on a type OID.
205  * TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc) - Builds a
206  *              TupleTableSlot, which is not needed anymore.
207  * TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum
208  *              given a tuple and a slot.
209  *----------
210  */
211
212 #define HeapTupleGetDatum(_tuple)               PointerGetDatum((_tuple)->t_data)
213 /* obsolete version of above */
214 #define TupleGetDatum(_slot, _tuple)    PointerGetDatum((_tuple)->t_data)
215
216 extern TupleDesc RelationNameGetTupleDesc(const char *relname);
217 extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases);
218
219 /* from execTuples.c */
220 extern TupleDesc BlessTupleDesc(TupleDesc tupdesc);
221 extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc);
222 extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values);
223 extern TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc);
224
225
226 /*----------
227  *              Support for Set Returning Functions (SRFs)
228  *
229  * The basic API for SRFs looks something like:
230  *
231  * Datum
232  * my_Set_Returning_Function(PG_FUNCTION_ARGS)
233  * {
234  *      FuncCallContext    *funcctx;
235  *      Datum                           result;
236  *      MemoryContext           oldcontext;
237  *      <user defined declarations>
238  *
239  *      if (SRF_IS_FIRSTCALL())
240  *      {
241  *              funcctx = SRF_FIRSTCALL_INIT();
242  *              // switch context when allocating stuff to be used in later calls
243  *              oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
244  *              <user defined code>
245  *              <if returning composite>
246  *                      <build TupleDesc, and perhaps AttInMetaData>
247  *              <endif returning composite>
248  *              <user defined code>
249  *              // return to original context when allocating transient memory
250  *              MemoryContextSwitchTo(oldcontext);
251  *      }
252  *      <user defined code>
253  *      funcctx = SRF_PERCALL_SETUP();
254  *      <user defined code>
255  *
256  *      if (funcctx->call_cntr < funcctx->max_calls)
257  *      {
258  *              <user defined code>
259  *              <obtain result Datum>
260  *              SRF_RETURN_NEXT(funcctx, result);
261  *      }
262  *      else
263  *              SRF_RETURN_DONE(funcctx);
264  * }
265  *
266  *----------
267  */
268
269 /* from funcapi.c */
270 extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS);
271 extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS);
272 extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx);
273
274 #define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL)
275
276 #define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo)
277
278 #define SRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo)
279
280 #define SRF_RETURN_NEXT(_funcctx, _result) \
281         do { \
282                 ReturnSetInfo      *rsi; \
283                 (_funcctx)->call_cntr++; \
284                 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
285                 rsi->isDone = ExprMultipleResult; \
286                 PG_RETURN_DATUM(_result); \
287         } while (0)
288
289 #define  SRF_RETURN_DONE(_funcctx) \
290         do { \
291                 ReturnSetInfo      *rsi; \
292                 end_MultiFuncCall(fcinfo, _funcctx); \
293                 rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
294                 rsi->isDone = ExprEndResult; \
295                 PG_RETURN_NULL(); \
296         } while (0)
297
298 #endif   /* FUNCAPI_H */