# HG changeset patch # User Sylvain Thénault # Date 1272385902 -7200 # Node ID 09b50d7e532131fe88f4cd54861f7e9c72115a57 # Parent 0b7805928a27337d1b515b9785aedceb944069c7 [ms] fix planning bug with rewritten constants: when removing some source for a const due to relation constraints, we should propagate this change to other constants coming from the same original variable diff -r 0b7805928a27 -r 09b50d7e5321 server/msplanner.py --- a/server/msplanner.py Tue Apr 27 18:27:43 2010 +0200 +++ b/server/msplanner.py Tue Apr 27 18:31:42 2010 +0200 @@ -350,8 +350,11 @@ source.support_relation, (r.r_type for r in rels))): self.needsplit = True # add source for rewritten constants to sourcesterms + self._const_vars = {} for vconsts in self.rqlst.stinfo['rewritten'].itervalues(): - const = vconsts[0] + # remember those consts come from the same variable + for const in vconsts: + self._const_vars[const] = vconsts source = self._session.source_from_eid(const.eval(self.plan.args)) if source is self.system_source: for const in vconsts: @@ -537,6 +540,11 @@ rel in self._crossrelations[s])) if invalid_sources: self._remove_sources(term, invalid_sources) + # if term is a rewritten const, we can apply the same changes to + # all other consts inserted from the same original variable + for const in self._const_vars.get(term, ()): + if const is not term: + self._remove_sources(const, invalid_sources) termsources -= invalid_sources self._remove_sources_until_stable(term, termssources) if isinstance(oterm, Constant): diff -r 0b7805928a27 -r 09b50d7e5321 server/test/unittest_msplanner.py --- a/server/test/unittest_msplanner.py Tue Apr 27 18:27:43 2010 +0200 +++ b/server/test/unittest_msplanner.py Tue Apr 27 18:31:42 2010 +0200 @@ -625,7 +625,6 @@ 2. return the result of Any X,Y WHERE X login 'syt', Y login 'adim' on the system source """ - ueid = self.session.user.eid self._test('Any X,Y LIMIT 10 OFFSET 10 WHERE X login "syt", Y login "adim"', [('FetchStep', [('Any X WHERE X login "syt", X is CWUser', [{'X': 'CWUser'}])], @@ -637,7 +636,7 @@ [('Any X,Y LIMIT 10 OFFSET 10 WHERE X is CWUser, Y is CWUser', [{'X': 'CWUser', 'Y': 'CWUser'}])], 10, 10, [self.system], {'X': 'table0.C0', 'Y': 'table1.C0'}, []) - ], {'x': ueid}) + ]) def test_complex_aggregat(self): self._test('Any MAX(X)', @@ -1417,7 +1416,7 @@ [])], {'E': self.session.user.eid}) - def test_eid_dont_cross_relation(self): + def test_eid_dont_cross_relation_1(self): repo._type_source_cache[999999] = ('Personne', 'system', 999999) self._test('Any Y,YT WHERE X eid %(x)s, X fiche Y, Y title YT', [('OneFetchStep', [('Any Y,YT WHERE X eid 999999, X fiche Y, Y title YT', @@ -1425,6 +1424,18 @@ None, None, [self.system], {}, [])], {'x': 999999}) + def test_eid_dont_cross_relation_2(self): + repo._type_source_cache[999999] = ('Note', 'cards', 999999) + self.cards.dont_cross_relations.add('concerne') + try: + self._test('Any Y,S,YT,X WHERE Y concerne X, Y in_state S, X eid 999999, Y ref YT', + [('OneFetchStep', [('Any Y,S,YT,999999 WHERE Y concerne 999999, Y in_state S, Y ref YT', + [{'Y': 'Affaire', 'YT': 'String', 'S': 'State'}])], + None, None, [self.system], {}, [])], + {'x': 999999}) + finally: + self.cards.dont_cross_relations.remove('concerne') + # external source w/ .cross_relations == ['multisource_crossed_rel'] ######