# HG changeset patch # User Laurent Peuch # Date 1564630965 -7200 # Node ID d91c229de97f8eb7a377580b9581d2d25528334b # Parent 7df6c6048bc8f9a19a057bc700810dca9c0bf721 [debug/rql] bind a uniq token per rql to trace its decomposition This is aimed to be used by the RQL debug panel (and the SQL one later on) but can also be used by other debugging tools. diff -r 7df6c6048bc8 -r d91c229de97f cubicweb/server/querier.py --- a/cubicweb/server/querier.py Thu Aug 01 02:51:52 2019 +0200 +++ b/cubicweb/server/querier.py Thu Aug 01 05:42:45 2019 +0200 @@ -18,6 +18,7 @@ """Helper classes to execute RQL queries on a set of sources, performing security checking and data aggregation. """ +import uuid from itertools import repeat from rql import RQLSyntaxError, CoercionError @@ -164,6 +165,8 @@ self.querier = querier self.schema = querier.schema self.rqlhelper = cnx.vreg.rqlhelper + # tracing token for debugging + self.rql_query_tracing_token = None def annotate_rqlst(self): if not self.rqlst.annotated: @@ -179,6 +182,7 @@ def execute(self): """execute a plan and return resulting rows""" for step in self.steps: + step.rql_query_tracing_token = self.rql_query_tracing_token result = step.execute() # the latest executed step contains the full query result return result @@ -552,6 +556,7 @@ # make an execution plan plan = self.plan_factory(rqlst, args, cnx) plan.cache_key = cachekey + plan.rql_query_tracing_token = str(uuid.uuid4()) self._planner.build_plan(plan) # execute the plan try: diff -r 7df6c6048bc8 -r d91c229de97f cubicweb/server/session.py --- a/cubicweb/server/session.py Thu Aug 01 02:51:52 2019 +0200 +++ b/cubicweb/server/session.py Thu Aug 01 05:42:45 2019 +0200 @@ -790,11 +790,12 @@ return service.call(**kwargs) @_open_only - def system_sql(self, sql, args=None, rollback_on_failure=True): + def system_sql(self, sql, args=None, rollback_on_failure=True, rql_query_tracing_token=None): """return a sql cursor on the system database""" source = self.repo.system_source try: - return source.doexec(self, sql, args, rollback=rollback_on_failure) + return source.doexec(self, sql, args, rollback=rollback_on_failure, + rql_query_tracing_token=rql_query_tracing_token) except (source.OperationalError, source.InterfaceError): if not rollback_on_failure: raise diff -r 7df6c6048bc8 -r d91c229de97f cubicweb/server/sources/native.py --- a/cubicweb/server/sources/native.py Thu Aug 01 02:51:52 2019 +0200 +++ b/cubicweb/server/sources/native.py Thu Aug 01 05:42:45 2019 +0200 @@ -499,7 +499,7 @@ continue raise AuthenticationError() - def syntax_tree_search(self, cnx, union, args=None, cachekey=None): + def syntax_tree_search(self, cnx, union, args=None, cachekey=None, rql_query_tracing_token=None): """return result from this source for a rql query (actually from a rql syntax tree and a solution dictionary mapping each used variable to a possible type). If cachekey is given, the query @@ -523,7 +523,7 @@ self._cache[cachekey] = sql, qargs, cbs args = self.merge_args(args, qargs) assert isinstance(sql, str), repr(sql) - cursor = cnx.system_sql(sql, args) + cursor = cnx.system_sql(sql, args, rql_query_tracing_token=rql_query_tracing_token) results = self.process_result(cursor, cnx, cbs) assert dbg_results(results) return results @@ -680,7 +680,7 @@ self.doexec(cnx, sql, attrs) @statsd_timeit - def doexec(self, cnx, query, args=None, rollback=True): + def doexec(self, cnx, query, args=None, rollback=True, rql_query_tracing_token=None): """Execute a query. it's a function just so that it shows up in profiling """ diff -r 7df6c6048bc8 -r d91c229de97f cubicweb/server/ssplanner.py --- a/cubicweb/server/ssplanner.py Thu Aug 01 02:51:52 2019 +0200 +++ b/cubicweb/server/ssplanner.py Thu Aug 01 05:42:45 2019 +0200 @@ -344,6 +344,7 @@ def __init__(self, plan, union): Step.__init__(self, plan) self.union = union + self.rql_query_tracing_token = None def execute(self): """call .syntax_tree_search with the given syntax tree on each @@ -365,7 +366,8 @@ cachekey = union.as_string() # get results for query source = cnx.repo.system_source - result = source.syntax_tree_search(cnx, union, args, cachekey) + result = source.syntax_tree_search(cnx, union, args, cachekey, + rql_query_tracing_token=self.rql_query_tracing_token) return result def mytest_repr(self):