|
1 # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
3 # |
|
4 # This file is part of CubicWeb. |
|
5 # |
|
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
|
7 # terms of the GNU Lesser General Public License as published by the Free |
|
8 # Software Foundation, either version 2.1 of the License, or (at your option) |
|
9 # any later version. |
|
10 # |
|
11 # logilab-common is distributed in the hope that it will be useful, but WITHOUT |
|
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
14 # details. |
|
15 # |
|
16 # You should have received a copy of the GNU Lesser General Public License along |
|
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
1 """plan execution of rql queries on multiple sources |
18 """plan execution of rql queries on multiple sources |
2 |
19 |
3 the best way to understand what are we trying to acheive here is to read the |
20 the best way to understand what are we trying to acheive here is to read the |
4 unit-tests in unittest_msplanner.py |
21 unit-tests in unittest_msplanner.py |
5 |
22 |
67 1. return the result of Any X WHERE X owned_by Y from system source, that's |
84 1. return the result of Any X WHERE X owned_by Y from system source, that's |
68 enough (optimization of the sql querier will avoid join on CWUser, so we |
85 enough (optimization of the sql querier will avoid join on CWUser, so we |
69 will directly get local eids) |
86 will directly get local eids) |
70 |
87 |
71 |
88 |
72 :organization: Logilab |
|
73 :copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. |
|
74 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
75 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
|
76 """ |
89 """ |
77 __docformat__ = "restructuredtext en" |
90 __docformat__ = "restructuredtext en" |
78 |
91 |
79 from itertools import imap, ifilterfalse |
92 from itertools import imap, ifilterfalse |
80 |
93 |
351 # query |
364 # query |
352 if not varobj._q_invariant and any(ifilterfalse( |
365 if not varobj._q_invariant and any(ifilterfalse( |
353 source.support_relation, (r.r_type for r in rels))): |
366 source.support_relation, (r.r_type for r in rels))): |
354 self.needsplit = True |
367 self.needsplit = True |
355 # add source for rewritten constants to sourcesterms |
368 # add source for rewritten constants to sourcesterms |
|
369 self._const_vars = {} |
356 for vconsts in self.rqlst.stinfo['rewritten'].itervalues(): |
370 for vconsts in self.rqlst.stinfo['rewritten'].itervalues(): |
357 const = vconsts[0] |
371 # remember those consts come from the same variable |
|
372 for const in vconsts: |
|
373 self._const_vars[const] = vconsts |
358 source = self._session.source_from_eid(const.eval(self.plan.args)) |
374 source = self._session.source_from_eid(const.eval(self.plan.args)) |
359 if source is self.system_source: |
375 if source is self.system_source: |
360 for const in vconsts: |
376 for const in vconsts: |
361 self._set_source_for_term(source, const) |
377 self._set_source_for_term(source, const) |
362 elif not self._sourcesterms: |
378 elif not self._sourcesterms: |
538 invalid_sources = frozenset((s, solidx) for s, solidx in invalid_sources |
554 invalid_sources = frozenset((s, solidx) for s, solidx in invalid_sources |
539 if not (s in self._crossrelations and |
555 if not (s in self._crossrelations and |
540 rel in self._crossrelations[s])) |
556 rel in self._crossrelations[s])) |
541 if invalid_sources: |
557 if invalid_sources: |
542 self._remove_sources(term, invalid_sources) |
558 self._remove_sources(term, invalid_sources) |
|
559 # if term is a rewritten const, we can apply the same changes to |
|
560 # all other consts inserted from the same original variable |
|
561 for const in self._const_vars.get(term, ()): |
|
562 if const is not term: |
|
563 self._remove_sources(const, invalid_sources) |
543 termsources -= invalid_sources |
564 termsources -= invalid_sources |
544 self._remove_sources_until_stable(term, termssources) |
565 self._remove_sources_until_stable(term, termssources) |
545 if isinstance(oterm, Constant): |
566 if isinstance(oterm, Constant): |
546 self._remove_sources(oterm, invalid_sources) |
567 self._remove_sources(oterm, invalid_sources) |
547 |
568 |