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, |