453 select, col = rqlst.locate_subquery(col, etype, self.args) |
453 select, col = rqlst.locate_subquery(col, etype, self.args) |
454 else: |
454 else: |
455 select = rqlst |
455 select = rqlst |
456 # take care, due to outer join support, we may find None |
456 # take care, due to outer join support, we may find None |
457 # values for non final relation |
457 # values for non final relation |
458 for i, attr, x in attr_desc_iterator(select, col): |
458 for i, attr, role in attr_desc_iterator(select, col): |
459 outerselidx = rqlst.subquery_selection_index(select, i) |
459 outerselidx = rqlst.subquery_selection_index(select, i) |
460 if outerselidx is None: |
460 if outerselidx is None: |
461 continue |
461 continue |
462 if x == 'subject': |
462 if role == 'subject': |
463 rschema = eschema.subjrels[attr] |
463 rschema = eschema.subjrels[attr] |
464 if rschema.final: |
464 if rschema.final: |
465 entity[attr] = rowvalues[outerselidx] |
465 entity[attr] = rowvalues[outerselidx] |
466 continue |
466 continue |
467 tetype = rschema.objects(etype)[0] |
|
468 card = rschema.rproperty(etype, tetype, 'cardinality')[0] |
|
469 else: |
467 else: |
470 rschema = eschema.objrels[attr] |
468 rschema = eschema.objrels[attr] |
471 tetype = rschema.subjects(etype)[0] |
469 rdef = eschema.rdef(attr, role) |
472 card = rschema.rproperty(tetype, etype, 'cardinality')[1] |
|
473 # only keep value if it can't be multivalued |
470 # only keep value if it can't be multivalued |
474 if card in '1?': |
471 if rdef.role_cardinality(role) in '1?': |
475 if rowvalues[outerselidx] is None: |
472 if rowvalues[outerselidx] is None: |
476 if x == 'subject': |
473 if role == 'subject': |
477 rql = 'Any Y WHERE X %s Y, X eid %s' |
474 rql = 'Any Y WHERE X %s Y, X eid %s' |
478 else: |
475 else: |
479 rql = 'Any Y WHERE Y %s X, X eid %s' |
476 rql = 'Any Y WHERE Y %s X, X eid %s' |
480 rrset = ResultSet([], rql % (attr, entity.eid)) |
477 rrset = ResultSet([], rql % (attr, entity.eid)) |
481 req.decorate_rset(rrset) |
478 req.decorate_rset(rrset) |
482 else: |
479 else: |
483 rrset = self._build_entity(row, outerselidx).as_rset() |
480 rrset = self._build_entity(row, outerselidx).as_rset() |
484 entity.set_related_cache(attr, x, rrset) |
481 entity.set_related_cache(attr, role, rrset) |
485 return entity |
482 return entity |
486 |
483 |
487 @cached |
484 @cached |
488 def syntax_tree(self): |
485 def syntax_tree(self): |
489 """get the syntax tree for the source query. |
486 """get the syntax tree for the source query. |