How to write a c-function to return multiple bytea rows - Mailing list pgsql-hackers

From Billow Gao
Subject How to write a c-function to return multiple bytea rows
Date
Msg-id 677a32120711281743t336b82d5i722001ae9e3e6bda@mail.gmail.com
Whole thread Raw
Responses Re: How to write a c-function to return multiple bytea rows
Re: How to write a c-function to return multiple bytea rows
List pgsql-hackers
I can return multiple strings w/o problem.<br /><br />But if I tried to return multiple bytea rows. It only return 10
rowswith empty data.<br />Please see the code below.<br /><br />Also, when I compile it, I had warning:<br />test.c
:121:warning: assignment makes pointer from integer without a cast <br />The line is: <br />tuple = heap_form_tuple(
tupdesc,&dtvalues, &isNull );<br /><br />Strange.. compiled in a linux box. <br /><br /><br />If I use: tuple =
BuildTupleFromCStrings(attinmeta,values); <br />it can work but it's string and I want to use bytea.<br /><br />Also,
doI need to free char** values or let postgresql do the job?<br /><br />Thanks<br /><br />Billow<br /><br /><br
/>============================================================================================<br
/>/************************************************************<br/>-- select * from test(1,2,'asdfdsaf') as (id
bytea);<br/>CREATE OR REPLACE FUNCTION test(int,int,text)<br />    RETURNS setof record<br />    AS
'gr_indexsearch.so','test' <br />    LANGUAGE 'C' IMMUTABLE CALLED ON NULL INPUT;<br
/>*************************************************************/<br/><br />// PostgreSQL includes<br />#include
"postgres.h"<br/>#include "fmgr.h" <br /><br />// Tuple building functions and macros<br />#include "funcapi.h"<br
/><br/>#include "utils/builtins.h"<br /><br /><br />#include <string.h><br /><br />#define _textout(str)
DatumGetPointer(DirectFunctionCall1(textout,PointerGetDatum(str))) <br /><br />#ifndef SET_VARSIZE<br />#define
SET_VARSIZE(v,l)(VARATT_SIZEP(v) = (l))<br />#endif<br /><br />/* SortMem got renamed in PostgreSQL 8.0 */<br />#ifndef
SortMem<br/> #define SortMem 16 * 1024<br />#endif<br /><br />#ifdef PG_MODULE_MAGIC <br />PG_MODULE_MAGIC;<br
/>#endif<br/><br /><br />// forward declaration to keep compiler happy<br />Datum c_complex_add( PG_FUNCTION_ARGS );<br
/><br/>PG_FUNCTION_INFO_V1( test );<br />Datum test( PG_FUNCTION_ARGS )<br />{<br />   // things we need to deal with
constructingour composite type <br />   TupleDesc         tupdesc;<br />   HeapTuple         tuple;<br />  
Tuplestorestate  *tupstore = NULL;<br />   ReturnSetInfo     *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;<br />  
<br/>   MemoryContext per_query_ctx; <br />   MemoryContext oldcontext;<br />   <br />   // Get arguments.  If we
declareour function as STRICT, then<br />   // this check is superfluous.<br />   if( PG_ARGISNULL(0) ||<br />      
PG_ARGISNULL(1)|| <br />       PG_ARGISNULL(2)) <br />   {<br />      PG_RETURN_NULL();<br />   }<br /><br />   // Get
arguments:TimeStart and TimeEnd<br />   int32 TimeStart = PG_GETARG_INT32(0);<br />   int32 TimeEnd   =
PG_GETARG_INT32(1);<br/><br />   // Get Search query<br />   char *query = _textout(PG_GETARG_TEXT_P(2));   <br />  
<br/>   <br />    /* check to see if caller supports us returning a tuplestore */<br />    if (!rsinfo ||
!(rsinfo->allowedModes& SFRM_Materialize))<br />        ereport(ERROR,<br />               
(errcode(ERRCODE_SYNTAX_ERROR),<br />                 errmsg("materialize mode required, but it is not " \<br />       
               "allowed in this context")));<br /><br />    /* let the caller know we're sending back a tuplestore */
<br/>    rsinfo->returnMode = SFRM_Materialize;<br />    <br />    per_query_ctx = fcinfo->flinfo->fn_mcxt;<br
/>   oldcontext = MemoryContextSwitchTo(per_query_ctx);<br /><br />    /* get the requested return tuple description */
<br/>    tupdesc = rsinfo->expectedDesc;<br />    <br />    /* OK, use it */<br />    AttInMetadata *attinmeta =
TupleDescGetAttInMetadata(tupdesc);<br/>    <br />    /* initialize our tuplestore */<br />    tupstore =
tuplestore_begin_heap(true,false, SortMem); <br />    <br />    char strtest[] = "This is a test!";<br />    int
strleng= strlen(strtest);<br />    <br />    int rows = 10;<br />    //char** values = (char **) palloc(rows *
sizeof(char*));<br />    <br />    bytea** values = (bytea **) palloc(rows * sizeof(bytea *)); <br />    Datum
dtvalues;<br/>    bool isNull;<br />    <br />    int i;<br />    for(i=0; i<rows; i++)<br />    {<br />       
//values[i]= palloc(strleng * sizeof(char));<br />        //strncpy(values[i], strtest, strleng);                  <br
/>       /* construct the tuple */<br />        //tuple = BuildTupleFromCStrings(attinmeta, values);<br />        /*
nowstore it */<br />        //tuplestore_puttuple(tupstore, tuple);<br />        <br />            values[i] = (bytea
*)palloc( strleng + VARHDRSZ ); <br />            SET_VARSIZE(values[i], strleng + VARHDRSZ);<br />            memcpy(
VARDATA(values[i]),strtest, strleng );<br />            dtvalues = PointerGetDatum(values[i]);<br /><br />           
tuple= heap_form_tuple( tupdesc, &dtvalues, &isNull ); <br /><br />            /* now store it */<br />       
   oldcontext = MemoryContextSwitchTo(per_query_ctx);<br />            tuplestore_puttuple(tupstore, tuple);<br />   
       MemoryContextSwitchTo(oldcontext);<br /><br />            heap_freetuple(tuple); <br />    }<br />    <br />   
tuplestore_donestoring(tupstore);<br/>    <br />   /* now go build it */<br />    rsinfo->setResult = tupstore;<br
/><br/>    /*<br />     * SFRM_Materialize mode expects us to return a NULL Datum. The actual <br />     * tuples are
inour tuplestore and passed back through rsinfo->setResult.<br />     * rsinfo->setDesc is set to the tuple
descriptionthat we actually used<br />     * to build our tuples with, so the caller can verify we did what it was <br
/>    * expecting.<br />     */<br />    rsinfo->setDesc = tupdesc;<br />    MemoryContextSwitchTo(oldcontext);<br
/><br/>    return (Datum) 0;<br />}<br /> 

pgsql-hackers by date:

Previous
From: Alvaro Herrera
Date:
Subject: Re: quotas once again
Next
From: "Jonah H. Harris"
Date:
Subject: Re: quotas once again