[rql] fix bug with query like 'Any 1 WHERE NOT X in_group G': tables should be kept in EXISTS() even when there are no restriction stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 22 Sep 2010 10:35:34 +0200
branchstable
changeset 6297 23c1e50ff97b
parent 6296 b7484ae2c693
child 6298 f4347f796908
[rql] fix bug with query like 'Any 1 WHERE NOT X in_group G': tables should be kept in EXISTS() even when there are no restriction
server/rqlannotation.py
server/sources/native.py
server/sources/rql2sql.py
server/test/unittest_rql2sql.py
--- a/server/rqlannotation.py	Wed Sep 22 10:34:20 2010 +0200
+++ b/server/rqlannotation.py	Wed Sep 22 10:35:34 2010 +0200
@@ -17,8 +17,8 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """Functions to add additional annotations on a rql syntax tree to ease later
 code generation.
+"""
 
-"""
 __docformat__ = "restructuredtext en"
 
 from logilab.common.compat import any
--- a/server/sources/native.py	Wed Sep 22 10:34:20 2010 +0200
+++ b/server/sources/native.py	Wed Sep 22 10:35:34 2010 +0200
@@ -675,7 +675,7 @@
                         index_name = mo.group(0)
                         elements = index_name.rstrip('_idx').split('_cw_')[1:]
                         etype = elements[0]
-                        rtypes = elements[1:]                        
+                        rtypes = elements[1:]
                         raise UniqueTogetherError(etype, rtypes)
                     mo = re.search('columns (.*) are not unique', arg)
                     if mo is not None: # sqlite in use
@@ -867,7 +867,6 @@
             cnx.commit()
             return eid
 
-
     def add_info(self, session, entity, source, extid, complete):
         """add type and source info for an eid into the system table"""
         # begin by inserting eid/type/source/extid into the entities table
--- a/server/sources/rql2sql.py	Wed Sep 22 10:34:20 2010 +0200
+++ b/server/sources/rql2sql.py	Wed Sep 22 10:35:34 2010 +0200
@@ -761,6 +761,8 @@
             restrictions.append(restriction)
         restriction = ' AND '.join(restrictions)
         if not restriction:
+            if tables:
+                return 'SELECT 1 FROM %s' % ', '.join(tables)
             return ''
         if not tables:
             # XXX could leave surrounding EXISTS() in this case no?
--- a/server/test/unittest_rql2sql.py	Wed Sep 22 10:34:20 2010 +0200
+++ b/server/test/unittest_rql2sql.py	Wed Sep 22 10:35:34 2010 +0200
@@ -567,6 +567,11 @@
 GROUP BY T1.C0,T1.C2
 ORDER BY T1.C2'''),
 
+    ('Any 1 WHERE X in_group G, X is CWUser',
+     '''SELECT 1
+FROM in_group_relation AS rel_in_group0'''),
+
+
     ]
 
 
@@ -1466,6 +1471,15 @@
 FROM cw_CWUser AS _X
 WHERE ((CAST(EXTRACT(YEAR from _X.cw_creation_date) AS INTEGER)=2010) OR (_X.cw_creation_date IS NULL))''')
 
+    def test_not_no_where(self):
+        # XXX will check if some in_group relation exists, that's it.
+        # We  can't actually know if we want to check if there are some
+        # X without in_group relation, or some G without it.
+        self._check('Any 1 WHERE NOT X in_group G, X is CWUser',
+                    '''SELECT 1
+WHERE NOT (EXISTS(SELECT 1 FROM in_group_relation AS rel_in_group0))''')
+
+
 
 class SqliteSQLGeneratorTC(PostgresSQLGeneratorTC):
     backend = 'sqlite'
@@ -1686,6 +1700,13 @@
 WHERE ((EXTRACT(YEAR from _X.cw_creation_date)=2010) OR (_X.cw_creation_date IS NULL))''')
 
 
+    def test_not_no_where(self):
+        self._check('Any 1 WHERE NOT X in_group G, X is CWUser',
+                    '''SELECT 1
+FROM (SELECT 1) AS _T
+WHERE NOT (EXISTS(SELECT 1 FROM in_group_relation AS rel_in_group0))''')
+
+
 class removeUnsusedSolutionsTC(TestCase):
     def test_invariant_not_varying(self):
         rqlst = mock_object(defined_vars={})