2017-08-24 52 views
1

我正在使用C語言創建PostgreSQL的擴展。AGGREGATE中的最終函數不能在PostgreSQL中運行

我實現了一個聚合函數,以返回一個有序的時間戳數組。

time_to_array函數負責將表列的所有時間戳元素添加到數組中。

time_to_array_final函數接收時間戳數組並進行排序。

以下是SQL定義:

CREATE OR REPLACE FUNCTION time_to_array(timestamp[], timestamp) 
    RETURNS timestamp[] 
    AS 'MODULE_PATHNAME','time_to_array' 
    LANGUAGE C IMMUTABLE; 

CREATE OR REPLACE FUNCTION time_to_array_final(timestamp[]) 
    RETURNS timestamp[] 
    AS 'MODULE_PATHNAME', 'time_to_array_final' 
    LANGUAGE C IMMUTABLE; 

CREATE AGGREGATE array_time_agg(timestamp) 
(
    SFUNC = time_to_array, 
    STYPE = timestamp[], 
    FINALFUNC = time_to_array_final 
); 

SELECT array_time_agg(column) FROM table; 

ELOG(): NOTA:time_to_array CALL(5次)

結果: array_time_agg | {「2016-06-01 00:00:00」,「2016-06-02 00:00:00」,「2016-06-05 00:00:00」,「2016-06-03 00:00: 00「,」2016-07-03 00:00:00「}

我正在使用elog分析代碼中發生了什麼。

執行select時,可以看到每次都會正確調用time_to_array函數。

但是time_to_array_final函數沒有。 日誌管理系統()是在函數的開始,表明同樣是不叫:

PG_FUNCTION_INFO_V1(time_to_array_final); 

Datum 
time_to_array_final(PG_FUNCTION_ARGS) 
{ 
    elog(NOTICE, "time_to_array_final"); 

    ArrayType *array_time; 
    ArrayType *array_time_result; 

    /* variables for "deconstructed" array*/ 
    Datum *datums_time; 
    bool *nulls_time; 
    int count_time; 
    int16 typlen; 
    bool typbyval; 
    char typalign; 

    array_time = PG_GETARG_ARRAYTYPE_P(0); 

    /*values found in table pg_type*/ 
    get_typlenbyvalalign(TIMESTAMPOID, &typlen, &typbyval, &typalign); 

    deconstruct_array(array_time, TIMESTAMPOID, typlen, typbyval, typalign , &datums_time, &nulls_time, &count_time); 

    quick_sort(datums_time, 0, count_time - 1); 

    array_time_result = construct_array(datums_time, 1, TIMESTAMPOID, typlen, typbyval, typalign); 

    PG_RETURN_ARRAYTYPE_P(array_time_result); 
} 

上午我路過一些錯誤的參數?

我還需要什麼來創建聚合函數嗎?我讀過initcond並不是必需的,函數假定它是null。

在此先感謝

回答

1

你的DDL語句是正確的,一定是有什麼在你的C函數。韋迪:

create or replace function time_to_array(timestamp[], timestamp) 
returns timestamp[] language sql as $$ 
    select $1 || $2 
$$; 

create or replace function time_to_array_final(timestamp[]) 
returns timestamp[] language sql as $$ 
    select array_agg(elem order by elem) 
    from unnest($1) as elem; 
$$; 

create aggregate array_time_agg(timestamp) 
(
    sfunc = time_to_array, 
    stype = timestamp[], 
    finalfunc = time_to_array_final 
); 

with my_table(tstamp) as (
values 
    ('2017-08-20'::timestamp), 
    ('2017-08-19'), 
    ('2017-08-22'), 
    ('2017-08-21') 
) 
select array_time_agg(tstamp) 
from my_table; 

             array_time_agg          
------------------------------------------------------------------------------------------- 
{"2017-08-19 00:00:00","2017-08-20 00:00:00","2017-08-21 00:00:00","2017-08-22 00:00:00"} 
(1 row) 

我編譯你的函數(不包括快速排序()),它似乎有一個小錯誤:

array_time_result = construct_array(datums_time, count_time, TIMESTAMPOID, typlen, typbyval, typalign); 
//            | was 1 

無論如何,它在我的總的效果非常不錯最終功能(沒有排序)。

+0

謝謝你的回答! 但由於我的C函數(time_to_array)正在返回一個數組,錯誤可能是在time_to_array_final函數中,或者不一定? –

+0

我這麼認爲,所有跡象都表明C函數'time_to_array_final'有問題。 – klin

+0

我編輯了帖子..我會看看C –

相關問題