server/querier.py
branchstable
changeset 5994 97c55baefa0c
parent 5989 099d46422f5a
child 6128 fbb8398f80dc
equal deleted inserted replaced
5976:00b1b6b906cf 5994:97c55baefa0c
    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, Exists, Not
    32 from rql.nodes import (Relation, VariableRef, Constant, SubQuery, Function,
       
    33                        Exists, Not)
    33 
    34 
    34 from cubicweb import Unauthorized, QueryError, UnknownEid, typed_eid
    35 from cubicweb import Unauthorized, QueryError, UnknownEid, typed_eid
    35 from cubicweb import server
    36 from cubicweb import server
    36 from cubicweb.rset import ResultSet
    37 from cubicweb.rset import ResultSet
    37 
    38 
    48     """return a sql schema to store RQL query result"""
    49     """return a sql schema to store RQL query result"""
    49     for i, term in enumerate(selected):
    50     for i, term in enumerate(selected):
    50         key = term.as_string()
    51         key = term.as_string()
    51         value = '%s.C%s' % (table, i)
    52         value = '%s.C%s' % (table, i)
    52         if varmap.get(key, value) != value:
    53         if varmap.get(key, value) != value:
    53             raise Exception('variable name conflict on %s' % key)
    54             raise Exception('variable name conflict on %s: got %s / %s'
       
    55                             % (key, value, varmap))
    54         varmap[key] = value
    56         varmap[key] = value
    55 
    57 
    56 # permission utilities ########################################################
    58 # permission utilities ########################################################
    57 
    59 
    58 def check_no_password_selected(rqlst):
    60 def check_no_password_selected(rqlst):
   292                     selected = set(vref.name for vref in aliases)
   294                     selected = set(vref.name for vref in aliases)
   293                     # now copy original selection and groups
   295                     # now copy original selection and groups
   294                     for term in origselection:
   296                     for term in origselection:
   295                         newselect.append_selected(term.copy(newselect))
   297                         newselect.append_selected(term.copy(newselect))
   296                     if select.orderby:
   298                     if select.orderby:
   297                         newselect.set_orderby([s.copy(newselect) for s in select.orderby])
   299                         sortterms = []
       
   300                         for sortterm in select.orderby:
       
   301                             sortterms.append(sortterm.copy(newselect))
       
   302                             for fnode in sortterm.get_nodes(Function):
       
   303                                 if fnode.name == 'FTIRANK':
       
   304                                     # we've to fetch the has_text relation as well
       
   305                                     var = fnode.children[0].variable
       
   306                                     rel = iter(var.stinfo['ftirels']).next()
       
   307                                     assert not rel.ored(), 'unsupported'
       
   308                                     newselect.add_restriction(rel.copy(newselect))
       
   309                                     # remove relation from the orig select and
       
   310                                     # cleanup variable stinfo
       
   311                                     rel.parent.remove(rel)
       
   312                                     var.stinfo['ftirels'].remove(rel)
       
   313                                     var.stinfo['relations'].remove(rel)
       
   314                                     # XXX not properly re-annotated after security insertion?
       
   315                                     newvar = newselect.get_variable(var.name)
       
   316                                     newvar.stinfo.setdefault('ftirels', set()).add(rel)
       
   317                                     newvar.stinfo.setdefault('relations', set()).add(rel)
       
   318                         newselect.set_orderby(sortterms)
   298                         _expand_selection(select.orderby, selected, aliases, select, newselect)
   319                         _expand_selection(select.orderby, selected, aliases, select, newselect)
   299                         select.orderby = () # XXX dereference?
   320                         select.orderby = () # XXX dereference?
   300                     if select.groupby:
   321                     if select.groupby:
   301                         newselect.set_groupby([g.copy(newselect) for g in select.groupby])
   322                         newselect.set_groupby([g.copy(newselect) for g in select.groupby])
   302                         _expand_selection(select.groupby, selected, aliases, select, newselect)
   323                         _expand_selection(select.groupby, selected, aliases, select, newselect)
   337                     add_noinvariant(noinvariant, restricted, myrqlst, nbtrees)
   358                     add_noinvariant(noinvariant, restricted, myrqlst, nbtrees)
   338                 if () in localchecks:
   359                 if () in localchecks:
   339                     select.set_possible_types(localchecks[()])
   360                     select.set_possible_types(localchecks[()])
   340                     add_types_restriction(self.schema, select)
   361                     add_types_restriction(self.schema, select)
   341                     add_noinvariant(noinvariant, restricted, select, nbtrees)
   362                     add_noinvariant(noinvariant, restricted, select, nbtrees)
       
   363                 self.rqlhelper.annotate(union)
   342 
   364 
   343     def _check_permissions(self, rqlst):
   365     def _check_permissions(self, rqlst):
   344         """return a dict defining "local checks", e.g. RQLExpression defined in
   366         """return a dict defining "local checks", e.g. RQLExpression defined in
   345         the schema that should be inserted in the original query
   367         the schema that should be inserted in the original query
   346 
   368 
   569         # some cache usage stats
   591         # some cache usage stats
   570         self.cache_hit, self.cache_miss = 0, 0
   592         self.cache_hit, self.cache_miss = 0, 0
   571         # rql parsing / analysing helper
   593         # rql parsing / analysing helper
   572         self.solutions = repo.vreg.solutions
   594         self.solutions = repo.vreg.solutions
   573         rqlhelper = repo.vreg.rqlhelper
   595         rqlhelper = repo.vreg.rqlhelper
       
   596         # set backend on the rql helper, will be used for function checking
       
   597         rqlhelper.backend = repo.config.sources()['system']['db-driver']
   574         self._parse = rqlhelper.parse
   598         self._parse = rqlhelper.parse
   575         self._annotate = rqlhelper.annotate
   599         self._annotate = rqlhelper.annotate
   576         # rql planner
   600         # rql planner
   577         # note: don't use repo.sources, may not be built yet, and also "admin"
   601         # note: don't use repo.sources, may not be built yet, and also "admin"
   578         #       isn't an actual source
   602         #       isn't an actual source