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
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