When concatenating column fields in order to perform aggregation on
them (e.g. group concatenation), we need to preserve all null values
in the data passed to each column callback.
Co-authored-by: Carlos Castillo <carlos.castillo@moodle.com>
When using the "Count distinct" aggregation type on a column that
selects multiple fields, we should account for each of them in the
returned SQL.
Move helper method to facilitate this to the base aggregation class
so it can be re-used between all types.
This change overcomes limitations in certain DB engines (such as
MySQL[1]) which can lead to truncation of data when applying group
concatenation to columns.
Ensure we account for that by validating that we are able to extract
the expected number of fields from each concatenated value.
[1] https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_group_concat_max_len
Use delimeters that are less likely to conflict with genuine row
content, for both column fields and field values, in the group
concatenation aggregation methods.
The group concatenation types now consistently sort the returned values
and support aggregating columns containing multiple fields and those
with defined callbacks.