server/querier.py
changeset 5768 1e73a466aa69
parent 5726 c3b99606644d
child 5890 141b935a38fc
equal deleted inserted replaced
5766:c397819f2482 5768:1e73a466aa69
    27 
    27 
    28 from logilab.common.cache import Cache
    28 from logilab.common.cache import Cache
    29 from logilab.common.compat import any
    29 from logilab.common.compat import any
    30 from rql import RQLSyntaxError
    30 from rql import RQLSyntaxError
    31 from rql.stmts import Union, Select
    31 from rql.stmts import Union, Select
    32 from rql.nodes import Relation, VariableRef, Constant, SubQuery
    32 from rql.nodes import Relation, VariableRef, Constant, SubQuery, Function
    33 
    33 
    34 from cubicweb import Unauthorized, QueryError, UnknownEid, typed_eid
    34 from cubicweb import Unauthorized, QueryError, UnknownEid, typed_eid
    35 from cubicweb import server
    35 from cubicweb import server
    36 from cubicweb.rset import ResultSet
    36 from cubicweb.rset import ResultSet
    37 
    37 
    48     """return a sql schema to store RQL query result"""
    48     """return a sql schema to store RQL query result"""
    49     for i, term in enumerate(selected):
    49     for i, term in enumerate(selected):
    50         key = term.as_string()
    50         key = term.as_string()
    51         value = '%s.C%s' % (table, i)
    51         value = '%s.C%s' % (table, i)
    52         if varmap.get(key, value) != value:
    52         if varmap.get(key, value) != value:
    53             raise Exception('variable name conflict on %s' % key)
    53             raise Exception('variable name conflict on %s: got %s / %s'
       
    54                             % (key, value, varmap))
    54         varmap[key] = value
    55         varmap[key] = value
    55 
    56 
    56 # permission utilities ########################################################
    57 # permission utilities ########################################################
    57 
    58 
    58 def check_no_password_selected(rqlst):
    59 def check_no_password_selected(rqlst):
   283                     selected = set(vref.name for vref in aliases)
   284                     selected = set(vref.name for vref in aliases)
   284                     # now copy original selection and groups
   285                     # now copy original selection and groups
   285                     for term in origselection:
   286                     for term in origselection:
   286                         newselect.append_selected(term.copy(newselect))
   287                         newselect.append_selected(term.copy(newselect))
   287                     if select.orderby:
   288                     if select.orderby:
   288                         newselect.set_orderby([s.copy(newselect) for s in select.orderby])
   289                         sortterms = []
       
   290                         for sortterm in select.orderby:
       
   291                             sortterms.append(sortterm.copy(newselect))
       
   292                             for fnode in sortterm.get_nodes(Function):
       
   293                                 if fnode.name == 'FTIRANK':
       
   294                                     # we've to fetch the has_text relation as well
       
   295                                     var = fnode.children[0].variable
       
   296                                     rel = iter(var.stinfo['ftirels']).next()
       
   297                                     assert not rel.ored(), 'unsupported'
       
   298                                     newselect.add_restriction(rel.copy(newselect))
       
   299                                     # remove relation from the orig select and
       
   300                                     # cleanup variable stinfo
       
   301                                     rel.parent.remove(rel)
       
   302                                     var.stinfo['ftirels'].remove(rel)
       
   303                                     var.stinfo['relations'].remove(rel)
       
   304                                     # XXX not properly re-annotated after security insertion?
       
   305                                     newvar = newselect.get_variable(var.name)
       
   306                                     newvar.stinfo.setdefault('ftirels', set()).add(rel)
       
   307                                     newvar.stinfo.setdefault('relations', set()).add(rel)
       
   308                         newselect.set_orderby(sortterms)
   289                         _expand_selection(select.orderby, selected, aliases, select, newselect)
   309                         _expand_selection(select.orderby, selected, aliases, select, newselect)
   290                         select.orderby = () # XXX dereference?
   310                         select.orderby = () # XXX dereference?
   291                     if select.groupby:
   311                     if select.groupby:
   292                         newselect.set_groupby([g.copy(newselect) for g in select.groupby])
   312                         newselect.set_groupby([g.copy(newselect) for g in select.groupby])
   293                         _expand_selection(select.groupby, selected, aliases, select, newselect)
   313                         _expand_selection(select.groupby, selected, aliases, select, newselect)
   560         # some cache usage stats
   580         # some cache usage stats
   561         self.cache_hit, self.cache_miss = 0, 0
   581         self.cache_hit, self.cache_miss = 0, 0
   562         # rql parsing / analysing helper
   582         # rql parsing / analysing helper
   563         self.solutions = repo.vreg.solutions
   583         self.solutions = repo.vreg.solutions
   564         rqlhelper = repo.vreg.rqlhelper
   584         rqlhelper = repo.vreg.rqlhelper
       
   585         # set backend on the rql helper, will be used for function checking
       
   586         rqlhelper.backend = repo.config.sources()['system']['db-driver']
   565         self._parse = rqlhelper.parse
   587         self._parse = rqlhelper.parse
   566         self._annotate = rqlhelper.annotate
   588         self._annotate = rqlhelper.annotate
   567         # rql planner
   589         # rql planner
   568         # note: don't use repo.sources, may not be built yet, and also "admin"
   590         # note: don't use repo.sources, may not be built yet, and also "admin"
   569         #       isn't an actual source
   591         #       isn't an actual source