Agrégats avec arguments

Alors que je jouais avec PostgreSQL 9.0, j'ai cherché à obtenir le comportement de l’agrégat string_agg ( second argument pour définir le séparateur ), mais dans les versions 8.3 et 8.4

Je connaissais la technique, grâce entre autre aux explications de Stéphane Bortzmeyer, mais je ne savais pas comment passer le séparateur. J'ai donc posé la question sur le canal IRC dédié à PostgreSQL ( irc.freenode.net#postgresql ), et en quelques minutes, j'ai eu l'explication de la part d'Andrew « RhodiumToad » Gierth.

Il s'agissait d'utiliser une syntaxe que je connaissais pas, qui consiste à passer les types de données de l'agrégat avant sa définition :

CREATE OR REPLACE FUNCTION string_concat(text, text, text)
RETURNS text 
 LANGUAGE SQL
AS $$
    SELECT CASE WHEN $1 IS NULL OR $1 = '' THEN $2
                WHEN $2 IS NULL OR $2 = '' THEN $1
                ELSE $1 || coalesce($3, '' ) || $2
                END; 
 $$ ;

CREATE AGGREGATE string_agg( text, text )  (
    SFUNC = string_concat,
    STYPE = text
);

L'utilisation est ensuite la même que pour l'agrégat de la version 9.0 :

 > select string_agg(relname,', ') from ( select relname from pg_class where relkind='r' order by relpages desc limit 5 ) x  ; 
string_agg     
----------
 pg_proc, pg_depend, pg_attribute, pg_description, pg_operator
(1 row)

> select string_agg(relname,' / ') from ( select relname from pg_class where relkind='r' order by relpages desc limit 5 ) x  ; 
string_agg                             
----------
 pg_proc / pg_depend / pg_attribute / pg_description / pg_operator
(1 row)

Haut de page