401 select, col = rqlst.locate_subquery(col, etype, self.args) |
401 select, col = rqlst.locate_subquery(col, etype, self.args) |
402 else: |
402 else: |
403 select = rqlst |
403 select = rqlst |
404 # take care, due to outer join support, we may find None |
404 # take care, due to outer join support, we may find None |
405 # values for non final relation |
405 # values for non final relation |
406 for i, attr, x in attr_desc_iterator(select, col): |
406 for i, attr, role in attr_desc_iterator(select, col): |
407 outerselidx = rqlst.subquery_selection_index(select, i) |
407 outerselidx = rqlst.subquery_selection_index(select, i) |
408 if outerselidx is None: |
408 if outerselidx is None: |
409 continue |
409 continue |
410 if x == 'subject': |
410 if role == 'subject': |
411 rschema = eschema.subjrels[attr] |
411 rschema = eschema.subjrels[attr] |
412 if rschema.final: |
412 if rschema.final: |
413 entity[attr] = rowvalues[outerselidx] |
413 entity[attr] = rowvalues[outerselidx] |
414 continue |
414 continue |
415 tetype = rschema.objects(etype)[0] |
|
416 card = rschema.rproperty(etype, tetype, 'cardinality')[0] |
|
417 else: |
415 else: |
418 rschema = eschema.objrels[attr] |
416 rschema = eschema.objrels[attr] |
419 tetype = rschema.subjects(etype)[0] |
417 rdef = eschema.rdef(attr, role) |
420 card = rschema.rproperty(tetype, etype, 'cardinality')[1] |
|
421 # only keep value if it can't be multivalued |
418 # only keep value if it can't be multivalued |
422 if card in '1?': |
419 if rdef.role_cardinality(role) in '1?': |
423 if rowvalues[outerselidx] is None: |
420 if rowvalues[outerselidx] is None: |
424 if x == 'subject': |
421 if role == 'subject': |
425 rql = 'Any Y WHERE X %s Y, X eid %s' |
422 rql = 'Any Y WHERE X %s Y, X eid %s' |
426 else: |
423 else: |
427 rql = 'Any Y WHERE Y %s X, X eid %s' |
424 rql = 'Any Y WHERE Y %s X, X eid %s' |
428 rrset = ResultSet([], rql % (attr, entity.eid)) |
425 rrset = ResultSet([], rql % (attr, entity.eid)) |
429 req.decorate_rset(rrset) |
426 req.decorate_rset(rrset) |
430 else: |
427 else: |
431 rrset = self._build_entity(row, outerselidx).as_rset() |
428 rrset = self._build_entity(row, outerselidx).as_rset() |
432 entity.set_related_cache(attr, x, rrset) |
429 entity.set_related_cache(attr, role, rrset) |
433 return entity |
430 return entity |
434 |
431 |
435 @cached |
432 @cached |
436 def syntax_tree(self): |
433 def syntax_tree(self): |
437 """get the syntax tree for the source query. |
434 """get the syntax tree for the source query. |