[rset] Use RQL cache in syntax_tree method
This avoid several unnecessary parsings per HTTP request, since in most case
rset's rql is in the rql cache (since it has just been executed), while yapps
based parsing is known to be slow.
--- a/cubicweb/rset.py Fri Mar 17 07:32:48 2017 +0100
+++ b/cubicweb/rset.py Fri Mar 03 14:06:27 2017 +0100
@@ -27,7 +27,7 @@
from logilab.common.decorators import cached, clear_cache, copy_cache
from rql import nodes, stmts
-from cubicweb import NotAnEntity, NoResultError, MultipleResultsError
+from cubicweb import NotAnEntity, NoResultError, MultipleResultsError, UnknownEid
_MARKER = nullobject()
@@ -560,11 +560,21 @@
@cached
def syntax_tree(self):
- """return the syntax tree (:class:`rql.stmts.Union`) for the
- originating query. You can expect it to have solutions
- computed and it will be properly annotated.
+ """Return the **cached** syntax tree (:class:`rql.stmts.Union`) for the
+ originating query.
+
+ You can expect it to have solutions computed and it will be properly annotated.
+ Since this is a cached shared object, **you must not modify it**.
"""
- return self.req.vreg.parse(self.req, self.rql, self.args)
+ cnx = getattr(self.req, 'cnx', self.req)
+ try:
+ rqlst = cnx.repo.querier.rql_cache.get(cnx, self.rql, self.args)[0]
+ if not rqlst.annotated:
+ self.req.vreg.rqlhelper.annotate(rqlst)
+ return rqlst
+ except UnknownEid:
+ # unknown eid in args prevent usage of rql cache, but we still need a rql st
+ return self.req.vreg.parse(self.req, self.rql, self.args)
@cached
def column_types(self, col):
--- a/cubicweb/test/unittest_rset.py Fri Mar 17 07:32:48 2017 +0100
+++ b/cubicweb/test/unittest_rset.py Fri Mar 03 14:06:27 2017 +0100
@@ -89,7 +89,7 @@
self.rset = ResultSet([[12, 'adim'], [13, 'syt']],
'Any U,L where U is CWUser, U login L',
description=[['CWUser', 'String'], ['Bar', 'String']])
- self.rset.req = mock_object(vreg=self.vreg)
+ self.rset.req = mock_object(vreg=self.vreg, repo=self.repo)
def compare_urls(self, url1, url2):
info1 = urlsplit(url1)