528 last = row |
528 last = row |
529 if last is not None: |
529 if last is not None: |
530 result[-1][1] = i |
530 result[-1][1] = i |
531 return result |
531 return result |
532 |
532 |
|
533 def _locate_query_params(self, rqlst, row, col): |
|
534 locate_query_col = col |
|
535 etype = self.description[row][col] |
|
536 # final type, find a better one to locate the correct subquery |
|
537 # (ambiguous if possible) |
|
538 eschema = self.vreg.schema.eschema |
|
539 if eschema(etype).final: |
|
540 for select in rqlst.children: |
|
541 try: |
|
542 myvar = select.selection[col].variable |
|
543 except AttributeError: |
|
544 # not a variable |
|
545 continue |
|
546 for i in xrange(len(select.selection)): |
|
547 if i == col: |
|
548 continue |
|
549 coletype = self.description[row][i] |
|
550 # None description possible on column resulting from an outer join |
|
551 if coletype is None or eschema(coletype).final: |
|
552 continue |
|
553 try: |
|
554 ivar = select.selection[i].variable |
|
555 except AttributeError: |
|
556 # not a variable |
|
557 continue |
|
558 # check variables don't comes from a subquery or are both |
|
559 # coming from the same subquery |
|
560 if getattr(ivar, 'query', None) is getattr(myvar, 'query', None): |
|
561 etype = coletype |
|
562 locate_query_col = i |
|
563 if len(self.column_types(i)) > 1: |
|
564 return etype, locate_query_col |
|
565 return etype, locate_query_col |
|
566 |
533 @cached |
567 @cached |
534 def related_entity(self, row, col): |
568 def related_entity(self, row, col): |
535 """try to get the related entity to extract format information if any""" |
569 """try to get the related entity to extract format information if any""" |
536 locate_query_col = col |
|
537 rqlst = self.syntax_tree() |
570 rqlst = self.syntax_tree() |
538 etype = self.description[row][col] |
571 etype, locate_query_col = self._locate_query_params(rqlst, row, col) |
539 if self.vreg.schema.eschema(etype).final: |
|
540 # final type, find a better one to locate the correct subquery |
|
541 # (ambiguous if possible) |
|
542 for i in xrange(len(rqlst.children[0].selection)): |
|
543 if i == col: |
|
544 continue |
|
545 coletype = self.description[row][i] |
|
546 if coletype is None: |
|
547 continue |
|
548 if not self.vreg.schema.eschema(coletype).final: |
|
549 etype = coletype |
|
550 locate_query_col = i |
|
551 if len(self.column_types(i)) > 1: |
|
552 break |
|
553 # UNION query, find the subquery from which this entity has been found |
572 # UNION query, find the subquery from which this entity has been found |
554 select = rqlst.locate_subquery(locate_query_col, etype, self.args)[0] |
573 select = rqlst.locate_subquery(locate_query_col, etype, self.args)[0] |
555 col = rqlst.subquery_selection_index(select, col) |
574 col = rqlst.subquery_selection_index(select, col) |
556 if col is None: |
575 if col is None: |
557 # XXX unexpected, should fix subquery_selection_index ? |
576 # XXX unexpected, should fix subquery_selection_index ? |