|
| 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 | +#ifndefFUNCAPI_H |
| 16 | +#defineFUNCAPI_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 | +typedefstruct |
| 44 | +{ |
| 45 | +/* full TupleDesc */ |
| 46 | +TupleDesctupdesc; |
| 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 | +typedefstruct |
| 67 | +{ |
| 68 | +/* Number of times we've been called before */ |
| 69 | +uintcall_cntr; |
| 70 | + |
| 71 | +/* Maximum number of calls */ |
| 72 | +uintmax_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 | +MemoryContextfmctx; |
| 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 | +externTupleDescRelationNameGetTupleDesc(char*relname); |
| 115 | +externTupleDescTypeGetTupleDesc(Oidtypeoid,List*colaliases); |
| 116 | + |
| 117 | +/* from execTuples.c */ |
| 118 | +externTupleTableSlot*TupleDescGetSlot(TupleDesctupdesc); |
| 119 | +externAttInMetadata*TupleDescGetAttInMetadata(TupleDesctupdesc); |
| 120 | +externHeapTupleBuildTupleFromCStrings(AttInMetadata*attinmeta,char**values); |
| 121 | + |
| 122 | +/* from funcapi.c */ |
| 123 | +externvoidget_type_metadata(Oidtypeid,Oid*attinfuncid,Oid*attelem); |
| 124 | + |
| 125 | +#defineTupleGetDatum(_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 | + * Datumresult; |
| 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 | +externFuncCallContext*init_MultiFuncCall(PG_FUNCTION_ARGS); |
| 170 | +externvoidend_MultiFuncCall(PG_FUNCTION_ARGS,FuncCallContext*funcctx); |
| 171 | + |
| 172 | +#defineSRF_IS_FIRSTPASS() (fcinfo->flinfo->fn_extra == NULL) |
| 173 | +#defineSRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo) |
| 174 | +#defineSRF_PERCALL_SETUP(_funcctx) \ |
| 175 | +fcinfo->flinfo->fn_extra; \ |
| 176 | +if(_funcctx->slot != NULL) \ |
| 177 | +ExecClearTuple(_funcctx->slot) |
| 178 | +#defineSRF_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 | +#defineSRF_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 */ |