Re: creating a new aggregate function

Поиск
Список
Период
Сортировка
От Sebastian P. Luque
Тема Re: creating a new aggregate function
Дата
Msg-id 87ha7eu6fm.fsf@net82.ceos.umanitoba.ca
обсуждение исходный текст
Ответ на creating a new aggregate function  (Seb <spluque@gmail.com>)
Список pgsql-sql
On Mon, 03 Mar 2014 19:17:55 -0500,
Tom Lane <tgl@sss.pgh.pa.us> wrote:

> Seb <spluque@gmail.com> writes:
>> Thanks for that suggestion.  It seemed as if array_agg would allow me
>> to define a new aggregate for avg as follows:

>> CREATE AGGREGATE avg (angle_vector) ( sfunc=array_agg,
>> stype=anyarray, finalfunc=angle_vector_avg );

> That's not going to work, for exactly this reason:

>> ERROR: cannot determine transition data type DETAIL: An aggregate
>> using a polymorphic transition type must have at least one
>> polymorphic argument.

> I see no reason to use a polymorphic type here anyway ... why not just
> declare the transition data type as angle_vector[] ?

OK, then it seems as if I must create custom sfunc *and* finalfunc:

-- sfunc
CREATE OR REPLACE FUNCTION angle_vector_accum(angle_vectors angle_vector[], angle_vector angle_vector) RETURNS
angle_vector[]AS
 
$BODY$
BEGINRETURN array_append(angle_vectors, angle_vector)::angle_vector[];
END
$BODY$ LANGUAGE plpgsql STABLE;

-- finalfunc
CREATE OR REPLACE FUNCTION angle_vector_avg(angle_vector_arr angle_vector[]) RETURNS record AS
$BODY$
DECLARExyrows angle_vector;x_avg numeric;y_avg numeric;magnitude numeric;angle_avg numeric;

BEGINxyrows := unnest(angle_vector_arr);x_avg := avg(xyrows.x);y_avg := avg(xyrows.y);magnitude := sqrt((x_avg ^ 2.0) +
(y_avg^ 2.0));angle_avg := degrees(atan2(x_avg, y_avg));IF (angle_avg < 0.0) THEN    angle_avg := angle_avg + 360;END
IF;RETURN(angle_avg, magnitude);
 
END
$BODY$ LANGUAGE plpgsql STABLE;

CREATE AGGREGATE avg (angle_vector)
(sfunc=angle_vector_accum,stype=angle_vector[],finalfunc=angle_vector_avg
);

But calling the aggregate with this statement:

SELECT avg(decompose_angle(angle, magnitude))
FROM (VALUES (10, 1), (350, 2), (200, 3)) AS a (angle, magnitude);

fails with:

ERROR:  query "SELECT unnest(angle_vector_arr)" returned more than one row
CONTEXT:  PL/pgSQL function angle_vector_avg(angle_vector[]) line 10 at assignment

But looks like I'm getting close!

Thanks,

-- 
Seb




В списке pgsql-sql по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: Re: creating a new aggregate function
Следующее
От: ALMA TAHIR
Дата:
Сообщение: Re: pgsql-sq-owner