Ejemplo n.º 1
0
def extend_path(
    source_set: irast.Set,
    ptrcls: s_pointers.Pointer,
    direction: PtrDir = PtrDir.Outbound,
    *,
    ignore_computable: bool = False,
    hoist_iterators: 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 is not s_pointers.PointerDirection.Inbound:
            source = ptrcls.get_near_endpoint(ctx.env.schema, direction)
            assert isinstance(source, s_types.Type)
            stype = get_set_type(source_set, ctx=ctx)
            if not stype.issubclass(ctx.env.schema, source):
                # Polymorphic link reference
                source_set = type_intersection_set(
                    source_set, source, optional=True, ctx=ctx)

        src_path_id = source_set.path_id

    expr_type = get_set_type(source_set, ctx=ctx).get_expr_type(ctx.env.schema)
    path_id = pathctx.extend_path_id(
        src_path_id,
        ptrcls=ptrcls,
        direction=direction,
        ns=ctx.path_id_namespace,
        include_descendants_in_ptrref=expr_type is s_types.ExprType.Update,
        ctx=ctx,
    )

    target = ptrcls.get_far_endpoint(ctx.env.schema, direction)
    assert isinstance(target, s_types.Type)
    target_set = new_set(stype=target, path_id=path_id, ctx=ctx)

    ptr = irast.Pointer(
        source=source_set,
        target=target_set,
        direction=direction,
        ptrref=path_id.rptr(),
    )

    target_set.rptr = ptr
    is_computable = _is_computable_ptr(ptrcls, ctx=ctx)
    if not ignore_computable and is_computable:
        target_set = computable_ptr_set(
            ptr,
            unnest_fence=unnest_fence,
            hoist_iterators=hoist_iterators,
            same_computable_scope=same_computable_scope,
            ctx=ctx,
        )

    return target_set
Ejemplo n.º 2
0
def extend_path(source_set: irast.Set,
                ptrcls: s_pointers.Pointer,
                direction: PtrDir = PtrDir.Outbound,
                target: typing.Optional[s_types.Type] = None,
                *,
                ignore_computable: bool = False,
                is_mut_assign: 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)
            stype = get_set_type(source_set, ctx=ctx)
            if not 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 = pathctx.extend_path_id(src_path_id,
                                     ptrcls=ptrcls,
                                     direction=direction,
                                     target=target,
                                     ns=ctx.path_id_namespace,
                                     ctx=ctx)

    target_set = new_set(stype=target, path_id=path_id, ctx=ctx)

    ptr = irast.Pointer(
        source=source_set,
        target=target_set,
        direction=direction,
        ptrref=path_id.rptr(),
    )

    target_set.rptr = ptr
    is_computable = _is_computable_ptr(ptrcls,
                                       is_mut_assign=is_mut_assign,
                                       ctx=ctx)
    if not ignore_computable and is_computable:
        target_set = computable_ptr_set(
            ptr,
            unnest_fence=unnest_fence,
            from_default_expr=is_mut_assign,
            same_computable_scope=same_computable_scope,
            ctx=ctx,
        )

    return target_set