Re: Return setof values from C-function

From: Yuriy Rusinov <yrusinov(at)gmail(dot)com>
To: Merlin Moncure <mmoncure(at)gmail(dot)com>
Cc: POSTGRES <pgsql-general(at)postgresql(dot)org>
Subject: Re: Return setof values from C-function
Date: 2013-12-11 08:46:24
Message-ID: CAA5U4sxjdptsQd64LuhhFMTq2vsmkz768ZFkuxDgfPw-iekY5w@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

I have received an error
The connection to the server was lost. Attempting reset: Failed

This problem was solved using by C-strings instead of Datum

such as

FuncCallContext *funcctx;
int call_cntr;
int max_calls;
AttInMetadata *attinmeta;
unsigned long il;
TupleDesc tupdescRes;
gsl_histogram * gHist;
if (SRF_IS_FIRSTCALL())
{
size_t nr_rand = strlen ( VARDATA (PG_GETARG_VARCHAR_P(0)));
char * sql = (char *) palloc (nr_rand+1);
// strncpy (sql, (char *)PG_GETARG_VARCHAR_P(0), nr_rand);
snprintf (sql, nr_rand+1, "%s", VARDATA (PG_GETARG_VARCHAR_P (0)));
float8 xmin = PG_GETARG_FLOAT8 (1);
float8 xmax = PG_GETARG_FLOAT8 (2);
unsigned int num = PG_GETARG_UINT32(3);

//float8 * result = (float8 *) (palloc (sizeof(float8)));

//*result= 5.0;

gHist = gsl_histogram_alloc (num);
elog (INFO, "query = %s\n", sql);
gsl_histogram_set_ranges_uniform (gHist, (double)xmin,
(double)xmax);
// Datum d = PointerGetDatum (gHist);
SPI_connect ();
int retVal = SPI_execute (sql, true, 0);
if (retVal != SPI_OK_SELECT)
{
elog (ERROR, "Cannot load values");
SPI_finish ();
PG_RETURN_NULL();
}
elog (INFO, "%d\n", retVal);
unsigned long int nproc = SPI_processed;
elog (INFO, "number of points is %lu, number of bins is %u", nproc,
num);
// SPI_finish ();
// pfree (sql);
// PG_RETURN_NULL();
int i=0;

TupleDesc tupdesc = SPI_tuptable->tupdesc;
for (; i< nproc; i++)
{
HeapTuple tuple = SPI_tuptable->vals[i];
int ncolbuf = 1;
char * x_str = SPI_getvalue (tuple, tupdesc, ncolbuf);
if (!x_str)
continue;
double x= atof (x_str);
//elog (INFO, "value=%f", x);
int res = gsl_histogram_increment (gHist, x);
if (res != 0)
{
elog (NOTICE, "Range error, value is %lf, min value is %lf,
max value %lf", x, gsl_histogram_min(gHist), gsl_histogram_max (gHist) );
continue;
}
}
SPI_finish ();
pfree (sql);
elog (INFO, "Reading was completed\n");
MemoryContext oldcontext;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
funcctx->max_calls = num;
Oid * oids = (Oid *)palloc (2*sizeof (Oid));
oids[0] = INT8OID;
oids[1] = FLOAT8OID;
if (get_call_result_type(fcinfo, oids, &tupdescRes) !=
TYPEFUNC_COMPOSITE)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("function returning record called in context "
"that cannot accept type record")));
attinmeta = TupleDescGetAttInMetadata(tupdescRes);
funcctx->attinmeta = attinmeta;
MemoryContextSwitchTo(oldcontext);
//funcctx->tuple_desc = BlessTupleDesc( tupdescRes );
pfree (oids);
elog (INFO, "1st row");
}
funcctx = SRF_PERCALL_SETUP();
call_cntr = funcctx->call_cntr;
max_calls = funcctx->max_calls;
elog (INFO, "number of rows = %d, number of columns are %d", max_calls,
tupdescRes->natts );
attinmeta = funcctx->attinmeta;
HeapTuple tuple;
if (call_cntr < max_calls)
{
elog (INFO, "Rows");
il = call_cntr;
//Datum * hvalues = (Datum *)palloc (2*sizeof(Datum));

char ** svals = (char **) palloc (2*sizeof (char*));
svals [0] = (char *) palloc(5 * sizeof(char));
svals [1] = (char *) palloc(20 * sizeof(char));
double val = gsl_histogram_get (gHist, il);
snprintf (svals[0], 5, "%lu", il);
snprintf (svals[1], 20, "%lf", val);
//hvalues[0] = UInt32GetDatum (il);
//hvalues[1] = Float8GetDatum (val);
bool * nulls = palloc( 2 * sizeof( bool ) );

elog (INFO, "%lu", il);
tuple = BuildTupleFromCStrings (attinmeta,
svals);//heap_form_tuple( tupdescRes, hvalues, nulls);
elog (INFO, "%lu", il);
Datum result = HeapTupleGetDatum(tuple);
pfree (nulls);
pfree (svals[1]);
pfree (svals[0]);
pfree (svals);
//pfree (hvalues);
SRF_RETURN_NEXT(funcctx, result);//HeapTupleGetDatum( tuple ) );
}
else
{
SRF_RETURN_DONE(funcctx);
}

Thanks a lot.

Yuriy Rusinov

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Herouth Maoz 2013-12-11 09:49:00 Re: Question about optimizing access to a table.
Previous Message Jayadevan M 2013-12-11 08:08:04 vacuuming - doubt