# HG changeset patch # User Sylvain Thénault # Date 1265123988 -3600 # Node ID 410c99a917fa5d7dfa89d16353997529dae40885 # Parent 1f777d13a76b7f91d050c2bddb48430d829f4352 fix rset.related_entity with variables coming from subquery while some others not diff -r 1f777d13a76b -r 410c99a917fa rset.py --- 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) diff -r 1f777d13a76b -r 410c99a917fa test/unittest_rset.py --- 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