基于PostgreSQL 9.6文档,我正在尝试执行一个返回记录集的函数。请遵循C:
中的代码#include <funcapi.h>
.....
FuncCallContext *funcctx; /*help control to save and remember state */
MemoryContext oldcontext, newcontext;
Datum result;
uint32 ct_call;
TupleDesc tupdesc;
AttInMetadata *attinmeta;
// struct line_reverse_tuple_args *args; /*aux struct for save state*/
// struct geo_linestring *line1;
// struct geo_linestring *line2;
elog(NOTICE, "is being called called");
/* Determine if the function is being called for the first time.*/
if(SRF_IS_FIRSTCALL())
{
elog(NOTICE, "geo_linestring_intersection_points_v1 first called");
/* initialize the FuncCallContext */
funcctx = SRF_FIRSTCALL_INIT();
/* switch to memory context appropriate for multiple function calls */
newcontext = funcctx->multi_call_memory_ctx;
oldcontext = MemoryContextSwitchTo(newcontext);
// line1 = PG_GETARG_GEOLINESTRING_TYPE_P(0);
// line2 = PG_GETARG_GEOLINESTRING_TYPE_P(1);
/* allocate and zero-fill struct for persisting extracted arguments*/
//args = palloc0(sizeof(struct line_reverse_tuple_args));
//funcctx->user_fctx = args;
/* total number of tuples to be returned */
funcctx->max_calls = 3;
/* 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")));
attinmeta = TupleDescGetAttInMetadata(tupdesc);
funcctx->attinmeta = attinmeta;
/* restore memory context */
MemoryContextSwitchTo(oldcontext);
elog(NOTICE, "geo_linestring_intersection_points_v1 end first call");
}
funcctx = SRF_PERCALL_SETUP();
ct_call = funcctx->call_cntr;
attinmeta = funcctx->attinmeta;
elog(NOTICE, "funcapi others call");
if (ct_call < funcctx->max_calls)
{
HeapTuple tuple;
char **values;
/*
* Prepare a values array for building the returned tuple.
* This should be an array of C strings which will
* be processed later by the type input functions.
*/
values = (char **) palloc(3 * sizeof(char *));
values[0] = (char *) palloc(16 * sizeof(char));
values[1] = (char *) palloc(16 * sizeof(char));
values[2] = (char *) palloc(16 * sizeof(char));
snprintf(values[0], 16, "%d", 1 * PG_GETARG_INT32(1));
snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1));
snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1));
/* build a tuple */
tuple = BuildTupleFromCStrings(attinmeta, values);
/* make the tuple into a datum */
result = HeapTupleGetDatum(tuple);
/* clean up (this is not really necessary) */
pfree(values[0]);
pfree(values[1]);
pfree(values[2]);
pfree(values);
SRF_RETURN_NEXT(funcctx, result);
}
else
{
SRF_RETURN_DONE(funcctx);
}
在sql中创建函数在文档中是相同的。 但是当我运行这样的SQL时:
SELECT * FROM build_rows_funcapi(1,48);
服务器崩溃。将显示以下消息:
服务器意外关闭了连接。
基于elog,可以观察到函数执行到第一个if:if(SRF_IS_FIRSTCALL())
我是在实施某些错误,还是遗忘了什么?
答案 0 :(得分:0)
确保您拥有与服务器相同的postgre SQL版本。如果没有,请下载正确的版本。如果这不是问题,请检查pg_hba.conf文件中的IP配置是否设置正确。