예제 #1
0
def get_schema_object(
        name: typing.Union[str, qlast.ObjectRef],
        module: typing.Optional[str] = None,
        *,
        item_types: typing.Optional[typing.List[s_obj.ObjectMeta]],
        ctx: context.ContextLevel,
        srcctx: typing.Optional[parsing.ParserContext] = None) -> s_obj.Object:

    if isinstance(name, qlast.ObjectRef):
        if srcctx is None:
            srcctx = name.context
        module = name.module
        name = name.name

    if module:
        name = sn.Name(name=name, module=module)

    if not module:
        result = ctx.aliased_views.get(name)
        if result is not None:
            return result

    try:
        scls = ctx.schema.get(name=name,
                              module_aliases=ctx.modaliases,
                              type=item_types)

    except s_err.ItemNotFoundError as e:
        qlerror = qlerrors.EdgeQLError(e.args[0], context=srcctx)
        s_utils.enrich_schema_lookup_error(qlerror,
                                           name,
                                           modaliases=ctx.modaliases,
                                           schema=ctx.schema,
                                           item_types=item_types)

        raise qlerror

    except s_err.SchemaError as e:
        raise qlerrors.EdgeQLError(e.args[0], context=srcctx)

    result = ctx.aliased_views.get(scls.name)
    if result is None:
        result = scls

    return result
예제 #2
0
def get_schema_object(
        name: typing.Union[str, qlast.ObjectRef],
        module: typing.Optional[str] = None,
        *,
        item_types: typing.Optional[typing.List[s_obj.ObjectMeta]],
        ctx: context.ContextLevel,
        srcctx: typing.Optional[parsing.ParserContext] = None) -> s_obj.Object:

    if isinstance(name, qlast.ObjectRef):
        if srcctx is None:
            srcctx = name.context
        module = name.module
        name = name.name
    elif isinstance(name, qlast.AnyType):
        return s_pseudo.Any.create()

    if module:
        name = sn.Name(name=name, module=module)

    if not module:
        result = ctx.aliased_views.get(name)
        if result is not None:
            return result

    try:
        stype = ctx.env.schema.get(name=name,
                                   module_aliases=ctx.modaliases,
                                   type=item_types)

    except errors.QueryError as e:
        s_utils.enrich_schema_lookup_error(e,
                                           name,
                                           modaliases=ctx.modaliases,
                                           schema=ctx.env.schema,
                                           item_types=item_types)
        raise

    result = ctx.aliased_views.get(stype.get_name(ctx.env.schema))
    if result is None:
        result = stype

    return result
예제 #3
0
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