예제 #1
0
def ast_objref_to_objref(node: ql_ast.ObjectRef,
                         *,
                         metaclass: typing.Optional[so.ObjectMeta] = None,
                         modaliases: typing.Dict[typing.Optional[str], str],
                         schema) -> so.Object:

    if metaclass is not None and issubclass(metaclass, so.GlobalObject):
        return schema.get_global(metaclass, node.name)

    nqname = node.name
    module = node.module
    if module is not None:
        lname = sn.Name(module=module, name=nqname)
    else:
        lname = nqname
    obj = schema.get(lname, module_aliases=modaliases, default=None)
    if obj is not None:
        return obj

    if module is None:
        err = errors.InvalidReferenceError(
            f'reference to a non-existent schema item {nqname!r}',
            context=node.context)
        enrich_schema_lookup_error(
            err,
            lname,
            modaliases=modaliases,
            schema=schema,
            item_types=(metaclass, ) if metaclass is not None else None)
        raise err

    return so.ObjectRef(name=sn.Name(module=module, name=nqname))
예제 #2
0
    def __new__(cls, name, module=None):
        if not name:
            raise NameError('name must not be empty')

        if isinstance(name, SchemaName):
            _name = name.name
            _module = name.module
        elif module is not None:
            _name = name
            _module = module
        else:
            _module, _, _name = name.rpartition('::')

            if not _module:
                if not module:
                    err = 'improperly formed name: ' \
                          'module is not specified: {}'.format(name)
                    raise errors.InvalidReferenceError(err)
                else:
                    _module = module

        result = super().__new__(cls, _module + '::' + _name)
        result.name = _name
        result.module = _module

        return result
예제 #3
0
    def _check_factoring_errors(
        self,
        path_id: pathid.PathId,
        descendant: ScopeTreeNodeWithPathId,
        factor_point: ScopeTreeNode,
        existing: ScopeTreeNodeWithPathId,
        unnest_fence: bool,
        existing_finfo: FenceInfo,
        context: Optional[pctx.ParserContext],
    ) -> None:
        if existing_finfo.factoring_fence:
            # This node is already present in the surrounding
            # scope and cannot be factored out, such as
            # a reference to a correlated set inside a DML
            # statement.
            raise errors.InvalidReferenceError(
                f'cannot reference correlated set '
                f'{path_id.pformat()!r} here',
                context=context,
            )

        if (unnest_fence and (factor_point.find_child(
                path_id,
                in_branches=True,
                pfx_with_invariant_card=True,
        ) is None)
                and (not path_id.is_type_intersection_path() or
                     ((src_path := path_id.src_path()) and src_path is not None
                      and not self.is_visible(src_path)))):
예제 #4
0
    def get(self,
            name,
            default=_void,
            *,
            module_aliases=None,
            type=None,
            condition=None,
            label=None):
        def getter(schema, name):
            obj = schema._get_by_name(name, type=type)
            if obj is not None and condition is not None:
                if not condition(obj):
                    obj = None
            return obj

        obj = self._get(name,
                        getter=getter,
                        module_aliases=module_aliases,
                        default=default)

        if obj is not _void:
            return obj

        if label is None:
            if type is not None:
                if isinstance(type, tuple):
                    label = " or ".join(t.get_schema_class_displayname()
                                        for t in type)
                else:
                    label = type.get_schema_class_displayname()
            else:
                label = 'schema item'

        raise errors.InvalidReferenceError(f'{label} {name!r} does not exist')
예제 #5
0
def resolve_name(
    lname: sn.Name,
    *,
    metaclass: Optional[Type[so.Object]] = None,
    modaliases: Mapping[Optional[str], str],
    schema: s_schema.Schema,
) -> sn.Name:
    obj = schema.get(
        lname,
        type=metaclass,
        module_aliases=modaliases,
        default=None,
    )
    if obj is not None:
        name = obj.get_name(schema)
    elif isinstance(lname, sn.QualName):
        name = sn.QualName(
            module=modaliases.get(lname.module, lname.module),
            name=lname.name,
        )
    elif metaclass is not None and issubclass(metaclass, so.QualifiedObject):
        actual_module = modaliases.get(None)
        if actual_module is None:
            raise errors.InvalidReferenceError(
                'unqualified name and no default module alias set')
        name = sn.QualName(module=actual_module, name=lname.name)
    else:
        # Do not assume the name is fully-qualified unless asked
        # explicitly.
        name = lname

    return name
