server/sources/rql2sql.py
branchstable
changeset 3315 59220b704562
parent 3245 7ef021ac8dec
child 3689 deb13e88e037
--- a/server/sources/rql2sql.py	Thu Sep 17 19:38:04 2009 +0200
+++ b/server/sources/rql2sql.py	Fri Sep 18 11:24:37 2009 +0200
@@ -336,6 +336,7 @@
         self._varmap = varmap
         self._query_attrs = {}
         self._state = None
+        self._not_scope_offset = 0
         try:
             # union query for each rqlst / solution
             sql = self.union_sql(union)
@@ -553,7 +554,11 @@
 
     def visit_not(self, node):
         self._state.push_scope()
+        if isinstance(node.children[0], Relation):
+            self._not_scope_offset += 1
         csql = node.children[0].accept(self)
+        if isinstance(node.children[0], Relation):
+            self._not_scope_offset -= 1
         sqls, tables = self._state.pop_scope()
         if node in self._state.done or not csql:
             # already processed or no sql generated by children
@@ -651,10 +656,6 @@
                 sql = self._visit_outer_join_relation(relation, rschema)
             elif rschema.inlined:
                 sql = self._visit_inlined_relation(relation)
-#             elif isinstance(relation.parent, Not):
-#                 self._state.done.add(relation.parent)
-#                 # NOT relation
-#                 sql = self._visit_not_relation(relation, rschema)
             else:
                 # regular (non final) relation
                 sql = self._visit_relation(relation, rschema)
@@ -1080,12 +1081,16 @@
         # a EXISTS node
         if var.sqlscope is var.stmt:
             scope = 0
+        # don't consider not_scope_offset if the variable is only used in one
+        # relation
+        elif len(var.stinfo['relations']) > 1:
+            scope = -1 - self._not_scope_offset
         else:
             scope = -1
         try:
             sql = self._varmap[var.name]
             table = sql.split('.', 1)[0]
-            if scope == -1:
+            if scope < 0:
                 scope = self._varmap_table_scope(var.stmt, table)
             self.add_table(table, scope=scope)
         except KeyError:
@@ -1095,7 +1100,8 @@
                 raise BadRQLQuery(var.stmt.root)
             table = var.name
             sql = '%s.%seid' % (table, SQL_PREFIX)
-            self.add_table('%s%s AS %s' % (SQL_PREFIX, etype, table), table, scope=scope)
+            self.add_table('%s%s AS %s' % (SQL_PREFIX, etype, table), table,
+                           scope=scope)
         return sql, table
 
     def _inlined_var_sql(self, var, rtype):
@@ -1146,8 +1152,8 @@
             key = table
         if key in self._state.tables:
             return
-        if scope == -1:
-            scope = len(self._state.actual_tables) - 1
+        if scope < 0:
+            scope = len(self._state.actual_tables) + scope
         self._state.tables[key] = (scope, table)
         self._state.actual_tables[scope].append(table)