equal
deleted
inserted
replaced
609 sql += '\nGROUP BY %s' % groups |
609 sql += '\nGROUP BY %s' % groups |
610 if having: |
610 if having: |
611 sql += '\nHAVING %s' % having |
611 sql += '\nHAVING %s' % having |
612 # sort |
612 # sort |
613 if sorts: |
613 if sorts: |
614 sql += '\nORDER BY %s' % ','.join(self._sortterm_sql(sortterm, |
614 sqlsortterms = [self._sortterm_sql(sortterm, fselectidx) |
615 fselectidx) |
615 for sortterm in sorts] |
616 for sortterm in sorts) |
616 sqlsortterms = [x for x in sqlsortterms if x is not None] |
617 if fneedwrap: |
617 if sqlsortterms: |
618 selection = ['T1.C%s' % i for i in xrange(len(origselection))] |
618 sql += '\nORDER BY %s' % ','.join(sqlsortterms) |
619 sql = 'SELECT %s FROM (%s) AS T1' % (','.join(selection), sql) |
619 if sorts and fneedwrap: |
|
620 selection = ['T1.C%s' % i for i in xrange(len(origselection))] |
|
621 sql = 'SELECT %s FROM (%s) AS T1' % (','.join(selection), sql) |
620 state.finalize_source_cbs() |
622 state.finalize_source_cbs() |
621 finally: |
623 finally: |
622 select.selection = origselection |
624 select.selection = origselection |
623 # limit / offset |
625 # limit / offset |
624 limit = select.limit |
626 limit = select.limit |
694 return 'SELECT %s' % ', '.join(clause) |
696 return 'SELECT %s' % ', '.join(clause) |
695 |
697 |
696 def _sortterm_sql(self, sortterm, selectidx): |
698 def _sortterm_sql(self, sortterm, selectidx): |
697 term = sortterm.term |
699 term = sortterm.term |
698 try: |
700 try: |
699 sqlterm = str(selectidx.index(str(term)) + 1) |
701 sqlterm = selectidx.index(str(term)) + 1 |
700 except ValueError: |
702 except ValueError: |
701 # Constant node or non selected term |
703 # Constant node or non selected term |
702 sqlterm = str(term.accept(self)) |
704 sqlterm = term.accept(self) |
|
705 if sqlterm is None: |
|
706 return None |
703 if sortterm.asc: |
707 if sortterm.asc: |
704 return sqlterm |
708 return str(sqlterm) |
705 else: |
709 else: |
706 return '%s DESC' % sqlterm |
710 return '%s DESC' % sqlterm |
707 |
711 |
708 def visit_and(self, et): |
712 def visit_and(self, et): |
709 """generate SQL for a AND subtree""" |
713 """generate SQL for a AND subtree""" |
1058 if isinstance(rel.parent, Not): |
1062 if isinstance(rel.parent, Not): |
1059 self._state.done.add(rel.parent) |
1063 self._state.done.add(rel.parent) |
1060 not_ = True |
1064 not_ = True |
1061 else: |
1065 else: |
1062 not_ = False |
1066 not_ = False |
1063 return self.dbhelper.fti_restriction_sql(alias, const.eval(self._args), |
1067 query = const.eval(self._args) |
|
1068 return self.dbhelper.fti_restriction_sql(alias, query, |
1064 jointo, not_) + restriction |
1069 jointo, not_) + restriction |
1065 |
1070 |
1066 def visit_comparison(self, cmp): |
1071 def visit_comparison(self, cmp): |
1067 """generate SQL for a comparison""" |
1072 """generate SQL for a comparison""" |
1068 if len(cmp.children) == 2: |
1073 if len(cmp.children) == 2: |
1102 pass |
1107 pass |
1103 return '(%s %s %s)'% (lhs.accept(self), operator, rhs.accept(self)) |
1108 return '(%s %s %s)'% (lhs.accept(self), operator, rhs.accept(self)) |
1104 |
1109 |
1105 def visit_function(self, func): |
1110 def visit_function(self, func): |
1106 """generate SQL name for a function""" |
1111 """generate SQL name for a function""" |
|
1112 if func.name == 'FTIRANK': |
|
1113 try: |
|
1114 rel = iter(func.children[0].variable.stinfo['ftirels']).next() |
|
1115 except KeyError: |
|
1116 raise BadRQLQuery("can't use FTIRANK on variable not used in an" |
|
1117 " 'has_text' relation (eg full-text search)") |
|
1118 const = rel.get_parts()[1].children[0] |
|
1119 return self.dbhelper.fti_rank_order(self._fti_table(rel), |
|
1120 const.eval(self._args)) |
1107 args = [c.accept(self) for c in func.children] |
1121 args = [c.accept(self) for c in func.children] |
1108 if func in self._state.source_cb_funcs: |
1122 if func in self._state.source_cb_funcs: |
1109 # function executed as a callback on the source |
1123 # function executed as a callback on the source |
1110 assert len(args) == 1 |
1124 assert len(args) == 1 |
1111 return args[0] |
1125 return args[0] |
1130 _id = constant.value |
1144 _id = constant.value |
1131 if isinstance(_id, unicode): |
1145 if isinstance(_id, unicode): |
1132 _id = _id.encode() |
1146 _id = _id.encode() |
1133 else: |
1147 else: |
1134 _id = str(id(constant)).replace('-', '', 1) |
1148 _id = str(id(constant)).replace('-', '', 1) |
1135 if isinstance(value, unicode): |
|
1136 value = value.encode(self.dbencoding) |
|
1137 self._query_attrs[_id] = value |
1149 self._query_attrs[_id] = value |
1138 return '%%(%s)s' % _id |
1150 return '%%(%s)s' % _id |
1139 |
1151 |
1140 def visit_variableref(self, variableref): |
1152 def visit_variableref(self, variableref): |
1141 """get the sql name for a variable reference""" |
1153 """get the sql name for a variable reference""" |