*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.53 2002/06/20 20:29:27 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.54 2002/07/18 04:40:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
natts = tupdesc->natts;
dvalues = (Datum *) palloc(natts * sizeof(Datum));
+ nulls = (char *) palloc(natts * sizeof(char));
/* Call the "in" function for each attribute */
for (i = 0; i < natts; i++)
dvalues[i] = FunctionCall3(&attinfuncinfo, CStringGetDatum(values[i]),
ObjectIdGetDatum(attelem),
Int32GetDatum(atttypmod));
+ nulls[i] = ' ';
}
else
+ {
dvalues[i] = PointerGetDatum(NULL);
+ nulls[i] = 'n';
+ }
}
/*
* Form a tuple
*/
- nulls = (char *) palloc(natts * sizeof(char));
- for (i = 0; i < natts; i++)
- {
- if (DatumGetPointer(dvalues[i]) != NULL)
- nulls[i] = ' ';
- else
- nulls[i] = 'n';
- }
tuple = heap_formtuple(tupdesc, dvalues, nulls);
return tuple;
retval->call_cntr = 0;
retval->max_calls = 0;
retval->slot = NULL;
- retval->fctx = NULL;
+ retval->user_fctx = NULL;
retval->attinmeta = NULL;
retval->fmctx = fcinfo->flinfo->fn_mcxt;
return retval;
}
+/*
+ * per_MultiFuncCall
+ *
+ * Do Multi-function per-call setup
+ */
+FuncCallContext *
+per_MultiFuncCall(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *retval = (FuncCallContext *) fcinfo->flinfo->fn_extra;
+
+ /* make sure we start with a fresh slot */
+ if(retval->slot != NULL)
+ ExecClearTuple(retval->slot);
+
+ return retval;
+}
+
/*
* end_MultiFuncCall
* Clean up after init_MultiFuncCall
*/
typedef struct
{
- /* Number of times we've been called before */
+ /*
+ * Number of times we've been called before.
+ *
+ * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and
+ * incremented for you every time SRF_RETURN_NEXT() is called.
+ */
uint32 call_cntr;
- /* Maximum number of calls */
+ /*
+ * OPTIONAL maximum number of calls
+ *
+ * max_calls is here for convenience ONLY and setting it is OPTIONAL.
+ * If not set, you must provide alternative means to know when the
+ * function is done.
+ */
uint32 max_calls;
- /* pointer to result slot */
+ /*
+ * OPTIONAL pointer to result slot
+ *
+ * slot is for use when returning tuples (i.e. composite data types)
+ * and is not needed when returning base (i.e. scalar) data types.
+ */
TupleTableSlot *slot;
- /* pointer to misc context info */
- void *fctx;
-
- /* pointer to struct containing arrays of attribute type input metainfo */
+ /*
+ * OPTIONAL pointer to misc user provided context info
+ *
+ * user_fctx is for use as a pointer to your own struct to retain
+ * arbitrary context information between calls for your function.
+ */
+ void *user_fctx;
+
+ /*
+ * OPTIONAL pointer to struct containing arrays of attribute type input
+ * metainfo
+ *
+ * attinmeta is for use when returning tuples (i.e. composite data types)
+ * and is not needed when returning base (i.e. scalar) data types. It
+ * is ONLY needed if you intend to use BuildTupleFromCStrings() to create
+ * the return tuple.
+ */
AttInMetadata *attinmeta;
- /* memory context used to initialize structure */
+ /*
+ * memory context used to initialize structure
+ *
+ * fmctx is set by SRF_FIRSTCALL_INIT() for you, and used by
+ * SRF_RETURN_DONE() for cleanup. It is primarily for internal use
+ * by the API.
+ */
MemoryContext fmctx;
} FuncCallContext;
* Datum result;
* <user defined declarations>
*
- * if(SRF_IS_FIRSTPASS())
+ * if(SRF_IS_FIRSTCALL())
* {
* <user defined code>
* funcctx = SRF_FIRSTCALL_INIT();
* <user defined code>
* }
* <user defined code>
- * funcctx = SRF_PERCALL_SETUP(funcctx);
+ * funcctx = SRF_PERCALL_SETUP();
* <user defined code>
*
* if (funcctx->call_cntr < funcctx->max_calls)
/* from funcapi.c */
extern FuncCallContext *init_MultiFuncCall(PG_FUNCTION_ARGS);
+extern FuncCallContext *per_MultiFuncCall(PG_FUNCTION_ARGS);
extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx);
-#define SRF_IS_FIRSTPASS() (fcinfo->flinfo->fn_extra == NULL)
+#define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL)
#define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo)
-#define SRF_PERCALL_SETUP(_funcctx) \
- fcinfo->flinfo->fn_extra; \
- if(_funcctx->slot != NULL) \
- ExecClearTuple(_funcctx->slot)
+#define SRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo)
#define SRF_RETURN_NEXT(_funcctx, _result) \
do { \
ReturnSetInfo *rsi; \