# HG changeset patch # User Sylvain Thénault # Date 1253103379 -7200 # Node ID 988a72e59b2bf2c7391a01286a2abca429c6781c # Parent ee2253f9fbe68911578ef9d668f9894c0ce7fe3c [querier] fix sql generated w/ NOT relation and shared variable: ensure variable's table is in parent select'scope diff -r ee2253f9fbe6 -r 988a72e59b2b server/sources/rql2sql.py --- a/server/sources/rql2sql.py Tue Sep 15 19:04:09 2009 +0200 +++ b/server/sources/rql2sql.py Wed Sep 16 14:16:19 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 @@ -1080,12 +1085,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: @@ -1146,8 +1155,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) diff -r ee2253f9fbe6 -r 988a72e59b2b server/test/unittest_rql2sql.py --- a/server/test/unittest_rql2sql.py Tue Sep 15 19:04:09 2009 +0200 +++ b/server/test/unittest_rql2sql.py Wed Sep 16 14:16:19 2009 +0200 @@ -642,6 +642,13 @@ WHERE X.cw_in_state=S.cw_eid ORDER BY 2) AS T1'''), + ('Any O,AA,AB,AC ORDERBY AC DESC ' + 'WHERE NOT S use_email O, S eid 1, O is EmailAddress, O address AA, O alias AB, O modification_date AC, ' + 'EXISTS(A use_email O, EXISTS(A identity B, NOT B in_group D, D name "guests", D is CWGroup), A is CWUser), B eid 2', + '''SELECT O.cw_eid, O.cw_address, O.cw_alias, O.cw_modification_date +FROM cw_EmailAddress AS O +WHERE NOT EXISTS(SELECT 1 FROM use_email_relation AS rel_use_email0 WHERE rel_use_email0.eid_from=1 AND rel_use_email0.eid_to=O.cw_eid) AND EXISTS(SELECT 1 FROM use_email_relation AS rel_use_email1 WHERE rel_use_email1.eid_to=O.cw_eid AND EXISTS(SELECT 1 FROM cw_CWGroup AS D WHERE rel_use_email1.eid_from=2 AND NOT EXISTS(SELECT 1 FROM in_group_relation AS rel_in_group2 WHERE rel_in_group2.eid_from=2 AND rel_in_group2.eid_to=D.cw_eid) AND D.cw_name=guests)) +ORDER BY 4 DESC'''), ] MULTIPLE_SEL = [