예제 #6
0
파일: setgen.py 프로젝트: signupsi/edgedb
def resolve_special_anchor(
        anchor: qlast.SpecialAnchor, *,
        ctx: context.ContextLevel) -> irast.Set:

    # '__source__' and '__subject__` can only appear as the
    # starting path label syntactically and must be pre-populated
    # by the compile() caller.

    if isinstance(anchor, qlast.SpecialAnchor):
        token = anchor.name
    else:
        raise errors.InternalServerError(
            f'unexpected special anchor kind: {anchor!r}'
        )

    anchors = ctx.anchors
    path_tip = anchors.get(token)

    if path_tip is None:
        raise errors.InvalidReferenceError(
            f'{token} cannot be used in this expression',
            context=anchor.context,
        )

    return path_tip
예제 #7
0
    def __new__(
        cls: Type[NameT],
        name: Union[SchemaName, str],
        module: Optional[str] = None,
    ) -> NameT:
        if not name:
            raise NameError('name must not be empty')

        if isinstance(name, SchemaName):
            _name = name.name
            _module = name.module
        elif module is not None:
            _name = name
            _module = module
        else:
            _module, _, _name = name.rpartition('::')

            if not _module:
                if not module:
                    err = 'improperly formed name: ' \
                          'module is not specified: {}'.format(name)
                    raise errors.InvalidReferenceError(err)
                else:
                    _module = module

        # Ignore below since Mypy doesn't believe you can pass `_fullname` to
        # object.__new__.
        _fullname = f"{_module}::{_name}"
        result = super().__new__(cls, _fullname)  # type: ignore
        result.name = _name
        result.module = _module

        return cast(NameT, result)
예제 #8
0
파일: schema.py 프로젝트: yew1eb/edgedb
    def _delete(self, obj: so.Object) -> Schema:
        data = self._id_to_data.get(obj.id)
        if data is None:
            raise errors.InvalidReferenceError(
                f'cannot delete {obj!r}: not in this schema')

        name = data['name']

        updates = {}

        name_to_id, shortname_to_id, globalname_to_id = self._update_obj_name(
            obj.id, self._id_to_type[obj.id], name, None)

        refs_to = self._update_refs_to(obj, self._id_to_data[obj.id], None)

        updates.update(
            dict(
                name_to_id=name_to_id,
                shortname_to_id=shortname_to_id,
                globalname_to_id=globalname_to_id,
                id_to_data=self._id_to_data.delete(obj.id),
                id_to_type=self._id_to_type.delete(obj.id),
                refs_to=refs_to,
            ))

        return self._replace(**updates)  # type: ignore
예제 #9
0
def _get_local_obj(
    refname: s_name.QualName,
    tracer_type: Type[qltracer.NamedObject],
    sourcectx: Optional[parsing.ParserContext],
    *,
    ctx: LayoutTraceContext,
) -> Optional[qltracer.NamedObject]:

    obj = ctx.objects.get(refname)

    if isinstance(obj, s_pseudo.PseudoType):
        raise errors.SchemaError(
            f'invalid type: {obj.get_verbosename(ctx.schema)} is a generic '
            f'type and they are not supported in user-defined schema',
            context=sourcectx,
        )

    elif obj is not None and not isinstance(obj, tracer_type):
        obj_type = TRACER_TO_REAL_TYPE_MAP[type(obj)]
        real_type = TRACER_TO_REAL_TYPE_MAP[tracer_type]
        raise errors.InvalidReferenceError(
            f'{str(refname)!r} exists, but is '
            f'{english.add_a(obj_type.get_schema_class_displayname())}, '
            f'not {english.add_a(real_type.get_schema_class_displayname())}',
            context=sourcectx,
        )

    return obj
