[rset] Use RQL cache in syntax_tree method
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 03 Mar 2017 14:06:27 +0100
changeset 12063 4bcb58aa103a
parent 12062 601d65193619
child 12064 0c06abcf4f82
[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.
cubicweb/rset.py
cubicweb/test/unittest_rset.py
--- 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)