Hi, 
I've been working with SRF  and i want to return a setof record but i keep 
getting this error  ´cache lookup failed for type 18867840´ . My question is 
why and how to fix it. I need to do this work as quick as possible so I need 
all the help i can get, pleeeeeeease .....I am including postgres library and i 
am using version 8.1.
Where is the code:

#include "SRF_example.h"
#include "postgres.h"
#include "fmgr.h"
#include "funcapi.h"
#include "executor/spi.h"
#include "executor/executor.h"

PG_FUNCTION_INFO_V1(my_SRF_example);

Datum my_SRF_example(PG_FUNCTION_ARGS)
{
    FuncCallContext     *funcctx;
    int                  call_cntr;
    int                  max_calls;
    TupleDesc            tupdesc;
    AttInMetadata       *attinmeta;

     // stuff done only on the first call of the function 
     if (SRF_IS_FIRSTCALL())
     {
        MemoryContext   oldcontext;

        // create a function context for cross-call persistence 
        funcctx = SRF_FIRSTCALL_INIT();

        // switch to memory context appropriate for multiple function calls 
        oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

        // total number of tuples to be returned 
        funcctx->max_calls = PG_GETARG_UINT32(0);

        // Build a tuple descriptor for our result type 
        if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
            ereport(ERROR,
                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                     errmsg("function returning record called in context "
                            "that cannot accept type record")));


         // generate attribute metadata needed later to produce tuples from raw
         // C strings
         
        attinmeta = TupleDescGetAttInMetadata(tupdesc);
        funcctx->attinmeta = attinmeta;

        MemoryContextSwitchTo(oldcontext);
    }

    // stuff done on every call of the function 
    funcctx = SRF_PERCALL_SETUP();

    call_cntr = funcctx->call_cntr;
    max_calls = funcctx->max_calls;
   // max_calls -= 1;
    attinmeta = funcctx->attinmeta;
 elog(NOTICE,"%d < %d",call_cntr,max_calls);   
    if (call_cntr <max_calls)    // do when there is more left to send 
    {
        char       **values;
        HeapTuple    tuple;
        Datum        result;


         // Prepare a values array for building the returned tuple.
         // This should be an array of C strings which will
         // be processed later by the type input functions.
         
        values = (char **) palloc(3 * sizeof(char *));
        values[0] = (char *) palloc(16 * sizeof(char));
        values[1] = (char *) palloc(16 * sizeof(char));
        values[2] = (char *) palloc(16 * sizeof(char));

        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));
         
        // build a tuple 
        tuple = BuildTupleFromCStrings(attinmeta, values);

        // make the tuple into a datum 
        result = HeapTupleGetDatum(tuple);  
        // clean up (this is not really necessary) 
        pfree(values[0]);
        pfree(values[1]);
        pfree(values[2]);
        pfree(values);
        SRF_RETURN_NEXT(funcctx, result);
    }
    else    // do when there is no more left 
    {
        //elog(NOTICE,"%s",funcctx->user_fctx);
        SRF_RETURN_DONE(funcctx);
    }
}

Reply via email to