예제 #10
0
    def _delete(self, obj):
        data = self._id_to_data.get(obj.id)
        if data is None:
            raise errors.InvalidReferenceError(
                f'cannot delete {obj!r}: not in this schema')

        name = data['name']

        updates = {}

        if isinstance(obj, s_modules.Module):
            updates['modules'] = self._modules.delete(name)

        name_to_id, shortname_to_id = self._update_obj_name(
            obj.id, self._id_to_type[obj.id], name, None)

        refs_to = self._update_refs_to(obj, self._id_to_data[obj.id], None)

        updates.update(
            dict(
                name_to_id=name_to_id,
                shortname_to_id=shortname_to_id,
                id_to_data=self._id_to_data.delete(obj.id),
                id_to_type=self._id_to_type.delete(obj.id),
                refs_to=refs_to,
            ))

        return self._replace(**updates)
예제 #11
0
파일: setgen.py 프로젝트: joe2hpimn/edgedb
def resolve_ptr(near_endpoint: s_sources.Source,
                pointer_name: str,
                *,
                direction: s_pointers.PointerDirection = (
                    s_pointers.PointerDirection.Outbound),
                source_context: typing.Optional[parsing.ParserContext] = None,
                ctx: context.ContextLevel) -> s_pointers.Pointer:

    if not isinstance(near_endpoint, s_sources.Source):
        # Reference to a property on non-object
        msg = 'invalid property reference on a primitive type expression'
        raise errors.InvalidReferenceError(msg, context=source_context)

    ctx.env.schema, ptr = near_endpoint.resolve_pointer(ctx.env.schema,
                                                        pointer_name,
                                                        direction=direction)

    if ptr is None:
        if isinstance(near_endpoint, s_links.Link):
            msg = (f'{near_endpoint.get_displayname(ctx.env.schema)} '
                   f'has no property {pointer_name!r}')

        elif direction == s_pointers.PointerDirection.Outbound:
            msg = (f'{near_endpoint.get_displayname(ctx.env.schema)} '
                   f'has no link or property {pointer_name!r}')

        else:
            nep_name = near_endpoint.get_displayname(ctx.env.schema)
            path = f'{nep_name}.{direction}{pointer_name}'
            msg = f'{path!r} does not resolve to any known path'

        err = errors.InvalidReferenceError(msg, context=source_context)

        if direction == s_pointers.PointerDirection.Outbound:
            near_enpoint_pointers = near_endpoint.get_pointers(ctx.env.schema)
            s_utils.enrich_schema_lookup_error(
                err,
                pointer_name,
                modaliases=ctx.modaliases,
                item_types=(s_pointers.Pointer, ),
                collection=near_enpoint_pointers.objects(ctx.env.schema),
                schema=ctx.env.schema)

        raise err

    return ptr
예제 #12
0
 def get_global(self, objtype, name, default=_void):
     obj_id = self._globalname_to_id.get((objtype, name))
     if obj_id is not None:
         return self._id_to_type[obj_id]
     elif default is not _void:
         return default
     else:
         raise errors.InvalidReferenceError(
             f'reference to a non-existent {objtype.__name__}: {name}')
예제 #13
0
 def get_global(self, objtype, name, default=_void):
     obj_id = self._globalname_to_id.get((objtype, name))
     if obj_id is not None:
         return self._id_to_type[obj_id]
     elif default is not _void:
         return default
     else:
         desc = objtype.get_schema_class_displayname()
         raise errors.InvalidReferenceError(
             f'{desc} {name!r} does not exist')
예제 #14
0
    def get_operators(self, name, default=_void, *, module_aliases=None):
        funcs = self._get(name,
                          getter=_get_operators,
                          module_aliases=module_aliases,
                          default=default)

        if funcs is not _void:
            return funcs

        raise errors.InvalidReferenceError(f'operator {name!r} does not exist')
예제 #15
0
파일: indexes.py 프로젝트: syyunn/edgedb
 def get_object(self, schema, context, *, name=None):
     try:
         return super().get_object(schema, context, name=name)
     except errors.InvalidReferenceError:
         referrer_ctx = self.get_referrer_context(context)
         referrer = referrer_ctx.scls
         expr = self.get_attribute_value('expr')
         raise errors.InvalidReferenceError(
             f"index {expr.origtext!r} does not exist on "
             f"{referrer.get_verbosename(schema)}") from None
예제 #16
0
 def get_by_id(self, obj_id, default=_void):
     try:
         return self._id_to_type[obj_id]
     except KeyError:
         if default is _void:
             raise errors.InvalidReferenceError(
                 f'reference to a non-existent schema item {obj_id}'
                 f' in schema {self!r}') from None
         else:
             return default
