in src/frequent_strings_sketch_pg_functions.c [212:277]
Datum frequent_strings_sketch_get_result(PG_FUNCTION_ARGS, bool no_false_positives) {
FuncCallContext* funcctx;
TupleDesc tupdesc;
const bytea* bytes_in;
void* sketchptr;
unsigned long long threshold;
if (SRF_IS_FIRSTCALL()) {
MemoryContext oldcontext;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
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"))
);
}
if (PG_ARGISNULL(0)) SRF_RETURN_DONE(funcctx);
bytes_in = PG_GETARG_BYTEA_P(0);
sketchptr = frequent_strings_sketch_deserialize(VARDATA(bytes_in), VARSIZE(bytes_in) - VARHDRSZ);
threshold = PG_NARGS() > 1 ? PG_GETARG_INT64(1) : 0;
funcctx->user_fctx = frequent_strings_sketch_get_frequent_items(sketchptr, no_false_positives, threshold);
funcctx->max_calls = ((struct frequent_strings_sketch_result*) funcctx->user_fctx)->num;
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
frequent_strings_sketch_delete(sketchptr);
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
if (funcctx->call_cntr < funcctx->max_calls) {
char **values;
HeapTuple tuple;
Datum result;
struct frequent_strings_sketch_result* frequent_strings = funcctx->user_fctx;
struct frequent_strings_sketch_result_row* row = &frequent_strings->rows[funcctx->call_cntr];
values = (char**) palloc(4 * sizeof(char*));
values[0] = row->str;
values[1] = (char*) palloc(21);
values[2] = (char*) palloc(21);
values[3] = (char*) palloc(21);
snprintf(values[1], 21, "%llu", row->estimate);
snprintf(values[2], 21, "%llu", row->lower_bound);
snprintf(values[3], 21, "%llu", row->upper_bound);
tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
result = HeapTupleGetDatum(tuple);
pfree(values[1]);
pfree(values[2]);
pfree(values[3]);
pfree(values);
SRF_RETURN_NEXT(funcctx, result);
} else {
SRF_RETURN_DONE(funcctx);
}
}