c - PostgreSQL C 函数输出一组记录时出现语法错误

标签 c postgresql

我为 PostgreSQL 编写了一个返回一组记录的 C 函数。根据PostgreSQL服务器编程,我输入了这样的代码:

#include "postgres.h"
#include "fmgr.h"
#include "utils/array.h"
#include "executor/spi.h"
#include "utils/builtins.h"
#include "funcapi.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(iknnLP);

int dim;
Heap res;

Datum
iknnLP(PG_FUNCTION_ARGS) {
int call_cntr;
    int call_cntr;
    int max_calls;
    FuncCallContext *funcctx;

    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);

        //////////////////////////////////////////////////////////////
        //                     My Code
        //////////////////////////////////////////////////////////////

        funcctx->max_calls = res.length;  // res is a structure
        if (get_call_result_type(fcinfo, NULL, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE)
            ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
            errmsg("function returning record called in context" "that cannot accept type record")));
        BlessTupleDesc(funcctx->tuple_desc);

        // restore memory context
        MemoryContextSwitchTo(oldcontext);
    }

    funcctx = SRF_PERCALL_SETUP();
    call_cntr = funcctx->call_cntr;
    max_calls = funcctx->max_calls;

    if (call_cntr < max_calls) {
        HeapTuple rettuple;
        Datum *retvals;
        bool *retnulls;

        retvals = (Datum*)palloc0(sizeof(Datum) * dim);
        retnulls = (bool*)palloc0(sizeof(bool) * dim);
        for (i = 0; i < dim; i++) {
            retvals[i] = Int32GetDatum(res.rec[call_cntr + 1].vals[i]);
            retnulls[i] = false;
        }
        rettuple = heap_form_tuple(funcctx->tuple_desc, retvals, retnulls);
        SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(rettuple));
    }
    else {
        SRF_RETURN_DONE(funcctx);
    }
}

我的 .sql.in 文件在这里

CREATE OR REPLACE FUNCTION iknnLP(text)
  RETURNS SETOF record
  AS 'MODULE_PATHNAME', 'iknnLP'
  LANGUAGE C STRICT;

不幸的是,我在 PostgreSQL 命令行中调用此函数时遇到语法错误:

select iknnLP('find 3 neighbour of (a0,a1)(31,32) from test') as(a int, b int, distance float);
ERROR:  syntax error at or near "("
LINE 1: ...hbour of (a0,a1)(31,32) from test') as(a int, b ...
                                                 ^

PS:我在制作文件时收到警告:

warning: implicit declaration of function ‘heap_form_tuple’ [-Wimplicit-function-declaration]
rettuple = heap_form_tuple(funcctx->tuple_desc, retvals, retnulls);
^

有人知道原因吗

最佳答案

您的 SQL 语法不完全一致。您正在尝试使用别名构造将字段名称和类型分配给记录。

由于您要返回 SET OF 记录,因此您应该真正使用 FROM 子句中的函数以及记录集的别名:

SELECT a, b, distance
FROM iknnLP('find 3 neighbour of (a0,a1)(31,32) from test') AS x(a int, b int, distance float);

关于c - PostgreSQL C 函数输出一组记录时出现语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31665841/

相关文章:

c - 良好的实践和内存泄漏

c++ - 在 C/C++ 中正确地从管道获取输出

java - 如何使用 QueryDSL 在 "like"值上加 1

database - pgpool-II : is possible to promote a node to master more than one time?

ruby-on-rails - PostgreSQL 错误, "no pg_hba.conf entry"

html - 使用 postgres、nodejs 和 html 动态搜索查询

c - 如何在 C 中将 char 转换为 string?

c++ - 在 C++ 接口(interface)中隐藏 longjmps 到 C 代码

postgresql - 字符串排序顺序(LC_COLLATE 和 LC_CTYPE)

c - 使 fscanf 忽略 int 前没有空格的字母