equal
deleted
inserted
replaced
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: |