server/sources/rql2sql.py
branchstable
changeset 3852 03121ca1f85e
parent 3815 50b87f759b5d
child 3866 2783c166ad1a
equal deleted inserted replaced
3850:75023c2c34ee 3852:03121ca1f85e
   129 
   129 
   130 def remove_unused_solutions(rqlst, solutions, varmap, schema):
   130 def remove_unused_solutions(rqlst, solutions, varmap, schema):
   131     """cleanup solutions: remove solutions where invariant variables are taking
   131     """cleanup solutions: remove solutions where invariant variables are taking
   132     different types
   132     different types
   133     """
   133     """
   134     newsolutions = _new_solutions(rqlst, solutions)
   134     newsols = _new_solutions(rqlst, solutions)
   135     existssols = {}
   135     existssols = {}
   136     unstable = set()
   136     unstable = set()
       
   137     invariants = {}
   137     for vname, var in rqlst.defined_vars.iteritems():
   138     for vname, var in rqlst.defined_vars.iteritems():
   138         vtype = newsolutions[0][vname]
   139         vtype = newsols[0][vname]
   139         if var._q_invariant or vname in varmap:
   140         if var._q_invariant or vname in varmap:
   140             for i in xrange(len(newsolutions)-1, 0, -1):
   141             # remove invariant variable from solutions to remove duplicates
   141                 if vtype != newsolutions[i][vname]:
   142             # later, then reinserting a type for the variable even later
   142                     newsolutions.pop(i)
   143             for sol in newsols:
   143         elif not var.scope is rqlst:
   144                 invariants.setdefault(id(sol), {})[vname] = sol.pop(vname)
       
   145         elif var.scope is not rqlst:
   144             # move appart variables which are in a EXISTS scope and are variating
   146             # move appart variables which are in a EXISTS scope and are variating
   145             try:
   147             try:
   146                 thisexistssols, thisexistsvars = existssols[var.scope]
   148                 thisexistssols, thisexistsvars = existssols[var.scope]
   147             except KeyError:
   149             except KeyError:
   148                 thisexistssols = [newsolutions[0]]
   150                 thisexistssols = [newsols[0]]
   149                 thisexistsvars = set()
   151                 thisexistsvars = set()
   150                 existssols[var.scope] = thisexistssols, thisexistsvars
   152                 existssols[var.scope] = thisexistssols, thisexistsvars
   151             for i in xrange(len(newsolutions)-1, 0, -1):
   153             for i in xrange(len(newsols)-1, 0, -1):
   152                 if vtype != newsolutions[i][vname]:
   154                 if vtype != newsols[i][vname]:
   153                     thisexistssols.append(newsolutions.pop(i))
   155                     thisexistssols.append(newsols.pop(i))
   154                     thisexistsvars.add(vname)
   156                     thisexistsvars.add(vname)
   155         else:
   157         else:
   156             # remember unstable variables
   158             # remember unstable variables
   157             for i in xrange(1, len(newsolutions)):
   159             for i in xrange(1, len(newsols)):
   158                 if vtype != newsolutions[i][vname]:
   160                 if vtype != newsols[i][vname]:
   159                     unstable.add(vname)
   161                     unstable.add(vname)
   160     if len(newsolutions) > 1:
   162     if invariants:
   161         if rewrite_unstable_outer_join(rqlst, newsolutions, unstable, schema):
   163         # filter out duplicates
       
   164         newsols_ = []
       
   165         for sol in newsols:
       
   166             if not sol in newsols_:
       
   167                 newsols_.append(sol)
       
   168         newsols = newsols_
       
   169         # reinsert solutions for invariants
       
   170         for sol in newsols:
       
   171             for invvar, vartype in invariants[id(sol)].iteritems():
       
   172                 sol[invvar] = vartype
       
   173         for sol in existssols:
       
   174             for invvar, vartype in invariants[id(sol)].iteritems():
       
   175                 sol[invvar] = vartype
       
   176     if len(newsols) > 1:
       
   177         if rewrite_unstable_outer_join(rqlst, newsols, unstable, schema):
   162             # remove variables extracted to subqueries from solutions
   178             # remove variables extracted to subqueries from solutions
   163             newsolutions = _new_solutions(rqlst, newsolutions)
   179             newsols = _new_solutions(rqlst, newsols)
   164     return newsolutions, existssols, unstable
   180     return newsols, existssols, unstable
   165 
   181 
   166 def relation_info(relation):
   182 def relation_info(relation):
   167     lhs, rhs = relation.get_variable_parts()
   183     lhs, rhs = relation.get_variable_parts()
   168     try:
   184     try:
   169         lhs = lhs.variable
   185         lhs = lhs.variable