[req] fix find() generating non-rewritable rql on non final relations
When filtering on a relation, find() was generating rql like
'Any X WHERE X is ETYPE, X relation EID' which work without being rewritten (it
should probably not), but when applying some rewrite (eg. permissions) it raise
in rqlrewrite code.
def _use_orig_term(self, snippet_varname, term):
...
> self.rewritten[key] = term.name
E AttributeError: 'Constant' object has no attribute 'name'
Generate valid rql instead 'Any X WHERE X is ETYPE, X relation Y, Y eid EID'.
--- a/cubicweb/req.py Wed Apr 26 15:04:40 2017 +0200
+++ b/cubicweb/req.py Fri Apr 28 09:49:37 2017 +0200
@@ -229,9 +229,14 @@
parts.append('{var} {attr} X, {var} eid %(reverse_{attr})s'.format(
var=next(varmaker), attr=attr))
else:
- if attr not in eschema.subjrels:
+ rel = eschema.subjrels.get(attr)
+ if rel is None:
raise KeyError('{0} not in {1} subject relations'.format(attr, eschema))
- parts.append('X {attr} %({attr})s'.format(attr=attr))
+ if rel.final:
+ parts.append('X {attr} %({attr})s'.format(attr=attr))
+ else:
+ parts.append('X {attr} {var}, {var} eid %({attr})s'.format(
+ attr=attr, var=next(varmaker)))
rql = ', '.join(parts)
--- a/cubicweb/test/unittest_req.py Wed Apr 26 15:04:40 2017 +0200
+++ b/cubicweb/test/unittest_req.py Fri Apr 28 09:49:37 2017 +0200
@@ -132,7 +132,10 @@
firstname=u'adrien',
in_group=req.find('CWGroup', name=u'users').one())
- u = req.find('CWUser', login=u'cdevienne').one()
+ rset = req.find('CWUser', login=u'cdevienne')
+ self.assertEqual(rset.printable_rql(),
+ 'Any X WHERE X is CWUser, X login "cdevienne"')
+ u = rset.one()
self.assertEqual(u.firstname, u"Christophe")
users = list(req.find('CWUser').entities())
@@ -143,8 +146,11 @@
self.assertEqual(len(groups), 1)
self.assertEqual(groups[0].name, u'users')
- users = req.find('CWUser', in_group=groups[0]).entities()
- users = list(users)
+ rset = req.find('CWUser', in_group=groups[0])
+ self.assertEqual(rset.printable_rql(),
+ 'Any X WHERE X is CWUser, X in_group A, '
+ 'A eid {0}'.format(groups[0].eid))
+ users = list(rset.entities())
self.assertEqual(len(users), 2)
with self.assertRaisesRegexp(