[rql2sql] test and fix crash when OR in HAVING where both expresion are 'fake' having terms (eg not using aggregat function) stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 05 Jul 2010 17:55:37 +0200
branchstable
changeset 5887 3f55f0f10a22
parent 5886 00a78298d30d
child 5888 3ee80d487f11
[rql2sql] test and fix crash when OR in HAVING where both expresion are 'fake' having terms (eg not using aggregat function)
server/sources/rql2sql.py
server/test/unittest_rql2sql.py
--- a/server/sources/rql2sql.py	Mon Jul 05 17:06:11 2010 +0200
+++ b/server/sources/rql2sql.py	Mon Jul 05 17:55:37 2010 +0200
@@ -428,16 +428,15 @@
             p = compnode.parent
             oor = None
             while not isinstance(p, Select):
-                if p in ors:
+                if p in ors or p is None: # p is None for nodes already in fakehaving
                     break
                 if isinstance(p, Or):
                     oor = p
                 p = p.parent
             else:
                 node = oor or compnode
-                if not node in fakehaving:
-                    fakehaving.append(node)
-                    compnode.parent.remove(node)
+                fakehaving.append(node)
+                node.parent.remove(node)
     return fakehaving
 
 class SQLGenerator(object):
--- a/server/test/unittest_rql2sql.py	Mon Jul 05 17:06:11 2010 +0200
+++ b/server/test/unittest_rql2sql.py	Mon Jul 05 17:55:37 2010 +0200
@@ -1430,6 +1430,12 @@
                     '''SELECT (A || _X.cw_ref)
 FROM cw_Affaire AS _X''')
 
+    def test_or_having_fake_terms(self):
+        self._check('Any X WHERE X is CWUser, X creation_date D HAVING YEAR(D) = "2010" OR D = NULL',
+                    '''SELECT _X.cw_eid
+FROM cw_CWUser AS _X
+WHERE ((CAST(EXTRACT(YEAR from _X.cw_creation_date) AS INTEGER)=2010) OR (_X.cw_creation_date IS NULL))''')
+
 
 class SqliteSQLGeneratorTC(PostgresSQLGeneratorTC):
 
@@ -1538,6 +1544,13 @@
             yield t
 
 
+    def test_or_having_fake_terms(self):
+        self._check('Any X WHERE X is CWUser, X creation_date D HAVING YEAR(D) = "2010" OR D = NULL',
+                    '''SELECT _X.cw_eid
+FROM cw_CWUser AS _X
+WHERE ((YEAR(_X.cw_creation_date)=2010) OR (_X.cw_creation_date IS NULL))''')
+
+
 
 class MySQLGenerator(PostgresSQLGeneratorTC):
 
@@ -1623,6 +1636,14 @@
                     '''SELECT SUBSTRING(_P.cw_nom, 1, 1)
 FROM cw_Personne AS _P''')
 
+
+    def test_or_having_fake_terms(self):
+        self._check('Any X WHERE X is CWUser, X creation_date D HAVING YEAR(D) = "2010" OR D = NULL',
+                    '''SELECT _X.cw_eid
+FROM cw_CWUser AS _X
+WHERE ((EXTRACT(YEAR from _X.cw_creation_date)=2010) OR (_X.cw_creation_date IS NULL))''')
+
+
 class removeUnsusedSolutionsTC(TestCase):
     def test_invariant_not_varying(self):
         rqlst = mock_object(defined_vars={})