Tom Lane wrote:
> Definitely better.  I'd suggest also thinking about whether the
> same/similar macros can support functions that return a set of a
> scalar (non-tuple) datatype.  In my mind, the cleanest design would
> be some base macros that support functions-returning-set (of anything),
> and if you want to return a set of scalar then you just use these
> directly (handing a Datum to FUNC_RETURN_NEXT).  If you want to return
> a set of tuples then there are a couple extra steps that you need to
> do to build a tupdesc, build a tuple, and convert the tuple to Datum
> (which at the moment you do by putting it into a slot, but I think we
> ought to change that soon).  If it were really clean then the macros
> supporting these extra steps would also work without the SRF macros,
> so that you could use 'em in a function returning a single tuple.

I have a patch ready now which I think meets the design requirements 
above for the most part. The API is in two pieces: one which aids in 
creation of functions which return composite types; the other helps with 
SRFs. The comments in funcapi.h summarize the API:

/*-------------------------------------------------------------------------
  *     Support to ease writing Functions returning composite types
  *
  * External declarations:
  * TupleDesc RelationNameGetTupleDesc(char *relname) - Use to get a
  *     TupleDesc based on the function's return type relation.
  * TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) - Use to
  *     get a TupleDesc based on the function's type oid. This can be
  *     used to get a TupleDesc for a base (scalar), or composite type.
  * TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc) - Initialize a
  *     slot given a TupleDesc.
  * AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) - Get a
  *     pointer to AttInMetadata based on the function's TupleDesc.
  *     AttInMetadata can be used in conjunction with C strings to
  *     produce a properly formed tuple. Store the metadata here for
  *     use across calls to avoid redundant work.
  * HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta,
  *                                                char **values) -
  *    build a HeapTuple given user data in C string form. values is an
  *    array of C strings, one for each attribute of the return tuple.
  *
  * Macro declarations:
  * TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum
  *    given a tuple and a slot.
  */


/*-------------------------------------------------------------------------
  *             Support for Set Returning Functions (SRFs)
  *
  * The basic API for SRFs looks something like:
  *
  * Datum
  * my_Set_Returning_Function(PG_FUNCTION_ARGS)
  * {
  *     FuncCallContext    *funcctx;
  *     Datum           result;
  *     <user defined declarations>
  *
  *     if(SRF_IS_FIRSTPASS())
  *     {
  *             <user defined code>
  *             <obtain slot>
  *             funcctx = SRF_FIRSTCALL_INIT(slot);
  *             <user defined code>
  *     }
  *     <user defined code>
  *     funcctx = SRF_PERCALL_SETUP(funcctx);
  *     <user defined code>
  *
  *     if (funcctx->call_cntr < funcctx->max_calls)
  *     {
  *             <user defined code>
  *             <obtain result Datum>
  *             SRF_RETURN_NEXT(funcctx, result);
  *     }
  *     else
  *     {
  *             SRF_RETURN_DONE(funcctx);
  *     }
  * }
  *
  */

If interested in more details, the patch will be sent shortly to 
PATCHES. Included in the patch is a reference implementation of the API, 
show_all_vars() (showguc_all() in guc.c). This returns the same 
information as SHOW ALL, but as an SRF, allowing, for example, the 
following:

test=# select * from show_all_vars() where varname like 'cpu%';
        varname        | varval
----------------------+--------
  cpu_index_tuple_cost | 0.001
  cpu_operator_cost    | 0.0025
  cpu_tuple_cost       | 0.01
(3 rows)

Comments/thoughts?

Thanks,

Joe


---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org

Reply via email to