Make the GROUP_CONCAT aggregate function not repeat values (closes #3223975)
Work on sets instead of arrays, so if the same value appears twice it's
not repeated in the concatenated output.
This patch handles the postgresql and sqlite backends, mysql is left
alone at this point (seems doable, but I don't have time or motivation
to fix and test it).
--- a/schemas/_regproc.postgres.sql Tue Jan 07 15:48:31 2014 +0100
+++ b/schemas/_regproc.postgres.sql Thu Nov 14 12:26:29 2013 +0100
@@ -10,10 +10,15 @@
SELECT array_to_string($1, ', ')
$$ LANGUAGE SQL;;
+
+CREATE FUNCTION cw_array_append_unique (anyarray, anyelement) RETURNS anyarray AS $$
+ SELECT array_append($1, (SELECT $2 WHERE $2 <> ALL($1)))
+$$ LANGUAGE SQL
+
DROP AGGREGATE IF EXISTS group_concat (anyelement) CASCADE;
CREATE AGGREGATE group_concat (
basetype = anyelement,
- sfunc = array_append,
+ sfunc = cw_array_append_unique,
stype = anyarray,
finalfunc = comma_join,
initcond = '{}'
--- a/server/sqlutils.py Tue Jan 07 15:48:31 2014 +0100
+++ b/server/sqlutils.py Thu Nov 14 12:26:29 2013 +0100
@@ -327,10 +327,10 @@
class group_concat(object):
def __init__(self):
- self.values = []
+ self.values = set()
def step(self, value):
if value is not None:
- self.values.append(value)
+ self.values.add(value)
def finalize(self):
return ', '.join(unicode(v) for v in self.values)