Skip to content

Commit 7191652

Browse files
committed
Add another missing SRF file.
1 parent 27bce57 commit 7191652

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed

src/include/funcapi.h

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
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, PostgreSQL Global Development Group
11+
*
12+
*
13+
*-------------------------------------------------------------------------
14+
*/
15+
#ifndef FUNCAPI_H
16+
#define FUNCAPI_H
17+
18+
#include "postgres.h"
19+
20+
#include "fmgr.h"
21+
#include "access/htup.h"
22+
#include "access/tupdesc.h"
23+
#include "executor/executor.h"
24+
#include "executor/tuptable.h"
25+
26+
/*
27+
* All functions that can be called directly by fmgr must have this signature.
28+
* (Other functions can be called by using a handler that does have this
29+
* signature.)
30+
*/
31+
32+
33+
/*-------------------------------------------------------------------------
34+
* Support to ease writing Functions returning composite types
35+
*-------------------------------------------------------------------------
36+
*
37+
* This struct holds arrays of individual attribute information
38+
* needed to create a tuple from raw C strings. It also requires
39+
* a copy of the TupleDesc. The information carried here
40+
* is derived from the TupleDesc, but it is stored here to
41+
* avoid redundant cpu cycles on each call to an SRF.
42+
*/
43+
typedef struct
44+
{
45+
/* full TupleDesc */
46+
TupleDesc tupdesc;
47+
48+
/* pointer to array of attribute "type"in finfo */
49+
FmgrInfo *attinfuncs;
50+
51+
/* pointer to array of attribute type typelem */
52+
Oid *attelems;
53+
54+
/* pointer to array of attribute type typtypmod */
55+
int4 *atttypmods;
56+
57+
} AttInMetadata;
58+
59+
/*-------------------------------------------------------------------------
60+
* Support struct to ease writing Set Returning Functions (SRFs)
61+
*-------------------------------------------------------------------------
62+
*
63+
* This struct holds function context for Set Returning Functions.
64+
* Use fn_extra to hold a pointer to it across calls
65+
*/
66+
typedef struct
67+
{
68+
/* Number of times we've been called before */
69+
uint call_cntr;
70+
71+
/* Maximum number of calls */
72+
uint max_calls;
73+
74+
/* pointer to result slot */
75+
TupleTableSlot *slot;
76+
77+
/* pointer to misc context info */
78+
void *fctx;
79+
80+
/* pointer to struct containing arrays of attribute type input metainfo */
81+
AttInMetadata *attinmeta;
82+
83+
/* memory context used to initialize structure */
84+
MemoryContext fmctx;
85+
86+
} FuncCallContext;
87+
88+
/*-------------------------------------------------------------------------
89+
* Support to ease writing Functions returning composite types
90+
*
91+
* External declarations:
92+
* TupleDesc RelationNameGetTupleDesc(char *relname) - Use to get a TupleDesc
93+
* based on the function's return type relation.
94+
* TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) - Use to get a
95+
* TupleDesc based on the function's type oid. This can be used to get
96+
* a TupleDesc for a base (scalar), or composite (relation) type.
97+
* TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc) - Initialize a slot
98+
* given a TupleDesc.
99+
* AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) - Get a pointer
100+
* to AttInMetadata based on the function's TupleDesc. AttInMetadata can
101+
* be used in conjunction with C strings to produce a properly formed
102+
* tuple. Store the metadata here for use across calls to avoid redundant
103+
* work.
104+
* HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) -
105+
* build a HeapTuple given user data in C string form. values is an array
106+
* of C strings, one for each attribute of the return tuple.
107+
*
108+
* Macro declarations:
109+
* TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum
110+
* given a tuple and a slot.
111+
*/
112+
113+
/* from tupdesc.c */
114+
extern TupleDesc RelationNameGetTupleDesc(char *relname);
115+
extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases);
116+
117+
/* from execTuples.c */
118+
extern TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc);
119+
extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc);
120+
extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values);
121+
122+
/* from funcapi.c */
123+
extern void get_type_metadata(Oid typeid, Oid *attinfuncid, Oid *attelem);
124+
125+
#define TupleGetDatum(_slot, _tuple) \
126+
PointerGetDatum(ExecStoreTuple(_tuple, _slot, InvalidBuffer, true))
127+
128+
/*-------------------------------------------------------------------------
129+
* Support for Set Returning Functions (SRFs)
130+
*
131+
* The basic API for SRFs looks something like:
132+
*
133+
* Datum
134+
* my_Set_Returning_Function(PG_FUNCTION_ARGS)
135+
* {
136+
* FuncCallContext *funcctx;
137+
* Datum result;
138+
* <user defined declarations>
139+
*
140+
* if(SRF_IS_FIRSTPASS())
141+
* {
142+
* <user defined code>
143+
* funcctx = SRF_FIRSTCALL_INIT();
144+
* <if returning composite>
145+
* <obtain slot>
146+
* funcctx->slot = slot;
147+
* <endif returning composite>
148+
* <user defined code>
149+
* }
150+
* <user defined code>
151+
* funcctx = SRF_PERCALL_SETUP(funcctx);
152+
* <user defined code>
153+
*
154+
* if (funcctx->call_cntr < funcctx->max_calls)
155+
* {
156+
* <user defined code>
157+
* <obtain result Datum>
158+
* SRF_RETURN_NEXT(funcctx, result);
159+
* }
160+
* else
161+
* {
162+
* SRF_RETURN_DONE(funcctx);
163+
* }
164+
* }
165+
*
166+
*/
167+
168+
/* from funcapi.c */
169+
extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS);
170+
extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx);
171+
172+
#define SRF_IS_FIRSTPASS() (fcinfo->flinfo->fn_extra == NULL)
173+
#define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo)
174+
#define SRF_PERCALL_SETUP(_funcctx) \
175+
fcinfo->flinfo->fn_extra; \
176+
if(_funcctx->slot != NULL) \
177+
ExecClearTuple(_funcctx->slot)
178+
#define SRF_RETURN_NEXT(_funcctx, _result) \
179+
do { \
180+
ReturnSetInfo *rsi; \
181+
_funcctx->call_cntr++; \
182+
rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
183+
rsi->isDone = ExprMultipleResult; \
184+
PG_RETURN_DATUM(_result); \
185+
} while (0)
186+
187+
#define SRF_RETURN_DONE(_funcctx) \
188+
do { \
189+
ReturnSetInfo *rsi; \
190+
end_MultiFuncCall(fcinfo, _funcctx); \
191+
rsi = (ReturnSetInfo *) fcinfo->resultinfo; \
192+
rsi->isDone = ExprEndResult; \
193+
_funcctx->slot = NULL; \
194+
PG_RETURN_NULL(); \
195+
} while (0)
196+
197+
#endif /* FUNCAPI_H */

0 commit comments

Comments
 (0)