server/sources/rql2sql.py
changeset 5768 1e73a466aa69
parent 5706 c2e8290bc7b7
child 5811 e77cea9721e7
--- a/server/sources/rql2sql.py	Thu Jun 17 12:13:38 2010 +0200
+++ b/server/sources/rql2sql.py	Thu Jun 17 14:43:16 2010 +0200
@@ -568,12 +568,14 @@
                 sql += '\nHAVING %s' % having
             # sort
             if sorts:
-                sql += '\nORDER BY %s' % ','.join(self._sortterm_sql(sortterm,
-                                                                     fselectidx)
-                                                  for sortterm in sorts)
-                if fneedwrap:
-                    selection = ['T1.C%s' % i for i in xrange(len(origselection))]
-                    sql = 'SELECT %s FROM (%s) AS T1' % (','.join(selection), sql)
+                sqlsortterms = [self._sortterm_sql(sortterm, fselectidx)
+                                for sortterm in sorts]
+                sqlsortterms = [x for x in sqlsortterms if x is not None]
+                if sqlsortterms:
+                    sql += '\nORDER BY %s' % ','.join(sqlsortterms)
+                    if sorts and fneedwrap:
+                        selection = ['T1.C%s' % i for i in xrange(len(origselection))]
+                        sql = 'SELECT %s FROM (%s) AS T1' % (','.join(selection), sql)
             state.finalize_source_cbs()
         finally:
             select.selection = origselection
@@ -651,12 +653,14 @@
     def _sortterm_sql(self, sortterm, selectidx):
         term = sortterm.term
         try:
-            sqlterm = str(selectidx.index(str(term)) + 1)
+            sqlterm = selectidx.index(str(term)) + 1
         except ValueError:
             # Constant node or non selected term
-            sqlterm = str(term.accept(self))
+            sqlterm = term.accept(self)
+            if sqlterm is None:
+                return None
         if sortterm.asc:
-            return sqlterm
+            return str(sqlterm)
         else:
             return '%s DESC' % sqlterm
 
@@ -1014,7 +1018,8 @@
             not_ = True
         else:
             not_ = False
-        return self.dbhelper.fti_restriction_sql(alias, const.eval(self._args),
+        query = const.eval(self._args)
+        return self.dbhelper.fti_restriction_sql(alias, query,
                                                  jointo, not_) + restriction
 
     def visit_comparison(self, cmp):
@@ -1057,6 +1062,15 @@
 
     def visit_function(self, func):
         """generate SQL name for a function"""
+        if func.name == 'FTIRANK':
+            try:
+                rel = iter(func.children[0].variable.stinfo['ftirels']).next()
+            except KeyError:
+                raise BadRQLQuery("can't use FTIRANK on variable not used in an"
+                                  " 'has_text' relation (eg full-text search)")
+            const = rel.get_parts()[1].children[0]
+            return self.dbhelper.fti_rank_order(self._fti_table(rel),
+                                                const.eval(self._args))
         args = [c.accept(self) for c in func.children]
         if func in self._state.source_cb_funcs:
             # function executed as a callback on the source