def tuple_indirection_set(path_tip: irast.Set, *, source: s_sources.Source, ptr_name: str, source_context: parsing.ParserContext, ctx: context.ContextLevel) -> irast.Set: el_name = ptr_name el_norm_name = source.normalize_index(ctx.env.schema, el_name) el_type = source.get_subtype(ctx.env.schema, el_name) path_id = irutils.tuple_indirection_path_id(path_tip.path_id, el_norm_name, el_type, schema=ctx.env.schema) expr = irast.TupleIndirection(expr=path_tip, name=el_norm_name, path_id=path_id, context=source_context) return generated_set(expr, ctx=ctx)
def _is_ptr_or_self_ref(ir_expr: irast.Base, srccls: s_sources.Source, schema: s_schema.Schema) -> bool: if not isinstance(ir_expr, irast.Set): return False else: ir_set = ir_expr return (isinstance(srccls, s_objtypes.ObjectType) and ir_set.expr is None and (ir_set.scls == srccls or (ir_set.rptr is not None and srccls.getptr( schema, ir_set.rptr.ptrcls.shortname) is not None)))
def resolve_ptr(near_endpoint: s_sources.Source, ptr_name: typing.Tuple[str, str], direction: s_pointers.PointerDirection, target: typing.Optional[s_nodes.Node] = None, *, source_context: typing.Optional[parsing.ParserContext] = None, ctx: context.ContextLevel) -> s_pointers.Pointer: ptr_module, ptr_nqname = ptr_name if ptr_module: pointer = schemactx.get_schema_ptr(name=ptr_nqname, module=ptr_module, ctx=ctx) pointer_name = pointer.name else: pointer_name = ptr_nqname ptr = None if isinstance(near_endpoint, s_sources.Source): ptr = near_endpoint.resolve_pointer(ctx.schema, pointer_name, direction=direction, look_in_children=False, include_inherited=True, far_endpoint=target) if ptr is None: if isinstance(near_endpoint, s_links.Link): msg = (f'{near_endpoint.displayname} has no property ' f'{pointer_name!r}') if target: msg += f'of type {target.name!r}' elif direction == s_pointers.PointerDirection.Outbound: msg = (f'{near_endpoint.displayname} has no link or property ' f'{pointer_name!r}') if target: msg += f'of type {target.name!r}' else: path = f'{near_endpoint.name}.{direction}{pointer_name}' if target: path += f'[IS {target.name}]' msg = f'{path} does not resolve to any known path', err = errors.EdgeQLReferenceError(msg, context=source_context) if direction == s_pointers.PointerDirection.Outbound: s_utils.enrich_schema_lookup_error( err, pointer_name, modaliases=ctx.modaliases, item_types=(s_pointers.Pointer, ), collection=near_endpoint.pointers.values(), schema=ctx.schema) raise err else: if direction == s_pointers.PointerDirection.Outbound: bptr = schemactx.get_schema_ptr(pointer_name, ctx=ctx) schema_cls = ctx.schema.get('schema::ScalarType') if bptr.shortname == 'std::__type__': ptr = bptr.derive(ctx.schema, near_endpoint, schema_cls) if ptr is None: # Reference to a property on non-object msg = 'invalid property reference on a primitive type expression' raise errors.EdgeQLReferenceError(msg, context=source_context) return ptr