本文整理汇总了C++中SRF_PERCALL_SETUP函数的典型用法代码示例。如果您正苦于以下问题:C++ SRF_PERCALL_SETUP函数的具体用法?C++ SRF_PERCALL_SETUP怎么用?C++ SRF_PERCALL_SETUP使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了SRF_PERCALL_SETUP函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ts_parse_byid
Datum
ts_parse_byid(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL())
{
text *txt = PG_GETARG_TEXT_P(1);
funcctx = SRF_FIRSTCALL_INIT();
prs_setup_firstcall(funcctx, PG_GETARG_OID(0), txt);
PG_FREE_IF_COPY(txt, 1);
}
funcctx = SRF_PERCALL_SETUP();
if ((result = prs_process_call(funcctx)) != (Datum) 0)
SRF_RETURN_NEXT(funcctx, result);
SRF_RETURN_DONE(funcctx);
}
示例2: pg_visibility_rel
/*
* Visibility map information for every block in a relation, plus the page
* level information for each block.
*/
Datum
pg_visibility_rel(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
vbits *info;
if (SRF_IS_FIRSTCALL())
{
Oid relid = PG_GETARG_OID(0);
MemoryContext oldcontext;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
funcctx->tuple_desc = pg_visibility_tupdesc(true, true);
funcctx->user_fctx = collect_visibility_data(relid, true);
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
info = (vbits *) funcctx->user_fctx;
if (info->next < info->count)
{
Datum values[4];
bool nulls[4];
HeapTuple tuple;
MemSet(nulls, 0, sizeof(nulls));
values[0] = Int64GetDatum(info->next);
values[1] = BoolGetDatum((info->bits[info->next] & (1 << 0)) != 0);
values[2] = BoolGetDatum((info->bits[info->next] & (1 << 1)) != 0);
values[3] = BoolGetDatum((info->bits[info->next] & (1 << 2)) != 0);
info->next++;
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
}
SRF_RETURN_DONE(funcctx);
}
示例3: regexp_split_to_table
/*
* regexp_split_to_table()
* Split the string at matches of the pattern, returning the
* split-out substrings as a table.
*/
Datum
regexp_split_to_table(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
regexp_matches_ctx *splitctx;
if (SRF_IS_FIRSTCALL())
{
text *pattern = PG_GETARG_TEXT_PP(1);
text *flags = PG_GETARG_TEXT_PP_IF_EXISTS(2);
MemoryContext oldcontext;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/* be sure to copy the input string into the multi-call ctx */
splitctx = setup_regexp_matches(PG_GETARG_TEXT_P_COPY(0), pattern,
flags, true, false, true);
MemoryContextSwitchTo(oldcontext);
funcctx->user_fctx = (void *) splitctx;
}
funcctx = SRF_PERCALL_SETUP();
splitctx = (regexp_matches_ctx *) funcctx->user_fctx;
if (splitctx->next_match <= splitctx->nmatches)
{
Datum result = build_regexp_split_result(splitctx);
splitctx->next_match++;
SRF_RETURN_NEXT(funcctx, result);
}
/* release space in multi-call ctx to avoid intraquery memory leak */
cleanup_regexp_matches(splitctx);
SRF_RETURN_DONE(funcctx);
}
示例4: pg_stat_get_backend_idset
Datum
pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
int *fctx;
int32 result;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
2 * sizeof(int));
funcctx->user_fctx = fctx;
fctx[0] = 0;
fctx[1] = pgstat_fetch_stat_numbackends();
}
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
fctx = funcctx->user_fctx;
fctx[0] += 1;
result = fctx[0];
if (result <= fctx[1])
{
/* do when there is more left to send */
SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
}
else
{
/* do when there is no more left */
SRF_RETURN_DONE(funcctx);
}
}
示例5: ts_token_type_byname
Datum
ts_token_type_byname(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL())
{
text *prsname = PG_GETARG_TEXT_P(0);
Oid prsId;
funcctx = SRF_FIRSTCALL_INIT();
prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
tt_setup_firstcall(funcctx, prsId);
}
funcctx = SRF_PERCALL_SETUP();
if ((result = tt_process_call(funcctx)) != (Datum) 0)
SRF_RETURN_NEXT(funcctx, result);
SRF_RETURN_DONE(funcctx);
}
示例6: token_type_byname
Datum
token_type_byname(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
SET_FUNCOID();
if (SRF_IS_FIRSTCALL())
{
text *name = PG_GETARG_TEXT_P(0);
funcctx = SRF_FIRSTCALL_INIT();
setup_firstcall(fcinfo, funcctx, name2id_prs(name));
PG_FREE_IF_COPY(name, 0);
}
funcctx = SRF_PERCALL_SETUP();
if ((result = process_call(funcctx)) != (Datum) 0)
SRF_RETURN_NEXT(funcctx, result);
SRF_RETURN_DONE(funcctx);
}
示例7: testfunc4
Datum
testfunc4(PG_FUNCTION_ARGS)
{
int64 i = PG_GETARG_INT64(0);
FuncCallContext *funcctx;
MemoryContext oldcontext;
if (SRF_IS_FIRSTCALL())
{
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
funcctx->max_calls = 3;
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
if (funcctx->call_cntr < funcctx->max_calls)
{
SRF_RETURN_NEXT(funcctx, Int64GetDatum(i + funcctx->call_cntr));
}
else
{
SRF_RETURN_DONE(funcctx);
}
}
示例8: parse_current
Datum
parse_current(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
SET_FUNCOID();
if (SRF_IS_FIRSTCALL())
{
text *txt = PG_GETARG_TEXT_P(0);
funcctx = SRF_FIRSTCALL_INIT();
if (current_parser_id == InvalidOid)
current_parser_id = name2id_prs(char2text("default"));
prs_setup_firstcall(fcinfo, funcctx, current_parser_id, txt);
PG_FREE_IF_COPY(txt, 0);
}
funcctx = SRF_PERCALL_SETUP();
if ((result = prs_process_call(funcctx)) != (Datum) 0)
SRF_RETURN_NEXT(funcctx, result);
SRF_RETURN_DONE(funcctx);
}
示例9: ts_stat1
Datum
ts_stat1(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
if (SRF_IS_FIRSTCALL())
{
TSVectorStat *stat;
text *txt = PG_GETARG_TEXT_P(0);
funcctx = SRF_FIRSTCALL_INIT();
SPI_connect();
stat = ts_stat_sql(funcctx->multi_call_memory_ctx, txt, NULL);
PG_FREE_IF_COPY(txt, 0);
ts_setup_firstcall(fcinfo, funcctx, stat);
SPI_finish();
}
funcctx = SRF_PERCALL_SETUP();
if ((result = ts_process_call(funcctx)) != (Datum) 0)
SRF_RETURN_NEXT(funcctx, result);
SRF_RETURN_DONE(funcctx);
}
示例10: MarketFeedFrame1
//.........这里部分代码省略.........
if (ret != SPI_OK_INSERT) {
dump_mff1_inputs(price_quote_p, status_submitted_p,
symbol_p, trade_qty, type_limit_buy_p,
type_limit_sell_p, type_stop_loss_p);
FAIL_FRAME_SET(&funcctx->max_calls, MFF1_statements[4].sql);
}
++rows_sent;
#ifdef DEBUG
elog(NOTICE, "%d row(s) sent", rows_sent);
#endif /* DEBUG */
if (count > 0) {
strcat(values[i_symbol], ",");
strcat(values[i_trade_id], ",");
strcat(values[i_price_quote], ",");
strcat(values[i_trade_type], ",");
strcat(values[i_trade_qty], ",");
}
strcat(values[i_symbol], symbol);
strcat(values[i_trade_id], trade_id);
strcat(values[i_price_quote], req_price_quote);
strcat(values[i_trade_type], req_trade_type);
strcat(values[i_trade_qty], req_trade_qty);
++count;
}
/* FIXME: BEGIN/COMMIT statements not supported with SPI. */
/*
ret = SPI_exec("COMMIT;", 0);
if (ret == SPI_OK_SELECT) {
} else {
elog(NOTICE, "ERROR: COMMIT not ok = %d", ret);
}
*/
send_len += rows_sent;
p_s = att_addlength_pointer(p_s, typlen_s, p_s);
p_s = (char *) att_align_nominal(p_s, typalign_s);
}
strcat(values[i_symbol], "}");
strcat(values[i_trade_id], "}");
strcat(values[i_price_quote], "}");
strcat(values[i_trade_qty], "}");
strcat(values[i_trade_type], "}");
sprintf(values[i_num_updated], "%d", num_updated);
sprintf(values[i_send_len], "%d", send_len);
funcctx->max_calls = 1;
/* 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;
attinmeta = funcctx->attinmeta;
if (call_cntr < max_calls) {
/* do when there is more left to send */
HeapTuple tuple;
Datum result;
#ifdef DEBUG
for (i = 0; i < 7; i++) {
elog(NOTICE, "MFF1 OUT: %d %s", i, values[i]);
}
#endif /* DEBUG */
/* Build a tuple. */
tuple = BuildTupleFromCStrings(attinmeta, values);
/* Make the tuple into a datum. */
result = HeapTupleGetDatum(tuple);
SRF_RETURN_NEXT(funcctx, result);
} else {
/* Do when there is no more left. */
SPI_finish();
SRF_RETURN_DONE(funcctx);
}
}
示例11: compute_sql_asm_tsp
//.........这里部分代码省略.........
}
DBG("Total %i tuples", totalTuples);
DBG("Calling tsp functions total tuples <%i> initial path count <%i>", totalTuples,*pathCount);
ret=processATSPData(edges,totalTuples,sourceVertexId,reverseCost, path, pathCount,errMesg);
DBG("SIZE %i elements to process",*pathCount);
if (!ret ) {
elog(ERROR, "Error computing path: %s", errMesg);
}
return finish(SPIcode, ret);
}
PG_FUNCTION_INFO_V1(sql_asm_tsp);
Datum sql_asm_tsp(PG_FUNCTION_ARGS) {
FuncCallContext *funcctx;
int callCntr;
int maxCalls;
TupleDesc tupleDesc;
tspPathElementType *path;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL()) {
MemoryContext oldcontext;
int pathCount = 0;
int ret;
/* 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);
ret = compute_sql_asm_tsp(text2char(PG_GETARG_TEXT_P(0)),
PG_GETARG_INT32(1), PG_GETARG_BOOL(2), &path, &pathCount);
#ifdef DEBUG
if (ret >= 0) {
int i;
for (i = 0; i < pathCount; i++) {
DBG("Step # %i vertexId %i cost %.4f", i, path[i].vertexId,path[i].cost);
}
}
#endif
/* total number of tuples to be returned */
funcctx->max_calls = pathCount;
funcctx->user_fctx = path;
DBG("Path count %i", pathCount);
funcctx->tuple_desc =
BlessTupleDesc(RelationNameGetTupleDesc("pgr_costResult"));
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
callCntr = funcctx->call_cntr;
maxCalls = funcctx->max_calls;
tupleDesc = funcctx->tuple_desc;
path = (tspPathElementType*) funcctx->user_fctx;
if (callCntr < maxCalls) { /* do when there is more left to send */
HeapTuple tuple;
Datum result;
Datum *values;
char* nulls;
values = palloc(4 * sizeof(Datum));
nulls = palloc(4 * sizeof(char));
values[0] = Int32GetDatum(callCntr);
nulls[0] = ' ';
values[1] = Int32GetDatum(path[callCntr].vertexId);
nulls[1] = ' ';
values[2] = Float8GetDatum(0); // edge id not supplied by this method
nulls[2] = ' ';
values[3] = Float8GetDatum(path[callCntr].cost);
nulls[3] = ' ';
tuple = heap_formtuple(tupleDesc, values, nulls);
/* make the tuple into a datum */
result = HeapTupleGetDatum(tuple);
/* clean up (this is not really necessary) */
pfree(values);
pfree(nulls);
SRF_RETURN_NEXT(funcctx, result);
} else { /* do when there is no more left */
SRF_RETURN_DONE(funcctx);
}
}
示例12: pg_get_keywords
/* Function to return the list of grammar keywords */
Datum
pg_get_keywords(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
if (SRF_IS_FIRSTCALL())
{
MemoryContext oldcontext;
TupleDesc tupdesc;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
tupdesc = CreateTemplateTupleDesc(3, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode",
CHAROID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "catdesc",
TEXTOID, -1, 0);
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
if (funcctx->call_cntr < NumScanKeywords)
{
char *values[3];
HeapTuple tuple;
/* cast-away-const is ugly but alternatives aren't much better */
values[0] = (char *) ScanKeywords[funcctx->call_cntr].name;
switch (ScanKeywords[funcctx->call_cntr].category)
{
case UNRESERVED_KEYWORD:
values[1] = "U";
values[2] = _("unreserved");
break;
case COL_NAME_KEYWORD:
values[1] = "C";
values[2] = _("unreserved (cannot be function or type name)");
break;
case TYPE_FUNC_NAME_KEYWORD:
values[1] = "T";
values[2] = _("reserved (can be function or type name)");
break;
case RESERVED_KEYWORD:
values[1] = "R";
values[2] = _("reserved");
break;
default: /* shouldn't be possible */
values[1] = NULL;
values[2] = NULL;
break;
}
tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
}
SRF_RETURN_DONE(funcctx);
}
示例13: pg_tablespace_databases
Datum
pg_tablespace_databases(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
struct dirent *de;
ts_db_fctx *fctx;
if (SRF_IS_FIRSTCALL())
{
MemoryContext oldcontext;
Oid tablespaceOid = PG_GETARG_OID(0);
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
fctx = palloc(sizeof(ts_db_fctx));
/*
* size = tablespace dirname length + dir sep char + oid + terminator
*/
fctx->location = (char *) palloc(9 + 1 + OIDCHARS + 1 +
strlen(TABLESPACE_VERSION_DIRECTORY) + 1);
if (tablespaceOid == GLOBALTABLESPACE_OID)
{
fctx->dirdesc = NULL;
ereport(WARNING,
(errmsg("global tablespace never has databases")));
}
else
{
if (tablespaceOid == DEFAULTTABLESPACE_OID)
sprintf(fctx->location, "base");
else
sprintf(fctx->location, "pg_tblspc/%u/%s", tablespaceOid,
TABLESPACE_VERSION_DIRECTORY);
fctx->dirdesc = AllocateDir(fctx->location);
if (!fctx->dirdesc)
{
/* the only expected error is ENOENT */
if (errno != ENOENT)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not open directory \"%s\": %m",
fctx->location)));
ereport(WARNING,
(errmsg("%u is not a tablespace OID", tablespaceOid)));
}
}
funcctx->user_fctx = fctx;
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
fctx = (ts_db_fctx *) funcctx->user_fctx;
if (!fctx->dirdesc) /* not a tablespace */
SRF_RETURN_DONE(funcctx);
while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
{
char *subdir;
DIR *dirdesc;
Oid datOid = atooid(de->d_name);
/* this test skips . and .., but is awfully weak */
if (!datOid)
continue;
/* if database subdir is empty, don't report tablespace as used */
/* size = path length + dir sep char + file name + terminator */
subdir = palloc(strlen(fctx->location) + 1 + strlen(de->d_name) + 1);
sprintf(subdir, "%s/%s", fctx->location, de->d_name);
dirdesc = AllocateDir(subdir);
while ((de = ReadDir(dirdesc, subdir)) != NULL)
{
if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
break;
}
FreeDir(dirdesc);
pfree(subdir);
if (!de)
continue; /* indeed, nothing in it */
SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(datOid));
}
FreeDir(fctx->dirdesc);
SRF_RETURN_DONE(funcctx);
}
示例14: heap_page_items
Datum
heap_page_items(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
heap_page_items_state *inter_call_data = NULL;
FuncCallContext *fctx;
int raw_page_size;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use raw page functions"))));
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
if (SRF_IS_FIRSTCALL())
{
TupleDesc tupdesc;
MemoryContext mctx;
if (raw_page_size < SizeOfPageHeaderData)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input page too small (%d bytes)", raw_page_size)));
fctx = SRF_FIRSTCALL_INIT();
mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);
inter_call_data = palloc(sizeof(heap_page_items_state));
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
inter_call_data->tupd = tupdesc;
inter_call_data->offset = FirstOffsetNumber;
inter_call_data->page = VARDATA(raw_page);
fctx->max_calls = PageGetMaxOffsetNumber(inter_call_data->page);
fctx->user_fctx = inter_call_data;
MemoryContextSwitchTo(mctx);
}
fctx = SRF_PERCALL_SETUP();
inter_call_data = fctx->user_fctx;
if (fctx->call_cntr < fctx->max_calls)
{
Page page = inter_call_data->page;
HeapTuple resultTuple;
Datum result;
ItemId id;
Datum values[13];
bool nulls[13];
uint16 lp_offset;
uint16 lp_flags;
uint16 lp_len;
memset(nulls, 0, sizeof(nulls));
/* Extract information from the line pointer */
id = PageGetItemId(page, inter_call_data->offset);
lp_offset = ItemIdGetOffset(id);
lp_flags = ItemIdGetFlags(id);
lp_len = ItemIdGetLength(id);
values[0] = UInt16GetDatum(inter_call_data->offset);
values[1] = UInt16GetDatum(lp_offset);
values[2] = UInt16GetDatum(lp_flags);
values[3] = UInt16GetDatum(lp_len);
/*
* We do just enough validity checking to make sure we don't reference
* data outside the page passed to us. The page could be corrupt in
* many other ways, but at least we won't crash.
*/
if (ItemIdHasStorage(id) &&
lp_len >= sizeof(HeapTupleHeader) &&
lp_offset == MAXALIGN(lp_offset) &&
lp_offset + lp_len <= raw_page_size)
{
HeapTupleHeader tuphdr;
int bits_len;
/* Extract information from the tuple header */
tuphdr = (HeapTupleHeader) PageGetItem(page, id);
values[4] = UInt32GetDatum(HeapTupleHeaderGetXmin(tuphdr));
values[5] = UInt32GetDatum(HeapTupleHeaderGetRawXmax(tuphdr));
values[6] = UInt32GetDatum(HeapTupleHeaderGetRawCommandId(tuphdr)); /* shared with xvac */
values[7] = PointerGetDatum(&tuphdr->t_ctid);
values[8] = UInt32GetDatum(tuphdr->t_infomask2);
values[9] = UInt32GetDatum(tuphdr->t_infomask);
values[10] = UInt8GetDatum(tuphdr->t_hoff);
//.........这里部分代码省略.........
示例15: heap_page_items
datum_t
heap_page_items(PG_FUNC_ARGS)
{
bytea *raw_page = ARG_BYTEA_P(0);
heap_page_items_state *inter_call_data = NULL;
struct fcall_ctx *fctx;
int raw_page_size;
if (!superuser())
ereport(ERROR,
(errcode(E_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use raw page functions"))));
raw_page_size = VLA_SZ(raw_page) - VAR_HDR_SZ;
if (SRF_IS_FIRSTCALL())
{
struct tuple * tupdesc;
struct mctx * mctx;
if (raw_page_size < PAGE_HDR_SZ)
ereport(ERROR,
(errcode(E_INVALID_PARAMETER_VALUE),
errmsg("input page too small (%d bytes)", raw_page_size)));
fctx = SRF_FIRSTCALL_INIT();
mctx = mctx_switch(fctx->multi_call_memory_ctx);
inter_call_data = palloc(sizeof(heap_page_items_state));
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
inter_call_data->tupd = tupdesc;
inter_call_data->offset = FIRST_ITEM_ID;
inter_call_data->page = VLA_DATA(raw_page);
fctx->max_calls = PAGE_MAX_ITEM_ID(inter_call_data->page);
fctx->user_fctx = inter_call_data;
mctx_switch(mctx);
}
fctx = SRF_PERCALL_SETUP();
inter_call_data = fctx->user_fctx;
if (fctx->call_cntr < fctx->max_calls)
{
page_p page = inter_call_data->page;
struct heap_tuple * resultTuple;
datum_t result;
struct item_id * id;
datum_t values[13];
bool nulls[13];
uint16 lp_offset;
uint16 lp_flags;
uint16 lp_len;
memset(nulls, 0, sizeof(nulls));
/* Extract information from the line pointer */
id = PAGE_ITEM_ID(page, inter_call_data->offset);
lp_offset = ITEMID_OFFSET(id);
lp_flags = ITEMID_FLAGS(id);
lp_len = ITEMID_LENGTH(id);
values[0] = UINT16_TO_D(inter_call_data->offset);
values[1] = UINT16_TO_D(lp_offset);
values[2] = UINT16_TO_D(lp_flags);
values[3] = UINT16_TO_D(lp_len);
/*
* We do just enough validity checking to make sure we don't reference
* data outside the page passed to us. The page could be corrupt in
* many other ways, but at least we won't crash.
*/
if (ITEMID_HAS_STORAGE(id) &&
lp_len >= sizeof(struct htup_header *) &&
lp_offset == MAX_ALIGN(lp_offset) &&
lp_offset + lp_len <= raw_page_size)
{
struct htup_header * tuphdr;
int bits_len;
/* Extract information from the tuple header */
tuphdr = (struct htup_header *) PAGE_GET_ITEM(page, id);
values[4] = UINT32_TO_D(HTH_GET_XMIN(tuphdr));
values[5] = UINT32_TO_D(HTH_GET_XMAX(tuphdr));
values[6] = UINT32_TO_D(HTH_GET_RAW_CMDID(tuphdr)); /* shared with xvac */
values[7] = PTR_TO_D(&tuphdr->t_ctid);
values[8] = UINT32_TO_D(tuphdr->t_infomask2);
values[9] = UINT32_TO_D(tuphdr->t_infomask);
values[10] = UINT8_TO_D(tuphdr->t_hoff);
//.........这里部分代码省略.........