Postgresql c函数返回一行2个文件
我是postgresql c函数的新手,我开始以下示例 我想编写一个简单的函数,它在一个SQL和接收参数evaluate中分别返回两个字段作为两列的总和(现在更简单) 下面的函数无法通过检查Postgresql c函数返回一行2个文件,postgresql,Postgresql,我是postgresql c函数的新手,我开始以下示例 我想编写一个简单的函数,它在一个SQL和接收参数evaluate中分别返回两个字段作为两列的总和(现在更简单) 下面的函数无法通过检查 (get_call_result_type(fcinfo, &resultTypeId, &resultTupleDesc) != TYPEFUNC_COMPOSITE) 如果我删除这一行,我会从这个查询中得到一个整数 select * from pdc_imuanno(2012); 和
(get_call_result_type(fcinfo, &resultTypeId, &resultTupleDesc) != TYPEFUNC_COMPOSITE)
如果我删除这一行,我会从这个查询中得到一个整数
select * from pdc_imuanno(2012);
和错误来自
select (a).* from pdc_imuanno(2012) a;
因为它不是复合类型
问题是,如果元组不正确,我如何为元组准备模板
resultTupleDesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "abp1", FLOAT4OID, -1, 0);
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "abp2", FLOAT4OID, -1, 0);
还有更多
get_call_result_type(fcinfo, &resultTypeId, &resultTupleDesc)
fcinfo什么是,从哪里来
源表:
CREATE TABLE imu.calcolo (
codfis character varying(16) NOT NULL,
anno integer NOT NULL,
abp1 numeric,
abp2 numeric,
CONSTRAINT imucalcolo_pkey PRIMARY KEY (codfis, anno)
)
WITH ( OIDS=FALSE );
-------------------------------------------------------
#include "postgres.h"
#include "fmgr.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "executor/spi.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
#include <math.h>
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/numeric.h"
#include "access/htup_details.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(test_query);
Datum test_query(PG_FUNCTION_ARGS);
Datum
test_query(PG_FUNCTION_ARGS)
{
TupleDesc resultTupleDesc, tupledesc;
bool bisnull, cisnull;
Oid resultTypeId;
Datum retvals[2];
bool retnulls[2];
HeapTuple rettuple;
sprintf(query,"SELECT anno, abp1::real, abp2::real "
"FROM imu.calcolo WHERE anno = %d;",PG_GETARG_INT32(0));
int ret;
int proc;
float abp1 = 0;
float abp2 = 0;
SPI_connect();
ret = SPI_exec(query,0);
proc = SPI_processed;
if (ret > 0 && SPI_tuptable != NULL)
{
HeapTuple tuple;
tupledesc = SPI_tuptable->tupdesc;
SPITupleTable *tuptable = SPI_tuptable;
for (j = 0; j < proc; j++)
{
tuple = tuptable->vals[j];
abp1 += DatumGetFloat4(SPI_getbinval(tuple, tupledesc, 2, &bisnull));
abp2 += DatumGetFloat4(SPI_getbinval(tuple, tupledesc, 3, &cisnull));
}
}
resultTupleDesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "abp1", FLOAT4OID, -1, 0);
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "abp2", FLOAT4OID, -1, 0);
if (get_call_result_type(fcinfo, &resultTypeId, &resultTupleDesc) != TYPEFUNC_COMPOSITE) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("function returning record called in context that cannot accept type record")));
}
resultTupleDesc = BlessTupleDesc(resultTupleDesc);
SPI_finish();
retvals[0] = Float4GetDatum(abp1);
retvals[1] = Float4GetDatum(abp2);
retnulls[1] = bisnull;
retnulls[2] = cisnull;
rettuple = heap_form_tuple( resultTupleDesc, retvals, retnulls);
PG_RETURN_DATUM( HeapTupleGetDatum( rettuple ) );
}
查询:
select * from pdc_imuanno(2012);
好吧,我发现了一个简单而愚蠢的错误
我自己创建了函数retunning 1字段,并将其导出为return 2字段
通过创建sql,它可以正常工作
CREATE FUNCTION pdc_imuanno(integer)
RETURNS TABLE(abp1 real, abp2 real)
AS 'pdc','test_query'
LANGUAGE C STABLE STRICT;
不管怎样,它的行数是有限的,如果我扩展行数,它就会崩溃
在这一点上
rettuple = heap_form_tuple( resultTupleDesc, retvals, retnulls);
我猜在值的类型中有一些错误
所以我以numeric::real的形式查询表字段,以float4的形式获取它们,并将它们作为数据输出
我的错误在哪里
非常感谢你的帮助
这是我在StackOverflow的第一篇文章
卢卡
在:
get\u call\u result\u type(fcinfo,&resultTypeId,&resultTupleDesc)
fcinfo
-是什么,从哪里来
fcinfo
是v1调用约定中的PG_FUNCTION_ARGS
的一部分。它是函数调用的上下文,包含各种各样的细节,如参数等。其中大部分由GETARG
宏等在后台处理,但您需要将其传递给助手函数
由于拼写错误等原因,问题的其余部分很难理解。我猜您想用C编写一个函数,将两个值相加并返回结果?如果是这样,在复合类型中作为两个字段返回就没有多大意义了。请显示相关的CREATE TYPE
语句、用于定义函数的CREATE或REPLACE FUNCTION
声明,并解释您试图执行的操作以及原因
(如果您编辑了您的问题,请在回复此答案时发表评论,否则我就不知道您是否编辑了。)PostgreSQL版本?请显示完整的可编译C文件。我使用的PostgreSQL在linux上是9.3。看起来您将问题确定为函数签名与声明不匹配。我很高兴。如果您有后续问题,请发布新问题。链接回这个上下文。包括你想做什么的解释,而不仅仅是你的问题。非常感谢Craig,我已经改进了这个问题。
rettuple = heap_form_tuple( resultTupleDesc, retvals, retnulls);