server/msplanner.py
changeset 5004 4cc020ee70e2
parent 4956 e8a5cd5032f4
child 5047 ed048e317eae
equal deleted inserted replaced
5003:cb27485ef5ae 5004:4cc020ee70e2
   307         eschema = self._schema.eschema
   307         eschema = self._schema.eschema
   308         sourcesterms = self._sourcesterms
   308         sourcesterms = self._sourcesterms
   309         # find for each source which variable/solution are supported
   309         # find for each source which variable/solution are supported
   310         for varname, varobj in self.rqlst.defined_vars.items():
   310         for varname, varobj in self.rqlst.defined_vars.items():
   311             # if variable has an eid specified, we can get its source directly
   311             # if variable has an eid specified, we can get its source directly
   312             # NOTE: use uidrels and not constnode to deal with "X eid IN(1,2,3,4)"
   312             # NOTE: use uidrel and not constnode to deal with "X eid IN(1,2,3,4)"
   313             if varobj.stinfo['uidrels']:
   313             if varobj.stinfo['uidrel'] is not None:
   314                 vrels = varobj.stinfo['relations'] - varobj.stinfo['uidrels']
   314                 rel = varobj.stinfo['uidrel']
   315                 for rel in varobj.stinfo['uidrels']:
   315                 for const in rel.children[1].get_nodes(Constant):
   316                     for const in rel.children[1].get_nodes(Constant):
   316                     eid = const.eval(self.plan.args)
   317                         eid = const.eval(self.plan.args)
   317                     source = self._session.source_from_eid(eid)
   318                         source = self._session.source_from_eid(eid)
   318                     if vrels and not any(source.support_relation(r.r_type)
   319                         if vrels and not any(source.support_relation(r.r_type)
   319                                          for r in vrels if not r is rel):
   320                                              for r in vrels):
   320                         self._set_source_for_term(self.system_source, varobj)
   321                             self._set_source_for_term(self.system_source, varobj)
   321                     else:
   322                         else:
   322                         self._set_source_for_term(source, varobj)
   323                             self._set_source_for_term(source, varobj)
       
   324                 continue
   323                 continue
   325             rels = varobj.stinfo['relations']
   324             rels = varobj.stinfo['relations']
   326             if not rels and not varobj.stinfo['typerels']:
   325             if not rels and varobj.stinfo['typerel'] is None:
   327                 # (rare) case where the variable has no type specified nor
   326                 # (rare) case where the variable has no type specified nor
   328                 # relation accessed ex. "Any MAX(X)"
   327                 # relation accessed ex. "Any MAX(X)"
   329                 self._set_source_for_term(self.system_source, varobj)
   328                 self._set_source_for_term(self.system_source, varobj)
   330                 continue
   329                 continue
   331             for i, sol in enumerate(self._solutions):
   330             for i, sol in enumerate(self._solutions):
   698                     # add attribute variables and mark variables which should be
   697                     # add attribute variables and mark variables which should be
   699                     # additionaly selected when possible
   698                     # additionaly selected when possible
   700                     for var in select.defined_vars.itervalues():
   699                     for var in select.defined_vars.itervalues():
   701                         if not var in terms:
   700                         if not var in terms:
   702                             stinfo = var.stinfo
   701                             stinfo = var.stinfo
   703                             for ovar, rtype in stinfo['attrvars']:
   702                             for ovar, rtype in stinfo.get('attrvars', ()):
   704                                 if ovar in terms:
   703                                 if ovar in terms:
   705                                     needsel.add(var.name)
   704                                     needsel.add(var.name)
   706                                     terms.append(var)
   705                                     terms.append(var)
   707                                     break
   706                                     break
   708                             else:
   707                             else:
   776             # supported relation with at least one end supported, check the
   775             # supported relation with at least one end supported, check the
   777             # other end is in as well. If not this usually means the
   776             # other end is in as well. If not this usually means the
   778             # variable is refed by an outer scope and should be substituted
   777             # variable is refed by an outer scope and should be substituted
   779             # using an 'identity' relation (else we'll get a conflict of
   778             # using an 'identity' relation (else we'll get a conflict of
   780             # temporary tables)
   779             # temporary tables)
   781             if rhsvar in terms and not lhsvar in terms:
   780             if rhsvar in terms and not lhsvar in terms and lhsvar.scope is lhsvar.stmt:
   782                 self._identity_substitute(rel, lhsvar, terms, needsel)
   781                 self._identity_substitute(rel, lhsvar, terms, needsel)
   783             elif lhsvar in terms and not rhsvar in terms:
   782             elif lhsvar in terms and not rhsvar in terms and rhsvar.scope is rhsvar.stmt:
   784                 self._identity_substitute(rel, rhsvar, terms, needsel)
   783                 self._identity_substitute(rel, rhsvar, terms, needsel)
   785 
   784 
   786     def _identity_substitute(self, relation, var, terms, needsel):
   785     def _identity_substitute(self, relation, var, terms, needsel):
   787         newvar = self._insert_identity_variable(relation.scope, var)
   786         newvar = self._insert_identity_variable(relation.scope, var)
   788         if newvar is not None:
   787         # ensure relation is using '=' operator, else we rely on a
   789             # ensure relation is using '=' operator, else we rely on a
   788         # sqlgenerator side effect (it won't insert an inequality operator
   790             # sqlgenerator side effect (it won't insert an inequality operator
   789         # in this case)
   791             # in this case)
   790         relation.children[1].operator = '='
   792             relation.children[1].operator = '='
   791         terms.append(newvar)
   793             terms.append(newvar)
   792         needsel.add(newvar.name)
   794             needsel.add(newvar.name)
       
   795 
   793 
   796     def _choose_term(self, sourceterms):
   794     def _choose_term(self, sourceterms):
   797         """pick one term among terms supported by a source, which will be used
   795         """pick one term among terms supported by a source, which will be used
   798         as a base to generate an execution step
   796         as a base to generate an execution step
   799         """
   797         """
  1416             return False
  1414             return False
  1417         if var.name in self.extneedsel or var.stinfo['selected']:
  1415         if var.name in self.extneedsel or var.stinfo['selected']:
  1418             return False
  1416             return False
  1419         if not var in terms or used_in_outer_scope(var, self.current_scope):
  1417         if not var in terms or used_in_outer_scope(var, self.current_scope):
  1420             return False
  1418             return False
  1421         if any(v for v, _ in var.stinfo['attrvars'] if not v in terms):
  1419         if any(v for v, _ in var.stinfo.get('attrvars', ()) if not v in terms):
  1422             return False
  1420             return False
  1423         return True
  1421         return True
  1424 
  1422 
  1425     def visit_exists(self, node, newroot, terms):
  1423     def visit_exists(self, node, newroot, terms):
  1426         newexists = node.__class__()
  1424         newexists = node.__class__()