fix sql generation bug with neged inlined relation where the object is invariant and subject is only referenced by the relation stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 03 Dec 2009 12:44:30 +0100
branchstable
changeset 3987 f85ef29f6214
parent 3986 cc29eddf51ad
child 3988 833cfe0fcf5f
fix sql generation bug with neged inlined relation where the object is invariant and subject is only referenced by the relation
server/sources/rql2sql.py
server/test/unittest_rql2sql.py
--- a/server/sources/rql2sql.py	Thu Dec 03 11:39:31 2009 +0100
+++ b/server/sources/rql2sql.py	Thu Dec 03 12:44:30 2009 +0100
@@ -693,7 +693,7 @@
         lhsvar, _, rhsvar, rhsconst = relation_info(relation)
         # we are sure here to have a lhsvar
         assert lhsvar is not None
-        if isinstance(relation.parent, Not):
+        if isinstance(relation.parent, Not) and len(lhsvar.stinfo['relations']) > 1:
             self._state.done.add(relation.parent)
             if rhsvar is not None and not rhsvar._q_invariant:
                 # if the lhs variable is only linked to this relation, this mean we
--- a/server/test/unittest_rql2sql.py	Thu Dec 03 11:39:31 2009 +0100
+++ b/server/test/unittest_rql2sql.py	Thu Dec 03 12:44:30 2009 +0100
@@ -1043,7 +1043,12 @@
 UNION ALL
 SELECT _S.cw_in_state
 FROM cw_Note AS _S
-WHERE _S.cw_eid=0 AND _S.cw_in_state IS NOT NULL''')
+WHERE _S.cw_eid=0 AND _S.cw_in_state IS NOT NULL'''),
+
+    ('Any X WHERE NOT Y for_user X, X eid 123',
+     '''SELECT 123
+WHERE NOT EXISTS(SELECT 1 FROM cw_CWProperty AS _Y WHERE _Y.cw_for_user=123)
+'''),
 
     ]
 
@@ -1552,7 +1557,16 @@
         self.o = SQLGenerator(schema, dbms_helper)
 
     def _norm_sql(self, sql):
-        return sql.strip().replace(' ILIKE ', ' LIKE ').replace('TRUE', '1').replace('FALSE', '0')
+        sql = sql.strip().replace(' ILIKE ', ' LIKE ').replace('TRUE', '1').replace('FALSE', '0')
+        newsql = []
+        latest = None
+        for line in sql.splitlines(False):
+            firstword = line.split(None, 1)[0]
+            if firstword == 'WHERE' and latest == 'SELECT':
+                newsql.append('FROM (SELECT 1) AS _T')
+            newsql.append(line)
+            latest = firstword
+        return '\n'.join(newsql)
 
     def test_from_clause_needed(self):
         queries = [("Any 1 WHERE EXISTS(T is CWGroup, T name 'managers')",