# HG changeset patch # User Sylvain Thénault # Date 1280745324 -7200 # Node ID 20af96a6fffc0b0380010bf7d77d6cfcac3d3ed1 # Parent f0ae98fa85a1d4ec0ba5c52b3317a6b9bc1012fa [rql2sql] add test for rql bug #37423, which triggered a cw bug fixed by this changeset (infinite loop with some queries...) diff -r f0ae98fa85a1 -r 20af96a6fffc server/sources/rql2sql.py --- a/server/sources/rql2sql.py Mon Aug 02 10:09:29 2010 +0200 +++ b/server/sources/rql2sql.py Mon Aug 02 12:35:24 2010 +0200 @@ -101,15 +101,12 @@ subquery. This function check this and rewrite the rql syntax tree if necessary (in place). Return a boolean telling if the tree has been modified """ - torewrite = set() modified = False for varname in tuple(unstable): var = select.defined_vars[varname] if not var.stinfo.get('optrelations'): continue - modified = True unstable.remove(varname) - torewrite.add(var) newselect = Select() newselect.need_distinct = False myunion = Union() @@ -139,10 +136,17 @@ var.stinfo['rhsrelations'].add(newrel) if rel.optional in ('right', 'both'): var.add_optional_relation(newrel) + if not select.where and not modified: + # oops, generated the same thing as the original select.... + # restore original query, else we'll indefinitly loop + for var, rel in towrap_rels: + select.add_restriction(rel) + continue + modified = True # extract subquery solutions mysolutions = [sol.copy() for sol in solutions] cleanup_solutions(newselect, mysolutions) - newselect.set_possible_types(solutions) + newselect.set_possible_types(mysolutions) # full sub-query aliases = [VariableRef(select.get_variable(avar.name, i)) for i, avar in enumerate(newselect.selection)] diff -r f0ae98fa85a1 -r 20af96a6fffc server/test/unittest_querier.py --- a/server/test/unittest_querier.py Mon Aug 02 10:09:29 2010 +0200 +++ b/server/test/unittest_querier.py Mon Aug 02 12:35:24 2010 +0200 @@ -836,7 +836,7 @@ rset = self.execute('Any X, NOW - CD WHERE X is Personne, X creation_date CD') self.failUnlessEqual(rset.description[0][1], 'Interval') - def test_select_subquery_aggregat(self): + def test_select_subquery_aggregat_1(self): # percent users by groups self.execute('SET X in_group G WHERE G name "users"') rset = self.execute('Any GN, COUNT(X)*100/T GROUPBY GN ORDERBY 2,1' @@ -845,6 +845,17 @@ self.assertEquals(rset.rows, [[u'guests', 50], [u'managers', 50], [u'users', 100]]) self.assertEquals(rset.description, [('String', 'Int'), ('String', 'Int'), ('String', 'Int')]) + def test_select_subquery_aggregat_2(self): + expected = self.execute('Any X, 0, COUNT(T) GROUPBY X ' + 'WHERE X is Workflow, T transition_of X').rows + rset = self.execute(''' +Any P1,B,E WHERE P1 identity P2 WITH + P1,B BEING (Any P,COUNT(T) GROUPBY P WHERE P is Workflow, T is Transition, + T? transition_of P, T type "auto"), + P2,E BEING (Any P,COUNT(T) GROUPBY P WHERE P is Workflow, T is Transition, + T? transition_of P, T type "normal")''') + self.assertEquals(sorted(rset.rows), sorted(expected)) + def test_select_subquery_const(self): rset = self.execute('Any X WITH X BEING ((Any NULL) UNION (Any "toto"))') self.assertEquals(rset.rows, [[None], ['toto']])