diff -r 6fd2651719bc -r 48a84fb4f301 test/unittest_rqlrewrite.py --- 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()