2013-11-09 58 views
2

我是新的postgresql c函數,我開始下面的例子。Postgresql c函數返回一行2個文件

我想寫一個簡單的函數,它內部包含一個SQL並接收參數evaluete,並將兩個字段分別作爲2列的總和返回(現在更簡單)。

下面的功能問題,檢查通過

(get_call_result_type(fcinfo, &resultTypeId, &resultTupleDesc) != TYPEFUNC_COMPOSITE) 

如果我刪除此行中我得到1個整數結果從該查詢

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

} 

創建功能:

CREATE FUNCTION pdc_imuanno(integer) 
RETURNS float 
AS 'pdc','test_query' 
LANGUAGE C STABLE STRICT; 
ALTER FUNCTION pdc_imuanno(integer) OWNER TO www; 

查詢:

select * from pdc_imuanno(2012); 

好吧,我找到簡單的和愚蠢的錯誤 我創建函數retunrning 1場,我希望看到迴歸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輸出,並將它們輸出爲datum。

我的錯誤在哪裏?

非常感謝您的幫助。

這在我的第一篇文章在StackOverflow。

盧卡

+0

PostgreSQL的版本?請顯示完整的可編譯C文件。 –

+0

我使用的PostgreSQL在Linux上是9.3。 –

+0

看起來您將問題確定爲函數簽名與聲明不匹配。我很高興。如果您有後續問題,請發佈新問題。鏈接回到這個上下文。包括你想要做什麼的解釋,而不僅僅是你的問題。 –

回答

1

在:

get_call_result_type(fcinfo, &resultTypeId, &resultTupleDesc)

fcinfo - 什麼是哪裏來的呢?

fcinfo是v1調用約定中PG_FUNCTION_ARGS的一部分。這是函數調用的上下文,並且包含各種細節,如參數等。這些內容大部分都是在後臺由宏等處理,但您需要將它傳遞給輔助函數。

由於錯別字等問題的其餘部分很難理解我是猜測你想寫一個函數在C中添加兩個值在一起並返回結果嗎?如果是這樣,那麼在複合類型中返回兩個字段沒有什麼意義。請顯示相關CREATE TYPE聲明,您用來定義函數的CREATE OR REPLACE FUNCTION聲明,並解釋您正在嘗試執行的操作以及原因。

(如果您編輯您的問題,發表回覆評論這個答案,否則否則我不知道你編輯。)

+0

非常感謝克雷格,我改進了問題。 –