server/msplanner.py
changeset 5423 e15abfdcce38
parent 5177 395e1ff018ae
parent 5421 8167de96c523
child 5426 0d4853a6e5ee
equal deleted inserted replaced
5412:27249e3fee3d 5423:e15abfdcce38
       
     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