예제 #17
0
파일: types.py 프로젝트: dungeon2567/edgedb
    def normalize_index(self, schema, field: str) -> str:
        if self.named and field.isdecimal():
            idx = int(field)
            if idx >= 0 and idx < len(self.element_types):
                return list(self.element_types.keys())[idx]
            else:
                raise errors.InvalidReferenceError(
                    f'{field} is not a member of '
                    f'{self.get_displayname(schema)}')

        return field
예제 #18
0
    def get_operators(self, name, default=_void, *, module_aliases=None):
        funcs = self._get(name,
                          getter=_get_operators,
                          module_aliases=module_aliases,
                          default=default)

        if funcs is not _void:
            return funcs

        raise errors.InvalidReferenceError(
            f'reference to a non-existent operator: {name}')
예제 #19
0
    def normalize_index(self, schema, field: str) -> str:
        if self.is_named(schema) and field.isdecimal():
            idx = int(field)
            el_names = self.get_element_names(schema)
            if idx >= 0 and idx < len(el_names):
                return el_names[idx]
            else:
                raise errors.InvalidReferenceError(
                    f'{field} is not a member of '
                    f'{self.get_displayname(schema)}')

        return field
예제 #20
0
파일: types.py 프로젝트: dungeon2567/edgedb
    def get_subtype(self, schema, field: str) -> Type:
        # index can be a name or a position
        if field.isdecimal():
            idx = int(field)
            if idx >= 0 and idx < len(self.element_types):
                return list(self.element_types.values())[idx]

        elif self.named and field in self.element_types:
            return self.element_types[field]

        raise errors.InvalidReferenceError(
            f'{field} is not a member of {self.get_displayname(schema)}')
예제 #21
0
파일: types.py 프로젝트: dungeon2567/edgedb
    def index_of(self, schema, field: str) -> int:
        if field.isdecimal():
            idx = int(field)
            if idx >= 0 and idx < len(self.element_types):
                if self.named:
                    return list(self.element_types.keys()).index(field)
                else:
                    return idx
        elif self.named and field in self.element_types:
            return list(self.element_types.keys()).index(field)

        raise errors.InvalidReferenceError(
            f'{field} is not a member of {self.get_displayname(schema)}')
예제 #22
0
파일: schema.py 프로젝트: yew1eb/edgedb
    def get_by_id(  # NoQA: F811
        self,
        obj_id: uuid.UUID,
        default: Union[so.Object_T, so.NoDefaultT, None] = so.NoDefault,
        *,
        type: Optional[Type[so.Object_T]] = None,
    ) -> Optional[so.Object_T]:
        try:
            obj = self._id_to_type[obj_id]
        except KeyError:
            if default is so.NoDefault:
                raise errors.InvalidReferenceError(
                    f'reference to a non-existent schema item {obj_id}'
                    f' in schema {self!r}') from None
            else:
                return default
        else:
            if type is not None and not isinstance(obj, type):
                raise errors.InvalidReferenceError(
                    f'schema object {obj_id!r} exists, but is not '
                    f'{type.get_schema_class_displayname()}')

            return cast(so.Object_T, obj)
예제 #23
0
    def get(self, name, default=_void, *, module_aliases=None, type=None):
        def getter(schema, name):
            return schema._get_by_name(name, type=type)

        obj = self._get(name,
                        getter=getter,
                        module_aliases=module_aliases,
                        default=default)

        if obj is not _void:
            return obj

        raise errors.InvalidReferenceError(
            f'reference to a non-existent schema item {name}')
예제 #24
0
파일: schema.py 프로젝트: mrs45p/edgedb
 def get_by_id(  # NoQA: F811
     self,
     obj_id: uuid.UUID,
     default: Union[so.Object, so.NoDefaultT, None] = so.NoDefault,
 ) -> Optional[so.Object]:
     try:
         return self._id_to_type[obj_id]
     except KeyError:
         if default is so.NoDefault:
             raise errors.InvalidReferenceError(
                 f'reference to a non-existent schema item {obj_id}'
                 f' in schema {self!r}') from None
         else:
             return default
