CREATE OR REPLACE FUNCTION count_distinct_elements_append(internal, anyarray) RETURNS internal AS 'count_distinct', 'count_distinct_elements_append' LANGUAGE C IMMUTABLE; CREATE OR REPLACE FUNCTION array_agg_distinct(internal, anynonarray) RETURNS anyarray AS 'count_distinct', 'array_agg_distinct_type_by_element' LANGUAGE C IMMUTABLE; CREATE OR REPLACE FUNCTION array_agg_distinct(internal, anyarray) RETURNS anyarray AS 'count_distinct', 'array_agg_distinct_type_by_array' LANGUAGE C IMMUTABLE; DO $$ BEGIN IF ( SELECT TRUE FROM pg_attribute WHERE attrelid = 'pg_catalog.pg_aggregate'::regclass AND attname = 'aggcombinefn' ) THEN DROP AGGREGATE count_distinct(anyelement); /* Server supports parallel aggregation (9.6+) */ /* serialize data */ CREATE OR REPLACE FUNCTION count_distinct_serial(p_pointer internal) RETURNS bytea AS 'count_distinct', 'count_distinct_serial' LANGUAGE C IMMUTABLE STRICT; /* deserialize data */ CREATE OR REPLACE FUNCTION count_distinct_deserial(p_value bytea, p_dummy internal) RETURNS internal AS 'count_distinct', 'count_distinct_deserial' LANGUAGE C IMMUTABLE STRICT; /* combine data */ CREATE OR REPLACE FUNCTION count_distinct_combine(p_state_1 internal, p_state_2 internal) RETURNS internal AS 'count_distinct', 'count_distinct_combine' LANGUAGE C IMMUTABLE; /* Create the aggregate functions */ CREATE AGGREGATE count_distinct(anyelement) ( SFUNC = count_distinct_append, STYPE = internal, FINALFUNC = count_distinct, COMBINEFUNC = count_distinct_combine, SERIALFUNC = count_distinct_serial, DESERIALFUNC = count_distinct_deserial, PARALLEL = SAFE ); CREATE AGGREGATE array_agg_distinct(anynonarray) ( SFUNC = count_distinct_append, STYPE = internal, FINALFUNC = array_agg_distinct, FINALFUNC_EXTRA, COMBINEFUNC = count_distinct_combine, SERIALFUNC = count_distinct_serial, DESERIALFUNC = count_distinct_deserial, PARALLEL = SAFE ); CREATE AGGREGATE count_distinct_elements(anyarray) ( SFUNC = count_distinct_elements_append, STYPE = internal, FINALFUNC = count_distinct, COMBINEFUNC = count_distinct_combine, SERIALFUNC = count_distinct_serial, DESERIALFUNC = count_distinct_deserial, PARALLEL = SAFE ); CREATE AGGREGATE array_agg_distinct_elements(anyarray) ( SFUNC = count_distinct_elements_append, STYPE = internal, FINALFUNC = array_agg_distinct, FINALFUNC_EXTRA, COMBINEFUNC = count_distinct_combine, SERIALFUNC = count_distinct_serial, DESERIALFUNC = count_distinct_deserial, PARALLEL = SAFE ); ELSE /* Server does not support parallel aggregation (pre-9.6) */ /* Create the aggregate function */ CREATE AGGREGATE array_agg_distinct(anynonarray) ( SFUNC = count_distinct_append, STYPE = internal, FINALFUNC = array_agg_distinct, FINALFUNC_EXTRA ); CREATE AGGREGATE count_distinct_elements(anyarray) ( SFUNC = count_distinct_elements_append, STYPE = internal, FINALFUNC = count_distinct ); CREATE AGGREGATE array_agg_distinct_elements(anyarray) ( SFUNC = count_distinct_elements_append, STYPE = internal, FINALFUNC = array_agg_distinct, FINALFUNC_EXTRA ); END IF; END; $$;