def class_indirection_set(source_set: irast.Set, target_scls: s_nodes.Node, *, optional: bool, ctx: context.ContextLevel) -> irast.Set: poly_set = new_set(stype=target_scls, ctx=ctx) rptr = source_set.rptr if (rptr is not None and not rptr.ptrcls.singular(ctx.env.schema, rptr.direction)): cardinality = irast.Cardinality.MANY else: cardinality = irast.Cardinality.ONE poly_set.path_id = irutils.type_indirection_path_id( source_set.path_id, target_scls, optional=optional, cardinality=cardinality, schema=ctx.env.schema) ptr = irast.Pointer(source=source_set, target=poly_set, ptrcls=poly_set.path_id.rptr(), direction=poly_set.path_id.rptr_dir()) poly_set.rptr = ptr return poly_set
def class_indirection_set( source_set: irast.Set, target_scls: s_nodes.Node, *, optional: bool, ctx: context.ContextLevel) -> irast.Set: poly_set = new_set(scls=target_scls, ctx=ctx) rptr = source_set.rptr if rptr is not None and not rptr.ptrcls.singular(rptr.direction): cardinality = s_pointers.PointerCardinality.ManyToMany else: cardinality = s_pointers.PointerCardinality.ManyToOne poly_set.path_id = irutils.type_indirection_path_id( source_set.path_id, target_scls, optional=optional, cardinality=cardinality) ptr = irast.Pointer( source=source_set, target=poly_set, ptrcls=poly_set.path_id.rptr(), direction=poly_set.path_id.rptr_dir() ) poly_set.rptr = ptr return poly_set
def extend_path(source_set: irast.Set, ptrcls: s_pointers.Pointer, direction: PtrDir = PtrDir.Outbound, target: typing.Optional[s_nodes.Node] = None, *, ignore_computable: bool = False, force_computable: bool = False, unnest_fence: bool = False, same_computable_scope: bool = False, ctx: context.ContextLevel) -> irast.Set: """Return a Set node representing the new path tip.""" if ptrcls.is_link_property(ctx.env.schema): src_path_id = source_set.path_id.ptr_path() else: if direction != s_pointers.PointerDirection.Inbound: source = ptrcls.get_near_endpoint(ctx.env.schema, direction) if not source_set.stype.issubclass(ctx.env.schema, source): # Polymorphic link reference source_set = class_indirection_set(source_set, source, optional=True, ctx=ctx) src_path_id = source_set.path_id if target is None: target = ptrcls.get_far_endpoint(ctx.env.schema, direction) path_id = src_path_id.extend(ptrcls, direction, target, ns=ctx.path_id_namespace, schema=ctx.env.schema) target_set = new_set(stype=target, path_id=path_id, ctx=ctx) ptr = irast.Pointer(source=source_set, target=target_set, ptrcls=ptrcls, direction=direction) target_set.rptr = ptr if (not ignore_computable and _is_computable_ptr( ptrcls, force_computable=force_computable, ctx=ctx)): target_set = computable_ptr_set( ptr, unnest_fence=unnest_fence, same_computable_scope=same_computable_scope, ctx=ctx) return target_set