srfpoc.c
text/x-c
#include "postgres.h"
#include <stdio.h> /* snprintf */
#include <stdlib.h> /* malloc, free */
#include <string.h> /* strncpy, strlen */
#include <sys/types.h> /* for uint32 and size_t*/
#include "catalog/pg_type.h"
#include "utils/builtins.h" /* text_to_cstring */
#include "funcapi.h"
#include "fmgr.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(srfpoc);
Datum srfpoc(PG_FUNCTION_ARGS) {
FuncCallContext *funcctx;
TupleDesc tupdesc;
text *t;
int max_calls,
call_cntr;
t = (text *)PG_GETARG_TEXT_PP(0);
if (SRF_IS_FIRSTCALL()) {
MemoryContext oldcontext;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
funcctx->max_calls = (uint32)PG_GETARG_INT32(1);
tupdesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "t", TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "count", INT4OID, -1, 0);
funcctx->user_fctx = BlessTupleDesc(tupdesc);
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
max_calls = funcctx->max_calls;
call_cntr = funcctx->call_cntr;
tupdesc = funcctx->user_fctx;
if(call_cntr < max_calls && t != NULL) {
bool nulls[2];
Datum values[2];
HeapTuple tuple;
text *cpyt;
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(call_cntr);
nulls[0] = false;
nulls[1] = false;
tuple = heap_form_tuple(tupdesc, values, nulls);
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
} else {
SRF_RETURN_DONE(funcctx);
}
}