本文整理汇总了C++中SRF_RETURN_DONE函数的典型用法代码示例。如果您正苦于以下问题:C++ SRF_RETURN_DONE函数的具体用法?C++ SRF_RETURN_DONE怎么用?C++ SRF_RETURN_DONE使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了SRF_RETURN_DONE函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: TradeStatusFrame1
//.........这里部分代码省略.........
strcat(values[i_status_name], SPI_getvalue(tuple, tupdesc, 3));
strcat(values[i_status_name], "\"");
strcat(values[i_type_name], "\"");
strcat(values[i_type_name], SPI_getvalue(tuple, tupdesc, 4));
strcat(values[i_type_name], "\"");
strcat(values[i_symbol], "\"");
strcat(values[i_symbol], SPI_getvalue(tuple, tupdesc, 5));
strcat(values[i_symbol], "\"");
strcat(values[i_trade_qty], SPI_getvalue(tuple, tupdesc, 6));
strcat(values[i_exec_name], "\"");
strcat(values[i_exec_name], SPI_getvalue(tuple, tupdesc, 7));
strcat(values[i_exec_name], "\"");
strcat(values[i_charge], SPI_getvalue(tuple, tupdesc, 8));
strcat(values[i_s_name], "\"");
strcat(values[i_s_name], SPI_getvalue(tuple, tupdesc, 9));
strcat(values[i_s_name], "\"");
strcat(values[i_ex_name], "\"");
strcat(values[i_ex_name], SPI_getvalue(tuple, tupdesc, 10));
strcat(values[i_ex_name], "\"");
}
strcat(values[i_trade_id], "}");
strcat(values[i_trade_dts], "}");
strcat(values[i_status_name], "}");
strcat(values[i_type_name], "}");
strcat(values[i_symbol], "}");
strcat(values[i_trade_qty], "}");
strcat(values[i_exec_name], "}");
strcat(values[i_charge], "}");
strcat(values[i_s_name], "}");
strcat(values[i_ex_name], "}");
#ifdef DEBUG
sprintf(sql, SQLTSF1_2, acct_id);
elog(NOTICE, "SQL\n%s", sql);
#endif /* DEBUG */
ret = SPI_execute_plan(TSF1_2, args, nulls, true, 0);
if (ret == SPI_OK_SELECT) {
tupdesc = SPI_tuptable->tupdesc;
tuptable = SPI_tuptable;
if (SPI_processed > 0) {
tuple = tuptable->vals[0];
values[i_cust_l_name] = SPI_getvalue(tuple, tupdesc, 1);
values[i_cust_f_name] = SPI_getvalue(tuple, tupdesc, 2);
values[i_broker_name] = SPI_getvalue(tuple, tupdesc, 3);
}
} else {
FAIL_FRAME_SET(&funcctx->max_calls, TSF1_statements[1].sql);
dump_tsf1_inputs(acct_id);
}
/* 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(TSF1_savedcxt);
}
/* 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 < 14; i++) {
elog(NOTICE, "TSF1 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();
if (TSF1_savedcxt) MemoryContextSwitchTo(TSF1_savedcxt);
SRF_RETURN_DONE(funcctx);
}
}
示例2: generate_series_step_int4
Datum
generate_series_step_int4(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
generate_series_fctx *fctx;
int32 result;
MemoryContext oldcontext;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
int32 start = PG_GETARG_INT32(0);
int32 finish = PG_GETARG_INT32(1);
int32 step = 1;
/* see if we were given an explicit step size */
if (PG_NARGS() == 3)
step = PG_GETARG_INT32(2);
if (step == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("step size may not equal zero")));
/* 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);
/* allocate memory for user context */
fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
/*
* Use fctx to keep state from call to call. Seed current with the
* original start value
*/
fctx->current = start;
fctx->finish = finish;
fctx->step = step;
funcctx->user_fctx = fctx;
MemoryContextSwitchTo(oldcontext);
}
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
/*
* get the saved state and use current as the result for this iteration
*/
fctx = funcctx->user_fctx;
result = fctx->current;
if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
(fctx->step < 0 && fctx->current >= fctx->finish))
{
/* increment current in preparation for next iteration */
fctx->current += fctx->step;
/* if next-value computation overflows, this is the final result */
if (SAMESIGN(result, fctx->step) && !SAMESIGN(result, fctx->current))
fctx->step = 0;
/* 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);
}
示例3: 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);
}
示例4: 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);
}
}
示例5: pg_prepared_xact
/*
* pg_prepared_xact
* Produce a view with one row per prepared transaction.
*
* This function is here so we don't have to export the
* GlobalTransactionData struct definition.
*/
Datum
pg_prepared_xact(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Working_State *status;
if (SRF_IS_FIRSTCALL())
{
TupleDesc tupdesc;
MemoryContext oldcontext;
/* 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);
/* build tupdesc for result tuples */
/* this had better match pg_prepared_xacts view in system_views.sql */
tupdesc = CreateTemplateTupleDesc(5, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "transaction",
XIDOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "gid",
TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepared",
TIMESTAMPTZOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "ownerid",
OIDOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "dbid",
OIDOID, -1, 0);
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
/*
* Collect all the 2PC status information that we will format and send
* out as a result set.
*/
status = (Working_State *) palloc(sizeof(Working_State));
funcctx->user_fctx = (void *) status;
status->ngxacts = GetPreparedTransactionList(&status->array);
status->currIdx = 0;
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
status = (Working_State *) funcctx->user_fctx;
while (status->array != NULL && status->currIdx < status->ngxacts)
{
GlobalTransaction gxact = &status->array[status->currIdx++];
Datum values[5];
bool nulls[5];
HeapTuple tuple;
Datum result;
if (!gxact->valid)
continue;
/*
* Form tuple with appropriate data.
*/
MemSet(values, 0, sizeof(values));
MemSet(nulls, 0, sizeof(nulls));
values[0] = TransactionIdGetDatum(gxact->proc.xid);
values[1] = CStringGetTextDatum(gxact->gid);
values[2] = TimestampTzGetDatum(gxact->prepared_at);
values[3] = ObjectIdGetDatum(gxact->owner);
values[4] = ObjectIdGetDatum(gxact->proc.databaseId);
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
result = HeapTupleGetDatum(tuple);
SRF_RETURN_NEXT(funcctx, result);
}
SRF_RETURN_DONE(funcctx);
}
示例6: pg_stat_get_activity
//.........这里部分代码省略.........
values[6] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
else
nulls[6] = true;
if (beentry->st_activity_start_timestamp != 0)
values[7] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
else
nulls[7] = true;
if (beentry->st_proc_start_timestamp != 0)
values[8] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
else
nulls[8] = true;
/* A zeroed client addr means we don't know */
memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
sizeof(zero_clientaddr) == 0))
{
nulls[9] = true;
nulls[10] = true;
}
else
{
if (beentry->st_clientaddr.addr.ss_family == AF_INET
#ifdef HAVE_IPV6
|| beentry->st_clientaddr.addr.ss_family == AF_INET6
#endif
)
{
char remote_host[NI_MAXHOST];
char remote_port[NI_MAXSERV];
int ret;
remote_host[0] = '\0';
remote_port[0] = '\0';
ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
beentry->st_clientaddr.salen,
remote_host, sizeof(remote_host),
remote_port, sizeof(remote_port),
NI_NUMERICHOST | NI_NUMERICSERV);
if (ret)
{
nulls[9] = true;
nulls[10] = true;
}
else
{
clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
values[9] = DirectFunctionCall1(inet_in,
CStringGetDatum(remote_host));
values[10] = Int32GetDatum(atoi(remote_port));
}
}
else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
{
/*
* Unix sockets always reports NULL for host and -1 for
* port, so it's possible to tell the difference to
* connections we have no permissions to view, or with
* errors.
*/
nulls[9] = true;
values[10] = DatumGetInt32(-1);
}
else
{
/* Unknown address type, should never happen */
nulls[9] = true;
nulls[10] = true;
}
}
values[12] = BoolGetDatum(beentry->st_waiting_resource);
}
else
{
/* No permissions to view data about this session */
values[4] = CStringGetTextDatum("<insufficient privilege>");
nulls[5] = true;
nulls[6] = true;
nulls[7] = true;
nulls[8] = true;
nulls[9] = true;
nulls[10] = true;
nulls[12] = true;
}
values[11] = Int32GetDatum(beentry->st_session_id); /* GPDB */
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
}
else
{
/* nothing left */
SRF_RETURN_DONE(funcctx);
}
}
示例7: compute_pa_grid_cell
Datum
compute_pa_grid_cell(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
TupleDesc tupdesc;
pa_grid* grid;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
MemoryContext oldcontext;
/* 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);
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_SCALAR)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("function returning record called in context "
"that cannot accept type record")));
/*
* WARNING: there stil is a small change that memory is alllocated
* during the next calls. This could cause problems.
* My user context stuff, allocate all memory expected in this call.
* Other memory allocated outside this context will be thrown away
* after the first call.
*/
text *arg1 = PG_GETARG_TEXT_P(0);
funcctx->user_fctx = create_pa_grid(VARDATA(arg1));
grid = (pa_grid*)funcctx->user_fctx;
if (grid->q.keyFlag == KD_BYTE_STRING)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("pa_grid_cell does not support byte keys. Use pa_grid function!")));
}
MemoryContextSwitchTo(oldcontext);
}
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
grid = (pa_grid*)funcctx->user_fctx;
if ( next_pa_grid(grid) )
{
Datum long_result = Int64GetDatum( grid->cellKey );
SRF_RETURN_NEXT(funcctx, long_result);
}
else /* do when there is no more left */
{
free_pa_grid(grid); // free the grid
funcctx->user_fctx = NULL;
//
SRF_RETURN_DONE(funcctx);
}
}
示例8: compute_pa_grid
Datum
compute_pa_grid(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
TupleDesc tupdesc;
AttInMetadata *attinmeta;
pa_grid* grid;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
MemoryContext oldcontext;
/* 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);
/* 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;
/*
* WARNING: there stil is a small change that memory is alllocated
* during the next calls. This could cause problems.
* My user context stuff, allocate all memory expected in this call.
* Other memory allocated outside this context will be thrown away
* after the first call.
*/
text *arg1 = PG_GETARG_TEXT_P(0);
// FILE* f = fopen("/tmp/LOG","a");
// fprintf(f,"KEY=[%s]\n",VARDATA(arg1));
// fclose(f);
if ( !(funcctx->user_fctx = create_pa_grid(VARDATA(arg1)))) {
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), // INCOMPLETE
errmsg("possible memory error "
)));
}
grid = (pa_grid*)funcctx->user_fctx;
MemoryContextSwitchTo(oldcontext);
}
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
grid = (pa_grid*)funcctx->user_fctx;
attinmeta = funcctx->attinmeta;
int nextVal = next_pa_grid(grid);
if ( nextVal < 0 ) {
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), // INCOMPLETE
errmsg("possible memory error "
)));
}
if ( nextVal )
{
HeapTuple tuple;
Datum result;
snprintf(grid->values[0], 24, "%ld", grid->gridKey);
snprintf(grid->values[1], 24, "%ld", grid->cellKey);
snprintf(grid->values[2], (grid->q.totalBytes+1) * 2, "%s", grid->cellByteKey);
/* build a tuple */
tuple = BuildTupleFromCStrings(attinmeta, grid->values);
/* make the tuple into a datum */
result = HeapTupleGetDatum(tuple);
SRF_RETURN_NEXT(funcctx, result);
}
else /* do when there is no more left */
{
free_pa_grid(grid); // free the grid
funcctx->user_fctx = NULL;
//
SRF_RETURN_DONE(funcctx);
}
}
示例9: withPoints_ksp
//.........这里部分代码省略.........
/*******************************************************************************/
if (SRF_IS_FIRSTCALL()) {
MemoryContext oldcontext;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/*******************************************************************************/
/* MODIFY AS NEEDED */
// CREATE OR REPLACE FUNCTION pgr_withPoint(
// edges_sql TEXT,
// points_sql TEXT,
// start_pid INTEGER,
// end_pid BIGINT,
// k BIGINT,
//
// directed BOOLEAN -- DEFAULT true,
// heap_paths BOOLEAN -- DEFAULT false,
// driving_side CHAR -- DEFAULT 'b',
// details BOOLEAN -- DEFAULT false,
PGR_DBG("Calling process");
PGR_DBG("initial driving side:%s", text_to_cstring(PG_GETARG_TEXT_P(7)));
process(
text_to_cstring(PG_GETARG_TEXT_P(0)),
text_to_cstring(PG_GETARG_TEXT_P(1)),
PG_GETARG_INT64(2),
PG_GETARG_INT64(3),
PG_GETARG_INT32(4),
PG_GETARG_BOOL(5),
PG_GETARG_BOOL(6),
text_to_cstring(PG_GETARG_TEXT_P(7)),
PG_GETARG_BOOL(8),
&result_tuples,
&result_count);
/* */
/*******************************************************************************/
#if PGSQL_VERSION > 95
funcctx->max_calls = result_count;
#else
funcctx->max_calls = (uint32_t)result_count;
#endif
funcctx->user_fctx = result_tuples;
if (get_call_result_type(fcinfo, NULL, &tuple_desc) != TYPEFUNC_COMPOSITE)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("function returning record called in context "
"that cannot accept type record")));
funcctx->tuple_desc = tuple_desc;
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
tuple_desc = funcctx->tuple_desc;
result_tuples = (General_path_element_t*) funcctx->user_fctx;
if (funcctx->call_cntr < funcctx->max_calls) {
HeapTuple tuple;
Datum result;
Datum *values;
bool* nulls;
/*******************************************************************************/
/* MODIFY AS NEEDED */
values = palloc(7 * sizeof(Datum));
nulls = palloc(7 * sizeof(bool));
size_t i;
for(i = 0; i < 7; ++i) {
nulls[i] = false;
}
/*
OUT seq INTEGER, OUT path_id INTEGER, OUT path_seq INTEGER,
OUT node BIGINT, OUT edge BIGINT,
OUT cost FLOAT, OUT agg_cost FLOAT)
*/
// postgres starts counting from 1
values[0] = Int32GetDatum(funcctx->call_cntr + 1);
values[1] = Int32GetDatum((int)(result_tuples[funcctx->call_cntr].start_id + 1));
values[2] = Int32GetDatum(result_tuples[funcctx->call_cntr].seq);
values[3] = Int64GetDatum(result_tuples[funcctx->call_cntr].node);
values[4] = Int64GetDatum(result_tuples[funcctx->call_cntr].edge);
values[5] = Float8GetDatum(result_tuples[funcctx->call_cntr].cost);
values[6] = Float8GetDatum(result_tuples[funcctx->call_cntr].agg_cost);
/*******************************************************************************/
tuple =heap_form_tuple(tuple_desc, values, nulls);
result = HeapTupleGetDatum(tuple);
SRF_RETURN_NEXT(funcctx, result);
} else {
SRF_RETURN_DONE(funcctx);
}
}
示例10: bt_page_items
//.........这里部分代码省略.........
errmsg("cannot access temporary tables of other sessions")));
if (blkno == 0)
elog(ERROR, "block 0 is a meta page");
CHECK_RELATION_BLOCK_RANGE(rel, blkno);
buffer = ReadBuffer(rel, blkno);
LockBuffer(buffer, BUFFER_LOCK_SHARE);
/*
* We copy the page into local storage to avoid holding pin on the
* buffer longer than we must, and possibly failing to release it at
* all if the calling query doesn't fetch all rows.
*/
mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);
uargs = palloc(sizeof(struct user_args));
uargs->page = palloc(BLCKSZ);
memcpy(uargs->page, BufferGetPage(buffer), BLCKSZ);
UnlockReleaseBuffer(buffer);
relation_close(rel, AccessShareLock);
uargs->offset = FirstOffsetNumber;
opaque = (BTPageOpaque) PageGetSpecialPointer(uargs->page);
if (P_ISDELETED(opaque))
elog(NOTICE, "page is deleted");
fctx->max_calls = PageGetMaxOffsetNumber(uargs->page);
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
fctx->attinmeta = TupleDescGetAttInMetadata(tupleDesc);
fctx->user_fctx = uargs;
MemoryContextSwitchTo(mctx);
}
fctx = SRF_PERCALL_SETUP();
uargs = fctx->user_fctx;
if (fctx->call_cntr < fctx->max_calls)
{
ItemId id;
IndexTuple itup;
int j;
int off;
int dlen;
char *dump;
char *ptr;
id = PageGetItemId(uargs->page, uargs->offset);
if (!ItemIdIsValid(id))
elog(ERROR, "invalid ItemId");
itup = (IndexTuple) PageGetItem(uargs->page, id);
j = 0;
values[j++] = psprintf("%d", uargs->offset);
values[j++] = psprintf("(%u,%u)",
BlockIdGetBlockNumber(&(itup->t_tid.ip_blkid)),
itup->t_tid.ip_posid);
values[j++] = psprintf("%d", (int) IndexTupleSize(itup));
values[j++] = psprintf("%c", IndexTupleHasNulls(itup) ? 't' : 'f');
values[j++] = psprintf("%c", IndexTupleHasVarwidths(itup) ? 't' : 'f');
ptr = (char *) itup + IndexInfoFindDataOffset(itup->t_info);
dlen = IndexTupleSize(itup) - IndexInfoFindDataOffset(itup->t_info);
dump = palloc0(dlen * 3 + 1);
values[j] = dump;
for (off = 0; off < dlen; off++)
{
if (off > 0)
*dump++ = ' ';
sprintf(dump, "%02x", *(ptr + off) & 0xff);
dump += 2;
}
tuple = BuildTupleFromCStrings(fctx->attinmeta, values);
result = HeapTupleGetDatum(tuple);
uargs->offset = uargs->offset + 1;
SRF_RETURN_NEXT(fctx, result);
}
else
{
pfree(uargs->page);
pfree(uargs);
SRF_RETURN_DONE(fctx);
}
}
示例11: extractGridData
Datum extractGridData(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
TupleDesc tupdesc;
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
/* 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")));
/* switch to memory context appropriate for multiple function calls */
MemoryContext oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
// Initalize geos
static int geosInitialized = 0;
if ( ! geosInitialized )
{
initGEOS(logInfo, logError);
geosInitialized = 1;
}
// Get the data to be returned
struct GridPointDataListIterator * points = getExtractGridDataReturnValues(fcinfo);
// Convert data into a set of Datums
funcctx->max_calls = points->list->count;
Datum * returnValues = palloc(sizeof(Datum) * funcctx->max_calls);
int i;
for ( i = 0; i < funcctx->max_calls; ++ i )
returnValues[i] = getNextReturnTupleViaDatums(GridPointDataListIteratorNext(points), funcctx->tuple_desc);
funcctx->user_fctx = (void *) returnValues;
// Delete intermediate data
// GridPointDataListDelete(points->list);
// GridPointDataListIteratorDelete(points);
MemoryContextSwitchTo(oldcontext);
}
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
if ( funcctx->call_cntr < funcctx->max_calls )
{
Datum * ret = (Datum *) funcctx->user_fctx;
Datum result = ret[funcctx->call_cntr];
SRF_RETURN_NEXT(funcctx, result);
}
else
{
//GridPointDataListDelete(iterator->list);
SRF_RETURN_DONE(funcctx);
}
}
示例12: kshortest_path
PGDLLEXPORT Datum
kshortest_path(PG_FUNCTION_ARGS) {
FuncCallContext *funcctx;
TupleDesc tuple_desc;
General_path_element_t *path = NULL;
size_t result_count = 0;
if (SRF_IS_FIRSTCALL()) {
MemoryContext oldcontext;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/*
CREATE OR REPLACE FUNCTION _pgr_ksp(
sql text,
start_vid bigint,
end_vid bigint,
k integer,
directed boolean,
heap_paths boolean
*/
PGR_DBG("Calling process");
compute(
text_to_cstring(PG_GETARG_TEXT_P(0)),
PG_GETARG_INT64(1),
PG_GETARG_INT64(2),
PG_GETARG_INT32(3),
PG_GETARG_BOOL(4),
PG_GETARG_BOOL(5),
&path,
&result_count);
PGR_DBG("Total number of tuples to be returned %ld \n", result_count);
#if PGSQL_VERSION > 95
funcctx->max_calls = result_count;
#else
funcctx->max_calls = (uint32_t)result_count;
#endif
funcctx->user_fctx = path;
if (get_call_result_type(fcinfo, NULL, &tuple_desc)
!= TYPEFUNC_COMPOSITE)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("function returning record called in context "
"that cannot accept type record\n")));
funcctx->tuple_desc = tuple_desc;
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
tuple_desc = funcctx->tuple_desc;
path = (General_path_element_t*) funcctx->user_fctx;
if (funcctx->call_cntr < funcctx->max_calls) {
HeapTuple tuple;
Datum result;
Datum *values;
bool* nulls;
values = palloc(7 * sizeof(Datum));
nulls = palloc(7 * sizeof(bool));
size_t i;
for (i = 0; i < 7; ++i) {
nulls[i] = false;
}
values[0] = Int32GetDatum(funcctx->call_cntr + 1);
values[1] = Int32GetDatum(path[funcctx->call_cntr].start_id + 1);
values[2] = Int32GetDatum(path[funcctx->call_cntr].seq);
values[3] = Int64GetDatum(path[funcctx->call_cntr].node);
values[4] = Int64GetDatum(path[funcctx->call_cntr].edge);
values[5] = Float8GetDatum(path[funcctx->call_cntr].cost);
values[6] = Float8GetDatum(path[funcctx->call_cntr].agg_cost);
tuple = heap_form_tuple(tuple_desc, values, nulls);
result = HeapTupleGetDatum(tuple);
SRF_RETURN_NEXT(funcctx, result);
} else { /* do when there is no more left */
SRF_RETURN_DONE(funcctx);
}
}
示例13: each
Datum
each(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
AKStore *st;
if (SRF_IS_FIRSTCALL())
{
TupleDesc tupdesc;
MemoryContext oldcontext;
HStore *hs = PG_GETARG_HS(0);
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
st = (AKStore *) palloc(sizeof(AKStore));
st->i = 0;
st->hs = (HStore *) palloc(VARSIZE(hs));
memcpy(st->hs, hs, VARSIZE(hs));
funcctx->user_fctx = (void *) st;
/* 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");
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
MemoryContextSwitchTo(oldcontext);
PG_FREE_IF_COPY(hs, 0);
}
funcctx = SRF_PERCALL_SETUP();
st = (AKStore *) funcctx->user_fctx;
if (st->i < st->hs->size)
{
HEntry *ptr = &(ARRPTR(st->hs)[st->i]);
Datum res,
dvalues[2];
char nulls[] = {' ', ' '};
text *item;
HeapTuple tuple;
item = (text *) palloc(VARHDRSZ + ptr->keylen);
SET_VARSIZE(item, VARHDRSZ + ptr->keylen);
memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos, ptr->keylen);
dvalues[0] = PointerGetDatum(item);
if (ptr->valisnull)
{
dvalues[1] = (Datum) 0;
nulls[1] = 'n';
}
else
{
int vallen = ptr->vallen;
item = (text *) palloc(VARHDRSZ + vallen);
SET_VARSIZE(item, VARHDRSZ + vallen);
memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos + ptr->keylen, vallen);
dvalues[1] = PointerGetDatum(item);
}
st->i++;
tuple = heap_formtuple(funcctx->attinmeta->tupdesc, dvalues, nulls);
res = HeapTupleGetDatum(tuple);
pfree(DatumGetPointer(dvalues[0]));
if (nulls[1] != 'n')
pfree(DatumGetPointer(dvalues[1]));
SRF_RETURN_NEXT(funcctx, res);
}
pfree(st->hs);
pfree(st);
SRF_RETURN_DONE(funcctx);
}
示例14: one_to_one_withPoints
//.........这里部分代码省略.........
size_t result_count = 0;
/* */
/*******************************************************************************/
if (SRF_IS_FIRSTCALL()) {
MemoryContext oldcontext;
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/*******************************************************************************/
/* MODIFY AS NEEDED */
// CREATE OR REPLACE FUNCTION pgr_withPoint(
// edges_sql TEXT,
// points_sql TEXT,
// start_pid BIGINT,
// end_pid BIGINT,
// directed BOOLEAN -- DEFAULT true,
// driving_side CHAR -- DEFAULT 'b',
// details BOOLEAN -- DEFAULT true,
// only_cost BOOLEAN DEFAULT false,
PGR_DBG("Calling process");
PGR_DBG("initial driving side:%s", pgr_text2char(PG_GETARG_TEXT_P(5)));
process(
pgr_text2char(PG_GETARG_TEXT_P(0)),
pgr_text2char(PG_GETARG_TEXT_P(1)),
PG_GETARG_INT64(2),
PG_GETARG_INT64(3),
PG_GETARG_BOOL(4),
pgr_text2char(PG_GETARG_TEXT_P(5)),
PG_GETARG_BOOL(6),
PG_GETARG_BOOL(7),
&result_tuples,
&result_count);
/* */
/*******************************************************************************/
funcctx->max_calls = (uint32_t)result_count;
funcctx->user_fctx = result_tuples;
if (get_call_result_type(fcinfo, NULL, &tuple_desc) != TYPEFUNC_COMPOSITE)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("function returning record called in context "
"that cannot accept type record")));
funcctx->tuple_desc = tuple_desc;
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
call_cntr = funcctx->call_cntr;
max_calls = funcctx->max_calls;
tuple_desc = funcctx->tuple_desc;
result_tuples = (General_path_element_t*) funcctx->user_fctx;
if (call_cntr < max_calls) {
HeapTuple tuple;
Datum result;
Datum *values;
char* nulls;
/*******************************************************************************/
/* MODIFY AS NEEDED */
// OUT seq BIGINT,
// OUT path_seq,
// OUT node BIGINT,
// OUT edge BIGINT,
// OUT cost FLOAT,
// OUT agg_cost FLOAT)
values = palloc(6 * sizeof(Datum));
nulls = palloc(6 * sizeof(char));
size_t i;
for(i = 0; i < 6; ++i) {
nulls[i] = ' ';
}
// postgres starts counting from 1
values[0] = Int32GetDatum(call_cntr + 1);
values[1] = Int32GetDatum(result_tuples[call_cntr].seq);
values[2] = Int64GetDatum(result_tuples[call_cntr].node);
values[3] = Int64GetDatum(result_tuples[call_cntr].edge);
values[4] = Float8GetDatum(result_tuples[call_cntr].cost);
values[5] = Float8GetDatum(result_tuples[call_cntr].agg_cost);
/*******************************************************************************/
tuple = heap_formtuple(tuple_desc, values, nulls);
result = HeapTupleGetDatum(tuple);
SRF_RETURN_NEXT(funcctx, result);
} else {
// cleanup
if (result_tuples) free(result_tuples);
SRF_RETURN_DONE(funcctx);
}
}
示例15: pg_lock_status
//.........这里部分代码省略.........
Datum values[16];
bool nulls[16];
int i;
int whichresultset = 0;
int whichelement = mystatus->currIdx - lockData->nelements;
int whichrow = whichelement;
Assert(Gp_role == GP_ROLE_DISPATCH);
/*
* Because we have one result set per segDB (rather than one big result set with everything),
* we need to figure out which result set we are on, and which row within that result set
* we are returning.
*
* So, we walk through all the result sets and all the rows in each one, in order.
*/
while(whichrow >= PQntuples(mystatus->segresults[whichresultset]))
{
whichrow -= PQntuples(mystatus->segresults[whichresultset]);
whichresultset++;
if (whichresultset >= mystatus->numsegresults)
break;
}
/*
* If this condition is true, we have already sent everything back,
* and we just want to do the SRF_RETURN_DONE
*/
if (whichresultset >= mystatus->numsegresults)
break;
mystatus->currIdx++;
/*
* Form tuple with appropriate data we got from the segDBs
*/
MemSet(values, 0, sizeof(values));
MemSet(nulls, false, sizeof(nulls));
/*
* For each column, extract out the value (which comes out in text).
* Convert it to the appropriate datatype to match our tupledesc,
* and put that in values.
* The columns look like this (from select statement earlier):
*
* " (locktype text, database oid, relation oid, page int4, tuple int2,"
* " transactionid xid, classid oid, objid oid, objsubid int2,"
* " transaction xid, pid int4, mode text, granted boolean, "
* " mppSessionId int4, mppIsWriter boolean, gp_segment_id int4) ,"
*/
values[0] = CStringGetTextDatum(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 0));
values[1] = ObjectIdGetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 1)));
values[2] = ObjectIdGetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 2)));
values[3] = UInt32GetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 3)));
values[4] = UInt16GetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 4)));
values[5] = TransactionIdGetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 5)));
values[6] = ObjectIdGetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 6)));
values[7] = ObjectIdGetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 7)));
values[8] = UInt16GetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 8)));
values[9] = TransactionIdGetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 9)));
values[10] = UInt32GetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow,10)));
values[11] = CStringGetTextDatum(PQgetvalue(mystatus->segresults[whichresultset], whichrow,11));
values[12] = BoolGetDatum(strncmp(PQgetvalue(mystatus->segresults[whichresultset], whichrow,12),"t",1)==0);
values[13] = Int32GetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow,13)));
values[14] = BoolGetDatum(strncmp(PQgetvalue(mystatus->segresults[whichresultset], whichrow,14),"t",1)==0);
values[15] = Int32GetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow,15)));
/*
* Copy the null info over. It should all match properly.
*/
for (i=0; i<16; i++)
{
nulls[i] = PQgetisnull(mystatus->segresults[whichresultset], whichrow, i);
}
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
result = HeapTupleGetDatum(tuple);
SRF_RETURN_NEXT(funcctx, result);
}
/*
* if we dispatched to the segDBs, free up the memory holding the result sets.
* Otherwise we might leak this memory each time we got called (does it automatically
* get freed by the pool being deleted? Probably, but this is safer).
*/
if (mystatus->segresults != NULL)
{
int i;
for (i = 0; i < mystatus->numsegresults; i++)
PQclear(mystatus->segresults[i]);
free(mystatus->segresults);
}
SRF_RETURN_DONE(funcctx);
}