srfmatpoc.c
text/x-c
#include "postgres.h"
#include "catalog/pg_type.h"
#include "fmgr.h"
#include "funcapi.h"
#include "executor/spi.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(srfmatpoc);
Datum srfmatpoc(PG_FUNCTION_ARGS) {
ReturnSetInfo *rsinfo;
Tuplestorestate *tupstore;
TupleDesc tupdesc;
MemoryContext per_query_ctx;
MemoryContext oldcontext;
text *t,
*cpyt;
int ret,
c,
i;
rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
if ((ret = SPI_connect()) < 0)
elog(ERROR, "srfmatpoc: SPI_connect returned %d", ret);
tupdesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "t", TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "count", INT4OID, -1, 0);
oldcontext = MemoryContextSwitchTo(per_query_ctx);
tupdesc = CreateTupleDescCopy(tupdesc);
tupstore =
tuplestore_begin_heap(rsinfo->allowedModes & SFRM_Materialize_Random,
false, work_mem);
MemoryContextSwitchTo(oldcontext);
t = (text *)PG_GETARG_TEXT_PP(0);
c = (uint32)PG_GETARG_INT32(1);
for(i=0; i<c; ++i) {
HeapTuple tuple;
Datum values[2];
bool nulls[2];
cpyt = (text *)palloc(VARHDRSZ + VARSIZE_ANY_EXHDR(t));
SET_VARSIZE(cpyt, VARHDRSZ + VARSIZE_ANY_EXHDR(t));
memcpy((void *)VARDATA(cpyt), (void *)VARDATA(t), VARSIZE_ANY_EXHDR(t));
values[0] = PointerGetDatum(cpyt);
values[1] = Int32GetDatum(i);
nulls[0] = false;
nulls[1] = false;
tuple = heap_form_tuple(tupdesc, values, nulls);
tuplestore_puttuple(tupstore, tuple);
heap_freetuple(tuple);
}
rsinfo->returnMode = SFRM_Materialize;
rsinfo->setResult = tupstore;
rsinfo->setDesc = tupdesc;
SPI_finish();
return (Datum) 0;
}