[rewrite] Fix crash when the main variable doesn't appear in the snippet's vargraph
Also, the added test discover another bug once the first has been fixed
(erroneous argument given to .rewrite recursive call).
Closes #3661918
--- a/rqlrewrite.py Thu Mar 13 15:33:22 2014 +0100
+++ b/rqlrewrite.py Thu Mar 13 17:32:40 2014 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -405,7 +405,7 @@
assert len(subquery.children) == 1
subselect = subquery.children[0]
RQLRewriter(self.session).rewrite(subselect, [(varmap, rqlexprs)],
- subselect.solutions, self.kwargs)
+ self.kwargs)
return
if varexistsmap is None:
# build an index for quick access to relations
@@ -790,7 +790,7 @@
vargraph = self.current_expr.vargraph
for existingvar in self.existingvars:
#path = has_path(vargraph, varname, existingvar)
- if has_path(vargraph, varname, existingvar):
+ if not varname in vargraph or has_path(vargraph, varname, existingvar):
return True
# no path from this variable to an existing variable
return False
--- a/test/unittest_rqlrewrite.py Thu Mar 13 15:33:22 2014 +0100
+++ b/test/unittest_rqlrewrite.py Thu Mar 13 17:32:40 2014 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -555,5 +555,40 @@
'AC is CWUser, E is CWUser, X is IN(Division, Societe)',
union.as_string())
+ def test_question_mark_attribute_snippet(self):
+ # see #3661918
+ from cubicweb.rqlrewrite import RQLRewriter
+ from logilab.common.decorators import monkeypatch
+ repotest.undo_monkey_patch()
+ orig_insert_snippets = RQLRewriter.insert_snippets
+ # patch insert_snippets and not rewrite, insert_snippets is already
+ # monkey patches (see above setupModule/repotest)
+ @monkeypatch(RQLRewriter)
+ def insert_snippets(self, snippets, varexistsmap=None):
+ # crash occurs if snippets are processed in a specific order, force
+ # destiny
+ if snippets[0][0] != {u'N': 'X'}:
+ snippets = list(reversed(snippets))
+ return orig_insert_snippets(self, snippets, varexistsmap)
+ try:
+ with self.temporary_permissions(
+ (self.schema['Affaire'],
+ {'read': (ERQLExpression('X ref "blah"'), )}),
+ (self.schema['Note'],
+ {'read': (ERQLExpression(
+ 'EXISTS(X inlined_affaire Z), EXISTS(Z owned_by U)'), )}),
+ ):
+ union = self.process(
+ 'Any A,COUNT(N) GROUPBY A '
+ 'WHERE A is Affaire, N? inlined_affaire A')
+ self.assertEqual('Any A,COUNT(N) GROUPBY A WHERE A is Affaire '
+ 'WITH N,A BEING (Any N,A WHERE N? inlined_affaire A, '
+ '(N is NULL) OR (EXISTS(EXISTS(N inlined_affaire B), '
+ 'EXISTS(B owned_by %(E)s), B is Affaire)), '
+ 'A is Affaire, N is Note, EXISTS(A ref "blah"))',
+ union.as_string())
+ finally:
+ RQLRewriter.insert_snippets = orig_insert_snippets
+
if __name__ == '__main__':
unittest_main()