[web/facet] Use an Exists node in HasRelationFacet
The generated RQL now includes an EXISTS clause. For instance, one gets:
::
DISTINCT Any WHERE X is CWUser, EXISTS(X in_group A)
instead of:
::
DISTINCT Any WHERE X is CWUser, X in_group A
for a HasRelationFacet with ``rtype = 'in_group'``, which is more appropriate
for testing the existence of the relation.
Add a test for this facet along the way.
--- a/web/facet.py Wed Apr 01 13:39:30 2015 +0200
+++ b/web/facet.py Mon Feb 23 09:02:41 2015 +0100
@@ -1465,15 +1465,17 @@
def add_rql_restrictions(self):
"""add restriction for this facet into the rql syntax tree"""
- self.select.set_distinct(True) # XXX
value = self._cw.form.get(self.__regid__)
if not value: # no value sent for this facet
return
+ exists = nodes.Exists()
+ self.select.add_restriction(exists)
var = self.select.make_variable()
if self.role == 'subject':
- self.select.add_relation(self.filtered_variable, self.rtype, var)
+ subj, obj = self.filtered_variable, var
else:
- self.select.add_relation(var, self.rtype, self.filtered_variable)
+ subj, obj = var, self.filtered_variable
+ exists.add_relation(subj, self.rtype, obj)
class BitFieldFacet(AttributeFacet):
--- a/web/test/unittest_facet.py Wed Apr 01 13:39:30 2015 +0200
+++ b/web/test/unittest_facet.py Mon Feb 23 09:02:41 2015 +0100
@@ -129,8 +129,6 @@
self.assertEqual(f.select.as_string(),
'DISTINCT Any WHERE X is CWUser')
-
-
def test_relationattribute(self):
with self.admin_access.web_request() as req:
f, (guests, managers) = self._in_group_facet(req, cls=facet.RelationAttributeFacet)
@@ -150,6 +148,20 @@
self.assertEqual(f.select.as_string(),
"DISTINCT Any WHERE X is CWUser, X in_group E, E name 'guests'")
+ def test_hasrelation(self):
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepare_rqlst(req)
+ f = facet.HasRelationFacet(req, rset=rset,
+ select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+ f.__regid__ = 'has_group'
+ f.rtype = 'in_group'
+ f.role = 'subject'
+ f._cw.form[f.__regid__] = 'feed me'
+ f.add_rql_restrictions()
+ self.assertEqual(f.select.as_string(),
+ 'DISTINCT Any WHERE X is CWUser, EXISTS(X in_group A)')
+
def test_daterange(self):
with self.admin_access.web_request() as req:
rset, rqlst, filtered_variable = self.prepare_rqlst(req)