# HG changeset patch # User Sylvain Thénault # Date 1323688189 -3600 # Node ID 96d343a5e01bd47fa5b2a2431542c4b68a76ce04 # Parent a4d8064bf3939b9bb408ad1ad74648f8a6106b41 [rql2sql] None for attributes in kwargs generate IS NULL, so should be considered in sql cache key. Closes #2116693 diff -r a4d8064bf393 -r 96d343a5e01b server/querier.py --- a/server/querier.py Fri Dec 09 12:57:22 2011 +0100 +++ b/server/querier.py Mon Dec 12 12:09:49 2011 +0100 @@ -668,7 +668,7 @@ print '*'*80 print 'querier input', repr(rql), repr(args) # parse the query and binds variables - cachekey = rql + cachekey = (rql,) try: if args: # search for named args in query which are eids (hence @@ -699,7 +699,7 @@ # we want queries such as "Any X WHERE X eid 9999" return an # empty result instead of raising UnknownEid return empty_rset(rql, args, rqlst) - if args and not rql in self._rql_ck_cache: + if args and rql not in self._rql_ck_cache: self._rql_ck_cache[rql] = eidkeys if eidkeys: cachekey = self._repo.querier_cache_key(session, rql, args, @@ -722,6 +722,11 @@ # a new syntax tree is built from them. rqlst = rqlst.copy() self._annotate(rqlst) + if args: + # different SQL generated when some argument is None or not (IS + # NULL). This should be considered when computing sql cache key + cachekey += tuple(sorted([k for k,v in args.iteritems() + if v is None])) # make an execution plan plan = self.plan_factory(rqlst, args, session) plan.cache_key = cachekey diff -r a4d8064bf393 -r 96d343a5e01b server/ssplanner.py --- a/server/ssplanner.py Fri Dec 09 12:57:22 2011 +0100 +++ b/server/ssplanner.py Mon Dec 12 12:09:49 2011 +0100 @@ -392,7 +392,8 @@ # cachekey if inputmap or self.plan.cache_key is None: cachekey = None - # union may have been splited into subqueries, rebuild a cache key + # union may have been splited into subqueries, in which case we can't + # use plan.cache_key, rebuild a cache key elif isinstance(self.plan.cache_key, tuple): cachekey = list(self.plan.cache_key) cachekey[0] = union.as_string() diff -r a4d8064bf393 -r 96d343a5e01b server/test/unittest_querier.py --- a/server/test/unittest_querier.py Fri Dec 09 12:57:22 2011 +0100 +++ b/server/test/unittest_querier.py Mon Dec 12 12:09:49 2011 +0100 @@ -1495,5 +1495,11 @@ rset = self.execute('Any X WHERE X is CWUser, X has_text "bidule", X in_state S, S name SN') self.assertEqual(rset.rows, [[peid]]) + + def test_nonregr_sql_cache(self): + # different SQL generated when 'name' is None or not (IS NULL). + self.assertFalse(self.execute('Any X WHERE X is CWEType, X name %(name)s', {'name': None})) + self.assertTrue(self.execute('Any X WHERE X is CWEType, X name %(name)s', {'name': 'CWEType'})) + if __name__ == '__main__': unittest_main()