예제 #25
0
파일: schema.py 프로젝트: syyunn/edgedb
    def get_functions(self,
                      name,
                      default=so.NoDefault,
                      *,
                      module_aliases=None):
        funcs = self._get(name,
                          getter=_get_functions,
                          module_aliases=module_aliases,
                          default=default)

        if funcs is not so.NoDefault:
            return funcs

        raise errors.InvalidReferenceError(f'function {name!r} does not exist')
예제 #26
0
파일: schema.py 프로젝트: yew1eb/edgedb
 def get_global(  # NoQA: F811
     self,
     objtype: Type[so.Object_T],
     name: str,
     default: Union[so.Object_T, so.NoDefaultT, None] = so.NoDefault,
 ) -> Optional[so.Object_T]:
     obj_id = self._globalname_to_id.get((objtype, name))
     if obj_id is not None:
         return cast(so.Object_T, self._id_to_type[obj_id])
     elif default is not so.NoDefault:
         return default
     else:
         desc = objtype.get_schema_class_displayname()
         raise errors.InvalidReferenceError(
             f'{desc} {name!r} does not exist')
예제 #27
0
    def get_subtype(self, schema, field: str) -> Type:
        # index can be a name or a position
        if field.isdecimal():
            idx = int(field)
            subtypes = list(self.get_subtypes(schema))
            if idx >= 0 and idx < len(subtypes):
                return subtypes[idx]

        elif self.is_named(schema):
            subtypes = dict(self.iter_subtypes(schema))
            if field in subtypes:
                return subtypes[field]

        raise errors.InvalidReferenceError(
            f'{field} is not a member of {self.get_displayname(schema)}')
예제 #28
0
        def from_string(
            cls: Type[QualNameT],
            name: str,
        ) -> QualNameT:

            module, _, nqname = name.rpartition('::')

            if not module:
                err = (f'improperly formed name {name!r}: '
                       f'module is not specified')
                raise errors.InvalidReferenceError(err)

            return cls(
                module=module,
                name=nqname,
            )
예제 #29
0
파일: indexes.py 프로젝트: zhutony/edgedb
 def get_object(  # type: ignore
     self,
     schema: s_schema.Schema,
     context: sd.CommandContext,
     *,
     name: Optional[str] = None,
 ) -> Optional[Index]:
     try:
         return super().get_object(schema, context, name=name)
     except errors.InvalidReferenceError:
         referrer_ctx = self.get_referrer_context_or_die(context)
         referrer = referrer_ctx.scls
         expr = self.get_attribute_value('expr')
         raise errors.InvalidReferenceError(
             f"index {expr.origtext!r} does not exist on "
             f"{referrer.get_verbosename(schema)}") from None
예제 #30
0
파일: schema.py 프로젝트: yew1eb/edgedb
    def get(  # NoQA: F811
        self,
        name: str,
        default: Union[so.Object_T, so.NoDefaultT, None] = so.NoDefault,
        *,
        module_aliases: Optional[Mapping[Optional[str], str]] = None,
        type: Optional[Type[so.Object_T]] = None,
        condition: Optional[Callable[[so.Object], bool]] = None,
        label: Optional[str] = None,
        sourcectx: Optional[parsing.ParserContext] = None,
    ) -> Optional[so.Object_T]:
        def getter(schema: Schema, name: str) -> Optional[so.Object]:
            obj = schema._get_by_name(name, type=type)
            if obj is not None and condition is not None:
                if not condition(obj):
                    obj = None
            return obj

        obj = self._get(name,
                        getter=getter,
                        module_aliases=module_aliases,
                        default=default)

        if obj is not so.NoDefault:
            return cast(so.Object_T, obj)

        if label is None:
            if type is not None:
                label = type.get_schema_class_displayname()
            else:
                label = 'schema item'

        refname = name

        if type is not None:
            if not sn.Name.is_qualified(refname):
                if module_aliases is not None:
                    default_module = module_aliases.get(None)
                    if default_module is not None:
                        refname = type.get_displayname_static(
                            f'{default_module}::{refname}', )
            else:
                refname = type.get_displayname_static(refname)

        raise errors.InvalidReferenceError(
            f'{label} {refname!r} does not exist', context=sourcectx)