在C中返回一组记录

时间:2017-08-04 19:26:38

标签: c postgresql

基于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())

我是在实施某些错误,还是遗忘了什么?

1 个答案:

答案 0 :(得分:0)

确保您拥有与服务器相同的postgre SQL版本。如果没有,请下载正确的版本。如果这不是问题,请检查pg_hba.conf文件中的IP配置是否设置正确。