fix rset.related_entity with variables coming from subquery while some others not
--- a/rset.py Mon Feb 01 19:11:14 2010 +0100
+++ b/rset.py Tue Feb 02 16:19:48 2010 +0100
@@ -530,26 +530,45 @@
result[-1][1] = i
return result
+ def _locate_query_params(self, rqlst, row, col):
+ locate_query_col = col
+ etype = self.description[row][col]
+ # final type, find a better one to locate the correct subquery
+ # (ambiguous if possible)
+ eschema = self.vreg.schema.eschema
+ if eschema(etype).final:
+ for select in rqlst.children:
+ try:
+ myvar = select.selection[col].variable
+ except AttributeError:
+ # not a variable
+ continue
+ for i in xrange(len(select.selection)):
+ if i == col:
+ continue
+ coletype = self.description[row][i]
+ # None description possible on column resulting from an outer join
+ if coletype is None or eschema(coletype).final:
+ continue
+ try:
+ ivar = select.selection[i].variable
+ except AttributeError:
+ # not a variable
+ continue
+ # check variables don't comes from a subquery or are both
+ # coming from the same subquery
+ if getattr(ivar, 'query', None) is getattr(myvar, 'query', None):
+ etype = coletype
+ locate_query_col = i
+ if len(self.column_types(i)) > 1:
+ return etype, locate_query_col
+ return etype, locate_query_col
+
@cached
def related_entity(self, row, col):
"""try to get the related entity to extract format information if any"""
- locate_query_col = col
rqlst = self.syntax_tree()
- etype = self.description[row][col]
- if self.vreg.schema.eschema(etype).final:
- # final type, find a better one to locate the correct subquery
- # (ambiguous if possible)
- for i in xrange(len(rqlst.children[0].selection)):
- if i == col:
- continue
- coletype = self.description[row][i]
- if coletype is None:
- continue
- if not self.vreg.schema.eschema(coletype).final:
- etype = coletype
- locate_query_col = i
- if len(self.column_types(i)) > 1:
- break
+ etype, locate_query_col = self._locate_query_params(rqlst, row, col)
# UNION query, find the subquery from which this entity has been found
select = rqlst.locate_subquery(locate_query_col, etype, self.args)[0]
col = rqlst.subquery_selection_index(select, col)
--- a/test/unittest_rset.py Mon Feb 01 19:11:14 2010 +0100
+++ b/test/unittest_rset.py Tue Feb 02 16:19:48 2010 +0100
@@ -345,6 +345,14 @@
self.assertEquals(entity.eid, e.eid)
self.assertEquals(rtype, 'title')
+ def test_related_entity_trap_subquery(self):
+ req = self.request()
+ req.create_entity('Bookmark', title=u'test bookmark', path=u'')
+ self.execute('SET B bookmarked_by U WHERE U login "admin"')
+ rset = self.execute('Any B,T,L WHERE B bookmarked_by U, U login L '
+ 'WITH B,T BEING (Any B,T WHERE B is Bookmark, B title T)')
+ rset.related_entity(0, 2)
+
def test_entities(self):
rset = self.execute('Any U,G WHERE U in_group G')
# make sure we have at least one element