Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1WKdfp-0000em-Fy for pgsql-sql@arkaria.postgresql.org; Tue, 04 Mar 2014 00:57:33 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.80) (envelope-from ) id 1WKdfo-0007AT-TE for pgsql-sql@arkaria.postgresql.org; Tue, 04 Mar 2014 00:57:32 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1WKdfn-00078r-7D for pgsql-sql@postgresql.org; Tue, 04 Mar 2014 00:57:31 +0000 Received: from plane.gmane.org ([80.91.229.3]) by magus.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1WKdfl-000423-Eo for pgsql-sql@postgresql.org; Tue, 04 Mar 2014 00:57:30 +0000 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1WKdfk-0001zT-RG for pgsql-sql@postgresql.org; Tue, 04 Mar 2014 01:57:28 +0100 Received: from net82.ceos.umanitoba.ca ([130.179.67.82]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 04 Mar 2014 01:57:28 +0100 Received: from spluque by net82.ceos.umanitoba.ca with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 04 Mar 2014 01:57:28 +0100 X-Injected-Via-Gmane: http://gmane.org/ To: pgsql-sql@postgresql.org From: Sebastian P. Luque Subject: Re: creating a new aggregate function Date: Mon, 03 Mar 2014 18:57:17 -0600 Organization: Church of Emacs Lines: 79 Message-ID: <87ha7eu6fm.fsf@net82.ceos.umanitoba.ca> References: <87iorvurrd.fsf@net82.ceos.umanitoba.ca> <1393868159887-5794419.post@n5.nabble.com> <87wqgbt3kf.fsf@net82.ceos.umanitoba.ca> <1393881121206-5794448.post@n5.nabble.com> <87lhwqu8q6.fsf@net82.ceos.umanitoba.ca> <20952.1393892275@sss.pgh.pa.us> Mime-Version: 1.0 Content-Type: text/plain X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: net82.ceos.umanitoba.ca User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:7agvttAJybsfrX5PZ6pdBPzDup0= X-Pg-Spam-Score: -1.0 (-) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-sql Precedence: bulk Sender: pgsql-sql-owner@postgresql.org On Mon, 03 Mar 2014 19:17:55 -0500, Tom Lane wrote: > Seb 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$ BEGIN RETURN 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$ DECLARE xyrows angle_vector; x_avg numeric; y_avg numeric; magnitude numeric; angle_avg numeric; BEGIN xyrows := 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 -- Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-sql