server/sources/rql2sql.py
branchstable
changeset 6050 20af96a6fffc
parent 6003 5fbc1c4c13ff
child 6131 087c5a168010
equal deleted inserted replaced
6049:f0ae98fa85a1 6050:20af96a6fffc
    99 def rewrite_unstable_outer_join(select, solutions, unstable, schema):
    99 def rewrite_unstable_outer_join(select, solutions, unstable, schema):
   100     """if some optional variables are unstable, they should be selected in a
   100     """if some optional variables are unstable, they should be selected in a
   101     subquery. This function check this and rewrite the rql syntax tree if
   101     subquery. This function check this and rewrite the rql syntax tree if
   102     necessary (in place). Return a boolean telling if the tree has been modified
   102     necessary (in place). Return a boolean telling if the tree has been modified
   103     """
   103     """
   104     torewrite = set()
       
   105     modified = False
   104     modified = False
   106     for varname in tuple(unstable):
   105     for varname in tuple(unstable):
   107         var = select.defined_vars[varname]
   106         var = select.defined_vars[varname]
   108         if not var.stinfo.get('optrelations'):
   107         if not var.stinfo.get('optrelations'):
   109             continue
   108             continue
   110         modified = True
       
   111         unstable.remove(varname)
   109         unstable.remove(varname)
   112         torewrite.add(var)
       
   113         newselect = Select()
   110         newselect = Select()
   114         newselect.need_distinct = False
   111         newselect.need_distinct = False
   115         myunion = Union()
   112         myunion = Union()
   116         myunion.append(newselect)
   113         myunion.append(newselect)
   117         # extract aliases / selection
   114         # extract aliases / selection
   137                 var = vref.variable
   134                 var = vref.variable
   138                 var.stinfo['relations'].add(newrel)
   135                 var.stinfo['relations'].add(newrel)
   139                 var.stinfo['rhsrelations'].add(newrel)
   136                 var.stinfo['rhsrelations'].add(newrel)
   140                 if rel.optional in ('right', 'both'):
   137                 if rel.optional in ('right', 'both'):
   141                     var.add_optional_relation(newrel)
   138                     var.add_optional_relation(newrel)
       
   139         if not select.where and not modified:
       
   140             # oops, generated the same thing as the original select....
       
   141             # restore original query, else we'll indefinitly loop
       
   142             for var, rel in towrap_rels:
       
   143                 select.add_restriction(rel)
       
   144             continue
       
   145         modified = True
   142         # extract subquery solutions
   146         # extract subquery solutions
   143         mysolutions = [sol.copy() for sol in solutions]
   147         mysolutions = [sol.copy() for sol in solutions]
   144         cleanup_solutions(newselect, mysolutions)
   148         cleanup_solutions(newselect, mysolutions)
   145         newselect.set_possible_types(solutions)
   149         newselect.set_possible_types(mysolutions)
   146         # full sub-query
   150         # full sub-query
   147         aliases = [VariableRef(select.get_variable(avar.name, i))
   151         aliases = [VariableRef(select.get_variable(avar.name, i))
   148                    for i, avar in enumerate(newselect.selection)]
   152                    for i, avar in enumerate(newselect.selection)]
   149         select.add_subquery(SubQuery(aliases, myunion), check=False)
   153         select.add_subquery(SubQuery(aliases, myunion), check=False)
   150     return modified
   154     return modified