# HG changeset patch # User Sylvain Thénault # Date 1488546387 -3600 # Node ID 4bcb58aa103a1c26af385ff472f523159f1a61a5 # Parent 601d6519361946cf09eae380f0b1debea85a1c05 [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. diff -r 601d65193619 -r 4bcb58aa103a cubicweb/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): diff -r 601d65193619 -r 4bcb58aa103a cubicweb/test/unittest_rset.py --- 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)