# HG changeset patch # User David Douard # Date 1507814520 -7200 # Node ID 23bc9f3856458aaa76c3fc11c6d9ba628bb19786 # Parent e36f2c862d5c26ab0376da7e2757cf14a5113222 [rql2sql] fix handling of the ORDERBY clause when the aggregation function is "embedded" ie. a situation like: Any X GROUPBY X ORDERBY COUNT(Y) WHERE ... works fine since the aggregation function (COUNT) if the first one, whereas a situation like the proposed test: Any X GROUPBY X ORDERBY ABS(COUNT(Y)) WHERE ... failed due to the fact we only checked the top aggratation function (ABS). Closes #17108671 diff -r e36f2c862d5c -r 23bc9f385645 cubicweb/server/sources/rql2sql.py --- a/cubicweb/server/sources/rql2sql.py Mon Apr 23 15:19:19 2018 +0200 +++ b/cubicweb/server/sources/rql2sql.py Thu Oct 12 15:22:00 2017 +0200 @@ -279,6 +279,14 @@ groups.append(vref) +def is_in_aggregat(node): + while node: + node = node.parent + if isinstance(node, Function) and node.descr().aggregat: + return True + return False + + def fix_selection_and_group(rqlst, needwrap, selectsortterms, sorts, groups, having): if selectsortterms and sorts: @@ -288,13 +296,11 @@ # when a query is grouped, ensure sort terms are grouped as well for sortterm in sorts: term = sortterm.term - if not (isinstance(term, Constant) or - (isinstance(term, Function) and - get_func_descr(term.name).aggregat)): - for vref in term.iget_nodes(VariableRef): - if not any(vref.is_equivalent(group) for group in groupvrefs): - groups.append(vref) - groupvrefs.append(vref) + for vref in term.iget_nodes(VariableRef): + if not (any(vref.is_equivalent(group) for group in groupvrefs) + or is_in_aggregat(vref)): + groups.append(vref) + groupvrefs.append(vref) if needwrap and (groups or having): selectedidx = set(vref.name for term in rqlst.selection for vref in term.get_nodes(VariableRef)) diff -r e36f2c862d5c -r 23bc9f385645 cubicweb/server/test/unittest_rql2sql.py --- a/cubicweb/server/test/unittest_rql2sql.py Mon Apr 23 15:19:19 2018 +0200 +++ b/cubicweb/server/test/unittest_rql2sql.py Thu Oct 12 15:22:00 2017 +0200 @@ -1437,6 +1437,16 @@ WHERE _X.cw_login ~ [0-9].* ''') + def test_aggregate_in_orderby(self): + self._check("Any X GROUPBY X ORDERBY ABS(COUNT(Y)) WHERE" + "X is CWGROUP, Y is CWUSER, Y in_group X", + '''SELECT rel_in_group1.eid_to +FROM in_group_relation AS rel_in_group1, is_relation AS rel_is0, is_relation AS rel_is2 +WHERE rel_in_group1.eid_to=rel_is0.eid_from AND rel_in_group1.eid_from=rel_is2.eid_from +GROUP BY rel_in_group1.eid_to +ORDER BY ABS(COUNT(rel_in_group1.eid_from)) +''') + def test_parser_parse(self): for rql, sql in PARSER: with self.subTest(rql=rql):