Обсуждение: Cstring vs. Datum values ( BuildTupleFromCStrings vs. BlessTupleDesc)
Cstring vs. Datum values ( BuildTupleFromCStrings vs. BlessTupleDesc)
От
Ivan Sergio Borgonovo
Дата:
Hi, I'm trying to write a couple of C function that will: - return a tsvector as a set of record. - turn a tsvector into a tsquery I'm looking at the example function to return set of records http://www.postgresql.org/docs/8.4/static/xfunc-c.html#AEN44970 and to this: "There are two ways you can build a composite data value (henceforth a "tuple"): you can build it from an array of Datum values, or from an array of C strings that can be passed to the input conversion functions of the tuple's column data types. In either case, you first need to obtain or construct a TupleDesc descriptor for the tuple structure. When working with Datums, you pass the TupleDesc to BlessTupleDesc, and then call heap_form_tuple for each row. When working with C strings, you pass the TupleDesc to TupleDescGetAttInMetadata, and then call BuildTupleFromCStrings for each row. In the case of a function returning a set of tuples, the setup steps can all be done once during the first call of the function." And I can't understand if I can avoid transforming everything into its text representation: snprintf(values[0], 16, "%d", 1 * PG_GETARG_INT32(1)); snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1)); snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1)); And if I can... how, why and when... because I didn't find any clear example in the source tree that gives me a clue about when I'd use one form or the other. Up to my understanding the way to go to use Datum is: /* create a template tupledesc specifying numbers of columns (eg.2) */ tupdesc = CreateTemplateTupleDesc(3, false); /* ??? bool hasoid */ /* configure the "fields" */ TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word", TEXTOID, -1, 0); /* ?????? Oid oidtypeid, // where can I get a list of OID int32 typmod, int attdim) */ /* ??? */ funcctx->tuple_desc = BlessTupleDesc(tupdesc); funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc); -- Ivan Sergio Borgonovo http://www.webthatworks.it
On Sat, Jan 23, 2010 at 12:56 PM, Ivan Sergio Borgonovo <mail@webthatworks.it> wrote: > And if I can... how, why and when... because I didn't find any clear > example in the source tree that gives me a clue about when I'd use > one form or the other. > There are a few contrib modules which make good examples, you could look at contrib/pageinspect/heapfuncs.c:heap_page_items() for example. -- greg
Re: Re: Cstring vs. Datum values ( BuildTupleFromCStrings vs. BlessTupleDesc)
От
Ivan Sergio Borgonovo
Дата:
On Sat, 23 Jan 2010 15:54:04 +0000 Greg Stark <gsstark@mit.edu> wrote: > On Sat, Jan 23, 2010 at 12:56 PM, Ivan Sergio Borgonovo > <mail@webthatworks.it> wrote: > > And if I can... how, why and when... because I didn't find any > > clear example in the source tree that gives me a clue about when > > I'd use one form or the other. > > > > There are a few contrib modules which make good examples, you could > look at contrib/pageinspect/heapfuncs.c:heap_page_items() for > example. That confused me further since it seems a 3rd technique to return set of records. One way is given for example in: ./src/backend/utils/adt/tsvector_op.c that uses BlessTupleDesc another that seems to be more frequent is given in the docs: http://www.postgresql.org/docs/8.4/static/xfunc-c.html#AEN44970 and finally the one you gave as an example I can't understand when each one should be used and I can't understand why so many ways to return a tuple... not to mention I've to "reverse engineer" many of the parameters of the function involved. Could someone give me a clue about when it is more suitable to use all the above techniques? thanks -- Ivan Sergio Borgonovo http://www.webthatworks.it
On Sat, Jan 23, 2010 at 5:53 PM, Ivan Sergio Borgonovo <mail@webthatworks.it> wrote: > That confused me further since it seems a 3rd technique to return > set of records. > The heapfuncs.c example uses get_call_result_type() to get the tupledesc and calls heap_form_tuple() to construct the return value, just like the docs describe. The extra code is because it's a set-returning-function which has its own set of tricky things to do. -- greg