server/sources/rql2sql.py
branch3.5
changeset 3238 988a72e59b2b
parent 2915 651bbe1526b6
child 3245 7ef021ac8dec
equal deleted inserted replaced
3237:ee2253f9fbe6 3238:988a72e59b2b
   334         self._lock.acquire()
   334         self._lock.acquire()
   335         self._args = args
   335         self._args = args
   336         self._varmap = varmap
   336         self._varmap = varmap
   337         self._query_attrs = {}
   337         self._query_attrs = {}
   338         self._state = None
   338         self._state = None
       
   339         self._not_scope_offset = 0
   339         try:
   340         try:
   340             # union query for each rqlst / solution
   341             # union query for each rqlst / solution
   341             sql = self.union_sql(union)
   342             sql = self.union_sql(union)
   342             # we are done
   343             # we are done
   343             return sql, self._query_attrs
   344             return sql, self._query_attrs
   551             return res[0]
   552             return res[0]
   552         return ''
   553         return ''
   553 
   554 
   554     def visit_not(self, node):
   555     def visit_not(self, node):
   555         self._state.push_scope()
   556         self._state.push_scope()
       
   557         if isinstance(node.children[0], Relation):
       
   558             self._not_scope_offset += 1
   556         csql = node.children[0].accept(self)
   559         csql = node.children[0].accept(self)
       
   560         if isinstance(node.children[0], Relation):
       
   561             self._not_scope_offset -= 1
   557         sqls, tables = self._state.pop_scope()
   562         sqls, tables = self._state.pop_scope()
   558         if node in self._state.done or not csql:
   563         if node in self._state.done or not csql:
   559             # already processed or no sql generated by children
   564             # already processed or no sql generated by children
   560             self._state.actual_tables[-1] += tables
   565             self._state.actual_tables[-1] += tables
   561             self._state.restrictions += sqls
   566             self._state.restrictions += sqls
  1078         # if current var or one of its attribute is selected , it *must*
  1083         # if current var or one of its attribute is selected , it *must*
  1079         # appear in the toplevel's FROM even if we're currently visiting
  1084         # appear in the toplevel's FROM even if we're currently visiting
  1080         # a EXISTS node
  1085         # a EXISTS node
  1081         if var.sqlscope is var.stmt:
  1086         if var.sqlscope is var.stmt:
  1082             scope = 0
  1087             scope = 0
       
  1088         # don't consider not_scope_offset if the variable is only used in one
       
  1089         # relation
       
  1090         elif len(var.stinfo['relations']) > 1:
       
  1091             scope = -1 - self._not_scope_offset
  1083         else:
  1092         else:
  1084             scope = -1
  1093             scope = -1
  1085         try:
  1094         try:
  1086             sql = self._varmap[var.name]
  1095             sql = self._varmap[var.name]
  1087             table = sql.split('.', 1)[0]
  1096             table = sql.split('.', 1)[0]
  1088             if scope == -1:
  1097             if scope < 0:
  1089                 scope = self._varmap_table_scope(var.stmt, table)
  1098                 scope = self._varmap_table_scope(var.stmt, table)
  1090             self.add_table(table, scope=scope)
  1099             self.add_table(table, scope=scope)
  1091         except KeyError:
  1100         except KeyError:
  1092             etype = self._state.solution[var.name]
  1101             etype = self._state.solution[var.name]
  1093             # XXX this check should be moved in rql.stcheck
  1102             # XXX this check should be moved in rql.stcheck
  1144     def add_table(self, table, key=None, scope=-1):
  1153     def add_table(self, table, key=None, scope=-1):
  1145         if key is None:
  1154         if key is None:
  1146             key = table
  1155             key = table
  1147         if key in self._state.tables:
  1156         if key in self._state.tables:
  1148             return
  1157             return
  1149         if scope == -1:
  1158         if scope < 0:
  1150             scope = len(self._state.actual_tables) - 1
  1159             scope = len(self._state.actual_tables) + scope
  1151         self._state.tables[key] = (scope, table)
  1160         self._state.tables[key] = (scope, table)
  1152         self._state.actual_tables[scope].append(table)
  1161         self._state.actual_tables[scope].append(table)
  1153 
  1162 
  1154     def replace_tables_by_outer_join(self, substitute, lefttable, *tables):
  1163     def replace_tables_by_outer_join(self, substitute, lefttable, *tables):
  1155         for table in tables:
  1164         for table in tables: