cubicweb/server/querier.py
changeset 12759 ec834074ea25
parent 12758 db95a417a5ec
child 12834 492e1e0bbc6c
equal deleted inserted replaced
12758:db95a417a5ec 12759:ec834074ea25
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    18 """Helper classes to execute RQL queries on a set of sources, performing
    18 """Helper classes to execute RQL queries on a set of sources, performing
    19 security checking and data aggregation.
    19 security checking and data aggregation.
    20 """
    20 """
    21 import uuid
    21 import uuid
       
    22 import time
       
    23 import traceback
    22 from itertools import repeat
    24 from itertools import repeat
    23 
    25 
    24 from rql import RQLSyntaxError, CoercionError
    26 from rql import RQLSyntaxError, CoercionError
    25 from rql.stmts import Union
    27 from rql.stmts import Union
    26 from rql.nodes import ETYPE_PYOBJ_MAP, etype_from_pyobj, Relation, Exists, Not
    28 from rql.nodes import ETYPE_PYOBJ_MAP, etype_from_pyobj, Relation, Exists, Not
    28 
    30 
    29 from cubicweb import ValidationError, Unauthorized, UnknownEid, QueryError
    31 from cubicweb import ValidationError, Unauthorized, UnknownEid, QueryError
    30 from cubicweb.rqlrewrite import RQLRelationRewriter
    32 from cubicweb.rqlrewrite import RQLRelationRewriter
    31 from cubicweb import Binary, server
    33 from cubicweb import Binary, server
    32 from cubicweb.rset import ResultSet
    34 from cubicweb.rset import ResultSet
       
    35 from cubicweb.debug import emit_to_debug_channel
    33 
    36 
    34 from cubicweb.utils import QueryCache, RepeatList
    37 from cubicweb.utils import QueryCache, RepeatList
    35 from cubicweb.misc.source_highlight import highlight_terminal
    38 from cubicweb.misc.source_highlight import highlight_terminal
    36 from cubicweb.server.rqlannotation import SQLGenAnnotator, set_qdata
    39 from cubicweb.server.rqlannotation import SQLGenAnnotator, set_qdata
    37 from cubicweb.server.ssplanner import READ_ONLY_RTYPES, add_types_restriction
    40 from cubicweb.server.ssplanner import READ_ONLY_RTYPES, add_types_restriction
   556         # make an execution plan
   559         # make an execution plan
   557         plan = self.plan_factory(rqlst, args, cnx)
   560         plan = self.plan_factory(rqlst, args, cnx)
   558         plan.cache_key = cachekey
   561         plan.cache_key = cachekey
   559         plan.rql_query_tracing_token = str(uuid.uuid4())
   562         plan.rql_query_tracing_token = str(uuid.uuid4())
   560         self._planner.build_plan(plan)
   563         self._planner.build_plan(plan)
       
   564 
       
   565         query_debug_informations = {
       
   566             "rql": rql,
       
   567             "rql_query_tracing_token": plan.rql_query_tracing_token,
       
   568             "args": args,
       
   569             # remove the last part of the stack which is: this line
       
   570             "callstack": "".join(traceback.format_stack()[:-1]),
       
   571             "description": "",
       
   572         }
       
   573 
       
   574         start = time.time()
       
   575 
   561         # execute the plan
   576         # execute the plan
   562         try:
   577         try:
   563             results = plan.execute()
   578             results = plan.execute()
   564         except (Unauthorized, ValidationError):
   579         except (Unauthorized, ValidationError):
   565             # getting an Unauthorized/ValidationError exception means the
   580             # getting an Unauthorized/ValidationError exception means the
   571             # * don't rollback if we're in the commit process, will be handled
   586             # * don't rollback if we're in the commit process, will be handled
   572             #   by the connection
   587             #   by the connection
   573             if cnx.commit_state is None:
   588             if cnx.commit_state is None:
   574                 cnx.commit_state = 'uncommitable'
   589                 cnx.commit_state = 'uncommitable'
   575             raise
   590             raise
       
   591 
       
   592         query_debug_informations["time"] = ((time.time() - start) * 1000)
       
   593         query_debug_informations["result"] = results
       
   594 
   576         # build a description for the results if necessary
   595         # build a description for the results if necessary
   577         descr = ()
   596         descr = ()
   578         if build_descr:
   597         if build_descr:
   579             if rqlst.TYPE == 'select':
   598             if rqlst.TYPE == 'select':
   580                 # sample selection
   599                 # sample selection
   594                 basedescr = [None] * len(plan.selected)
   613                 basedescr = [None] * len(plan.selected)
   595                 todetermine = list(zip(range(len(plan.selected)), repeat(False)))
   614                 todetermine = list(zip(range(len(plan.selected)), repeat(False)))
   596                 descr = _build_descr(cnx, results, basedescr, todetermine)
   615                 descr = _build_descr(cnx, results, basedescr, todetermine)
   597             # FIXME: get number of affected entities / relations on non
   616             # FIXME: get number of affected entities / relations on non
   598             # selection queries ?
   617             # selection queries ?
       
   618             query_debug_informations["description"] = descr
       
   619 
       
   620         emit_to_debug_channel("rql", query_debug_informations)
       
   621 
   599         # return a result set object
   622         # return a result set object
   600         return ResultSet(results, rql, args, descr)
   623         return ResultSet(results, rql, args, descr)
   601 
   624 
   602     # these are overridden by set_log_methods below
   625     # these are overridden by set_log_methods below
   603     # only defining here to prevent pylint from complaining
   626     # only defining here to prevent pylint from complaining