server/sources/rql2sql.py
branchstable
changeset 7579 5a610b34d2d2
parent 7472 9833c09460f1
child 7580 328542c4fdc8
child 7630 f4b954676721
equal deleted inserted replaced
7576:1b7fa4df1f83 7579:5a610b34d2d2
   245     switchedsql = sql.replace(table + '.eid_from', '__eid_from__')
   245     switchedsql = sql.replace(table + '.eid_from', '__eid_from__')
   246     switchedsql = switchedsql.replace(table + '.eid_to',
   246     switchedsql = switchedsql.replace(table + '.eid_to',
   247                                       table + '.eid_from')
   247                                       table + '.eid_from')
   248     return switchedsql.replace('__eid_from__', table + '.eid_to')
   248     return switchedsql.replace('__eid_from__', table + '.eid_to')
   249 
   249 
   250 def sort_term_selection(sorts, selectedidx, rqlst, groups):
   250 def sort_term_selection(sorts, rqlst, groups):
   251     # XXX beurk
   251     # XXX beurk
   252     if isinstance(rqlst, list):
   252     if isinstance(rqlst, list):
   253         def append(term):
   253         def append(term):
   254             rqlst.append(term)
   254             rqlst.append(term)
       
   255         selectionidx = set(str(term) for term in rqlst)
   255     else:
   256     else:
   256         def append(term):
   257         def append(term):
   257             rqlst.selection.append(term.copy(rqlst))
   258             rqlst.selection.append(term.copy(rqlst))
       
   259         selectionidx = set(str(term) for term in rqlst.selection)
       
   260 
   258     for sortterm in sorts:
   261     for sortterm in sorts:
   259         term = sortterm.term
   262         term = sortterm.term
   260         if not isinstance(term, Constant) and not str(term) in selectedidx:
   263         if not isinstance(term, Constant) and not str(term) in selectionidx:
   261             selectedidx.append(str(term))
   264             selectionidx.add(str(term))
   262             append(term)
   265             append(term)
   263             if groups:
   266             if groups:
   264                 for vref in term.iget_nodes(VariableRef):
   267                 for vref in term.iget_nodes(VariableRef):
   265                     if not vref in groups:
   268                     if not vref in groups:
   266                         groups.append(vref)
   269                         groups.append(vref)
   267 
   270 
   268 def fix_selection_and_group(rqlst, selectedidx, needwrap, selectsortterms,
   271 def fix_selection_and_group(rqlst, needwrap, selectsortterms,
   269                             sorts, groups, having):
   272                             sorts, groups, having):
   270     if selectsortterms and sorts:
   273     if selectsortterms and sorts:
   271         sort_term_selection(sorts, selectedidx, rqlst, not needwrap and groups)
   274         sort_term_selection(sorts, rqlst, not needwrap and groups)
       
   275     groupvrefs = [vref for term in groups for vref in term.iget_nodes(VariableRef)]
   272     if sorts and groups:
   276     if sorts and groups:
   273         # when a query is grouped, ensure sort terms are grouped as well
   277         # when a query is grouped, ensure sort terms are grouped as well
   274         for sortterm in sorts:
   278         for sortterm in sorts:
   275             term = sortterm.term
   279             term = sortterm.term
   276             if not (isinstance(term, Constant) or \
   280             if not (isinstance(term, Constant) or \
   277                     (isinstance(term, Function) and
   281                     (isinstance(term, Function) and
   278                      get_func_descr(term.name).aggregat)):
   282                      get_func_descr(term.name).aggregat)):
   279                 for vref in term.iget_nodes(VariableRef):
   283                 for vref in term.iget_nodes(VariableRef):
   280                     if not vref in groups:
   284                     if not vref in groupvrefs:
   281                         groups.append(vref)
   285                         groups.append(vref)
   282     if needwrap:
   286                         groupvrefs.append(vref)
       
   287     if needwrap and (groups or having):
       
   288         selectedidx = set(vref.name for term in rqlst.selection
       
   289                           for vref in term.get_nodes(VariableRef))
   283         if groups:
   290         if groups:
   284             for vref in groups:
   291             for vref in groupvrefs:
   285                 if not vref.name in selectedidx:
   292                 if vref.name not in selectedidx:
   286                     selectedidx.append(vref.name)
   293                     selectedidx.add(vref.name)
   287                     rqlst.selection.append(vref)
   294                     rqlst.selection.append(vref)
   288         if having:
   295         if having:
   289             for term in having:
   296             for term in having:
   290                 for vref in term.iget_nodes(VariableRef):
   297                 for vref in term.iget_nodes(VariableRef):
   291                     if not vref.name in selectedidx:
   298                     if vref.name not in selectedidx:
   292                         selectedidx.append(vref.name)
   299                         selectedidx.add(vref.name)
   293                         rqlst.selection.append(vref)
   300                         rqlst.selection.append(vref)
   294 
   301 
   295 def iter_mapped_var_sels(stmt, variable):
   302 def iter_mapped_var_sels(stmt, variable):
   296     # variable is a Variable or ColumnAlias node mapped to a source side
   303     # variable is a Variable or ColumnAlias node mapped to a source side
   297     # callback
   304     # callback
   804             # state from a previous unioned select
   811             # state from a previous unioned select
   805             state.merge_source_cbs(self._state.needs_source_cb)
   812             state.merge_source_cbs(self._state.needs_source_cb)
   806         # treat subqueries
   813         # treat subqueries
   807         self._subqueries_sql(select, state)
   814         self._subqueries_sql(select, state)
   808         # generate sql for this select node
   815         # generate sql for this select node
   809         selectidx = [str(term) for term in select.selection]
       
   810         if needwrap:
   816         if needwrap:
   811             outerselection = origselection[:]
   817             outerselection = origselection[:]
   812             if sorts and selectsortterms:
   818             if sorts and selectsortterms:
   813                 outerselectidx = [str(term) for term in outerselection]
       
   814                 if distinct:
   819                 if distinct:
   815                     sort_term_selection(sorts, outerselectidx,
   820                     sort_term_selection(sorts, outerselection, groups)
   816                                         outerselection, groups)
   821         fix_selection_and_group(select, needwrap, selectsortterms,
   817             else:
   822                                 sorts, groups, having)
   818                 outerselectidx = selectidx[:]
       
   819         fix_selection_and_group(select, selectidx, needwrap,
       
   820                                 selectsortterms, sorts, groups, having)
       
   821         if needwrap:
   823         if needwrap:
   822             fselectidx = outerselectidx
       
   823             fneedwrap = len(outerselection) != len(origselection)
   824             fneedwrap = len(outerselection) != len(origselection)
   824         else:
   825         else:
   825             fselectidx = selectidx
       
   826             fneedwrap = len(select.selection) != len(origselection)
   826             fneedwrap = len(select.selection) != len(origselection)
   827         if fneedwrap:
   827         if fneedwrap:
   828             needalias = True
   828             needalias = True
   829         self._in_wrapping_query = False
   829         self._in_wrapping_query = False
   830         self._state = state
   830         self._state = state
   852             if having:
   852             if having:
   853                 sql += '\nHAVING %s' % having
   853                 sql += '\nHAVING %s' % having
   854             # sort
   854             # sort
   855             if sorts:
   855             if sorts:
   856                 sqlsortterms = []
   856                 sqlsortterms = []
       
   857                 if needwrap:
       
   858                     selectidx = [str(term) for term in outerselection]
       
   859                 else:
       
   860                     selectidx = [str(term) for term in select.selection]
   857                 for sortterm in sorts:
   861                 for sortterm in sorts:
   858                     _term = self._sortterm_sql(sortterm, fselectidx)
   862                     _term = self._sortterm_sql(sortterm, selectidx)
   859                     if _term is not None:
   863                     if _term is not None:
   860                         sqlsortterms.append(_term)
   864                         sqlsortterms.append(_term)
   861                 if sqlsortterms:
   865                 if sqlsortterms:
   862                     sql = self.dbhelper.sql_add_order_by(
   866                     sql = self.dbhelper.sql_add_order_by(
   863                         sql, sqlsortterms, origselection, fneedwrap,
   867                         sql, sqlsortterms, origselection, fneedwrap,