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: