Re: revised sample SRF C function; proposed SRF API - Mailing list pgsql-hackers

From Joe Conway
Subject Re: revised sample SRF C function; proposed SRF API
Date
Msg-id 3D013C2F.2060703@joeconway.com
Whole thread Raw
In response to revised sample SRF C function; proposed SRF API  (Joe Conway <mail@joeconway.com>)
List pgsql-hackers
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
returningcomposite 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
fora base (scalar), or composite type. * TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc) - Initialize a *     slot
givena TupleDesc. * AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) - Get a *     pointer to AttInMetadata
basedon the function's TupleDesc. *     AttInMetadata can be used in conjunction with C strings to *     produce a
properlyformed tuple. Store the metadata here for *     use across calls to avoid redundant work. * HeapTuple
BuildTupleFromCStrings(AttInMetadata*attinmeta, *                                                char **values) - *
builda HeapTuple given user data in C string form. values is an *    array of C strings, one for each attribute of the
returntuple. * * Macro declarations: * TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum *    given a
tupleand 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; *
<userdefined 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



pgsql-hackers by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: NO CREATE TABLE
Next
From: Rachit Siamwalla
Date:
Subject: Question whether this is a known problem in 7.1.2