Пример #1
0
    def _apply_rebase_ast(self, context, node, op):
        from . import inheriting

        parent_ctx = context.get(sd.CommandContextToken)
        parent_op = parent_ctx.op
        rebase = next(
            iter(parent_op.get_subcommands(type=inheriting.RebaseNamedObject)))

        dropped = rebase.removed_bases
        added = rebase.added_bases

        if dropped:
            node.commands.append(
                qlast.AlterDropInherit(bases=[
                    qlast.ObjectRef(module=b.classname.module,
                                    name=b.classname.name) for b in dropped
                ]))

        for bases, pos in added:
            if isinstance(pos, tuple):
                pos_node = qlast.Position(position=pos[0],
                                          ref=qlast.ObjectRef(
                                              module=pos[1].classname.module,
                                              name=pos[1].classname.name))
            else:
                pos_node = qlast.Position(position=pos)

            node.commands.append(
                qlast.AlterAddInherit(bases=[
                    qlast.ObjectRef(module=b.classname.module,
                                    name=b.classname.name) for b in bases
                ],
                                      position=pos_node))
Пример #2
0
    def _float_to_path(self, token, context):
        from edgedb.lang.schema import pointers as s_pointers

        # make sure that the float is of the type 0.1
        parts = token.val.split('.')
        if not (len(parts) == 2 and parts[0].isdigit() and parts[1].isdigit()):
            raise EdgeQLSyntaxError(f"Unexpected {token.val!r}",
                                    context=token.context)

        # context for the AST is established manually here
        return [
            qlast.Ptr(
                ptr=qlast.ObjectRef(
                    name=parts[0],
                    context=token.context,
                ),
                direction=s_pointers.PointerDirection.Outbound,
                context=context,
            ),
            qlast.Ptr(
                ptr=qlast.ObjectRef(
                    name=parts[1],
                    context=token.context,
                ),
                direction=s_pointers.PointerDirection.Outbound,
                context=token.context,
            )
        ]
Пример #3
0
 def _apply_field_ast(self, context, node, op):
     if op.property == 'spectargets':
         if op.new_value:
             node.commands.append(qlast.AlterTarget(
                 targets=[
                     qlast.ObjectRef(name=t.classname.name,
                                     module=t.classname.module)
                     for t in op.new_value
                 ]
             ))
     elif op.property == 'target':
         if op.new_value:
             node.commands.append(qlast.AlterTarget(
                 targets=[
                     qlast.ObjectRef(
                         name=op.new_value.classname.name,
                         module=op.new_value.classname.module)
                 ]
             ))
     elif op.property == 'source':
         pass
     elif op.property == 'search':
         if op.new_value:
             v = qlast.Constant(value=str(op.new_value.weight))
             self._set_attribute_ast(context, node, 'search_weight', v)
         else:
             self._drop_attribute_ast(context, node, 'search_weight')
     else:
         super()._apply_field_ast(context, node, op)
Пример #4
0
    def visit_Set(self, node):
        if node.expr is not None:
            result = self.visit(node.expr)
        else:
            links = []

            while node.rptr and (not node.show_as_anchor
                                 or self.context.inline_anchors):
                rptr = node.rptr
                ptrcls = rptr.ptrcls
                pname = ptrcls.shortname

                if isinstance(rptr.target.scls, s_objtypes.ObjectType):
                    target = rptr.target.scls.shortname
                    target = qlast.ObjectRef(name=target.name,
                                             module=target.module)
                else:
                    target = None

                link = qlast.Ptr(ptr=qlast.ObjectRef(name=pname.name, ),
                                 direction=rptr.direction,
                                 target=target)
                if isinstance(ptrcls.source, s_links.Link):
                    link.type = 'property'
                links.append(link)

                node = node.rptr.source

            result = qlast.Path()

            if node.show_as_anchor and not self.context.inline_anchors:
                if issubclass(node.show_as_anchor, qlast.Expr):
                    step = node.show_as_anchor()
                else:
                    step = qlast.ObjectRef(name=node.show_as_anchor)
            else:
                step = qlast.ObjectRef(name=node.scls.shortname.name,
                                       module=node.scls.shortname.module)

            result.steps.append(step)
            result.steps.extend(reversed(links))

        if node.shape:
            result = qlast.Shape(expr=result, elements=[])

            for el in node.shape:
                rptr = el.rptr
                ptrcls = rptr.ptrcls
                pn = ptrcls.shortname

                pn = qlast.ShapeElement(expr=qlast.Path(steps=[
                    qlast.Ptr(ptr=qlast.ObjectRef(name=pn.name),
                              direction=rptr.direction)
                ]))

                result.elements.append(pn)

        return result
Пример #5
0
def type_to_ql_typeref(t: s_obj.Object) -> qlast.TypeName:
    if not isinstance(t, s_types.Collection):
        result = qlast.TypeName(
            maintype=qlast.ObjectRef(module=t.name.module, name=t.name.name))
    else:
        result = qlast.TypeName(
            maintype=qlast.ObjectRef(name=t.schema_name),
            subtypes=[type_to_ql_typeref(st) for st in t.get_subtypes()])

    return result
Пример #6
0
def typeref_to_ast(t: so.Object) -> ql_ast.TypeName:
    if not isinstance(t, s_types.Collection):
        if isinstance(t, so.ObjectRef):
            name = t.classname
        else:
            name = t.name

        result = ql_ast.TypeName(
            maintype=ql_ast.ObjectRef(module=name.module, name=name.name))
    else:
        result = ql_ast.TypeName(
            maintype=ql_ast.ObjectRef(name=t.schema_name),
            subtypes=[typeref_to_ast(st) for st in t.get_subtypes()])

    return result
Пример #7
0
 def edb_base_name(self):
     base = self.edb_base.name
     return codegen.generate_source(
         qlast.ObjectRef(
             module=base.module,
             name=base.name,
         ))
Пример #8
0
    def get_path_prefix(self, end_trim=None):
        # flatten the path
        path = [step for psteps in self._context.path for step in psteps]

        # find the first shadowed root
        for i, step in enumerate(path):
            base = step.type
            if base.shadow:
                break

        # trim the rest of the path
        path = path[i + 1:end_trim]
        prefix = [qlast.ObjectRef(module=base.module, name=base.short_name)]
        prefix.extend(
            qlast.Ptr(ptr=qlast.ObjectRef(name=step.name)) for step in path)
        return prefix
Пример #9
0
    def _apply_field_ast(self, context, node, op):
        objtype = context.get(LinkSourceCommandContext)

        if op.property == 'is_derived':
            pass
        elif op.property == 'spectargets':
            if op.new_value:
                node.targets = [
                    qlast.ObjectRef(name=t.classname.name,
                                    module=t.classname.module)
                    for t in op.new_value
                ]
        elif op.property == 'default':
            self._encode_default(context, node, op)
        elif op.property == 'required':
            node.is_required = op.new_value
        elif op.property == 'source':
            pass
        elif op.property == 'search':
            if op.new_value:
                v = qlast.Constant(value=str(op.new_value.weight))
                self._set_attribute_ast(context, node, 'search_weight', v)
        elif op.property == 'target' and objtype:
            if not node.targets:
                t = op.new_value
                node.targets = [utils.typeref_to_ast(t)]
        else:
            super()._apply_field_ast(context, node, op)
Пример #10
0
 def reduce_NodeName_Shape(self, *kids):
     self.val = qlast.Shape(expr=qlast.Path(steps=[
         qlast.ObjectRef(name=kids[0].val.name,
                         module=kids[0].val.module,
                         context=kids[0].context)
     ]),
                            elements=kids[1].val)
Пример #11
0
    def visit_TypeCast(self, node):
        if node.type.subtypes:
            typ = qlast.TypeName(
                maintype=qlast.ObjectRef(name=node.type.maintype),
                subtypes=[
                    qlast.ObjectRef(module=stn.module, name=stn.name)
                    for stn in node.type.subtypes
                ])
        else:
            mtn = node.type.maintype
            mt = qlast.ObjectRef(module=mtn.module, name=mtn.name)
            typ = qlast.TypeName(maintype=mt)

        result = qlast.TypeCast(expr=self.visit(node.expr), type=typ)

        return result
Пример #12
0
 def reduce_VIEW_Identifier_TurnstileBlob(self, *kids):
     self.val = esast.ViewDeclaration(
         name=kids[1].val,
         attributes=[
             esast.Attribute(name=qlast.ObjectRef(name='expr'),
                             value=kids[2].val)
         ])
Пример #13
0
    def _prepare_field(self, node):
        path = self._context.path[-1]
        include_base = self._context.include_base[-1]

        is_top = self._is_top_level_field(node)

        spath = self._context.path[-1]
        prevt, target = self._get_parent_and_current_type()

        # insert normal or specialized link
        steps = []
        if include_base:
            base = spath[0].type
            steps.append(
                qlast.ObjectRef(module=base.module, name=base.short_name))
        steps.append(qlast.Ptr(ptr=qlast.ObjectRef(name=node.name)))

        return is_top, path, prevt, target, steps
Пример #14
0
    def visit_TypeRef(self, node):
        # Bare TypeRef only appears as rhs of IS [NOT] and is always
        # an object type reference.
        mtn = node.maintype

        result = qlast.Path(
            steps=[qlast.ObjectRef(module=mtn.module, name=mtn.name)])

        return result
Пример #15
0
    def _get_ast(self, context):
        value = self.new_value

        new_value_empty = \
            (value is None or
                (isinstance(value, collections.Container) and not value))

        old_value_empty = \
            (self.old_value is None or
                (isinstance(self.old_value, collections.Container) and
                    not self.old_value))

        if new_value_empty and not old_value_empty:
            op = qlast.DropAttributeValue(
                name=qlast.ObjectRef(module='', name=self.property))
            return op

        if new_value_empty and old_value_empty:
            return

        if isinstance(value, s_expr.ExpressionText):
            value = edgeql.parse(str(value))
        elif utils.is_nontrivial_container(value):
            value = qlast.Tuple(
                elements=[qlast.Constant(value=el) for el in value])
        elif isinstance(value, nlang.WordCombination):
            forms = value.as_dict()
            if len(forms) > 1:
                items = []
                for k, v in forms.items():
                    items.append(
                        (qlast.Constant(value=k), qlast.Constant(value=v)))
                value = qlast.Mapping(items=items)
            else:
                value = qlast.Constant(value=str(value))
        else:
            value = qlast.Constant(value=value)

        as_expr = isinstance(value, qlast.ExpressionText)
        op = qlast.CreateAttributeValue(name=qlast.ObjectRef(
            module='', name=self.property),
                                        value=value,
                                        as_expr=as_expr)
        return op
Пример #16
0
    def reduce_ARRAY_LANGBRACKET_NonArrayTypeName_OptDimensions_RANGBRACKET(
            self, *kids):
        subtype = kids[2].val
        dimensions = kids[3].val

        self.val = qlast.TypeName(
            maintype=qlast.ObjectRef(name='array'),
            subtypes=[subtype],
            dimensions=dimensions,
        )
Пример #17
0
    def _set_attribute_ast(self, context, node, name, value):
        if isinstance(value, expr.ExpressionText):
            value = qlast.ExpressionText(expr=str(value))

        as_expr = isinstance(value, qlast.ExpressionText)
        name_ref = qlast.ObjectRef(name=name, module='')
        node.commands.append(
            qlast.CreateAttributeValue(name=name_ref,
                                       value=value,
                                       as_expr=as_expr))
Пример #18
0
    def _get_ast(self, context):
        metaclass = self.get_schema_metaclass()
        astnode = self._get_ast_node(context)
        if isinstance(self.classname, sn.Name):
            if hasattr(metaclass, 'get_shortname'):
                nname = metaclass.get_shortname(self.classname)
            else:
                nname = self.classname
            name = qlast.ObjectRef(module=nname.module, name=nname.name)
        else:
            name = qlast.ObjectRef(module='', name=self.classname)

        if astnode.get_field('name'):
            op = astnode(name=name)
        else:
            op = astnode()

        self._apply_fields_ast(context, op)

        return op
Пример #19
0
 def reduce_CreateViewShortStmt(self, *kids):
     r"""%reduce \
         CREATE VIEW NodeName TURNSTILE Expr \
     """
     self.val = qlast.CreateView(name=kids[2].val,
                                 commands=[
                                     qlast.CreateAttributeValue(
                                         name=qlast.ObjectRef(name='expr'),
                                         value=kids[4].val,
                                         as_expr=True)
                                 ])
Пример #20
0
 def _apply_field_ast(self, context, node, op):
     if op.property == 'target':
         if op.new_value:
             node.commands.append(
                 qlast.AlterTarget(targets=[
                     qlast.ObjectRef(name=op.new_value.classname.name,
                                     module=op.new_value.classname.module)
                 ]))
     elif op.property == 'source':
         pass
     else:
         super()._apply_field_ast(context, node, op)
Пример #21
0
    def visit_Argument(self, node, *, get_path_prefix):
        op = ast.ops.EQ
        name_parts = node.name

        _, target = self._get_parent_and_current_type()

        name = get_path_prefix()
        name.append(qlast.Ptr(ptr=qlast.ObjectRef(name=name_parts)))
        name = qlast.Path(steps=name)

        value = self.visit(node.value)

        # potentially need to cast the 'name' side into a <str>, so as
        # to be compatible with the 'value'
        typename = target.get_field_type(name_parts).short_name
        if (typename != 'str' and gt.EDB_TO_GQL_SCALARS_MAP[typename]
                in {GraphQLString, GraphQLID}):
            name = qlast.TypeCast(
                expr=name,
                type=qlast.TypeName(maintype=qlast.ObjectRef(name='str')),
            )

        return qlast.BinOp(left=name, op=op, right=value)
Пример #22
0
 def _apply_field_ast(self, context, node, op):
     if op.property == 'name':
         pass
     elif op.property == 'bases':
         node.bases = [
             qlast.ObjectRef(name=b.classname.name,
                             module=b.classname.module)
             for b in op.new_value
         ]
     elif op.property == 'mro':
         pass
     elif op.property == 'is_abstract':
         node.is_abstract = op.new_value
     elif op.property == 'is_final':
         node.is_final = op.new_value
     else:
         super()._apply_field_ast(context, node, op)
Пример #23
0
    def _apply_field_ast(self, context, node, op):
        if op.property == 'type':
            tp = op.new_value
            if isinstance(tp, s_types.Collection):
                maintype = tp.schema_name
                stt = tp.get_subtypes()

                for st in stt:
                    eltype = qlast.ObjectRef(module=st.module, name=st.name)
                tnn = qlast.TypeName(maintype=maintype, subtypes=[eltype])
            else:
                tnn = qlast.TypeName(maintype=tp)

            node.type = tnn

        else:
            super()._apply_field_ast(context, node, op)
Пример #24
0
    def _get_ast(self, context):
        astnode = self._get_ast_node(context)
        metaclass = self.get_schema_metaclass()

        if hasattr(metaclass, 'get_shortname'):
            new_name = metaclass.get_shortname(self.new_name)
        else:
            new_name = self.new_name

        if new_name != self.new_name:
            # Derived name
            name_b32 = base64.b32encode(self.new_name.name.encode()).decode()
            new_nname = '__b32_' + name_b32.replace('=', '_')

            new_name = sn.Name(module=self.new_name.module, name=new_nname)
        else:
            new_name = self.new_name

        ref = qlast.ObjectRef(name=new_name.name, module=new_name.module)
        return astnode(new_name=ref)
Пример #25
0
def compile_result_clause(
        result: qlast.Base, *,
        view_scls: typing.Optional[s_types.Type]=None,
        view_rptr: typing.Optional[context.ViewRPtr]=None,
        view_name: typing.Optional[s_name.SchemaName]=None,
        result_alias: typing.Optional[str]=None,
        ctx: context.ContextLevel) -> irast.Set:
    with ctx.new() as sctx:
        sctx.clause = 'result'
        if sctx.stmt is ctx.toplevel_stmt:
            sctx.toplevel_clause = sctx.clause
            sctx.expr_exposed = True

        if isinstance(result, qlast.Shape):
            result_expr = result.expr
            shape = result.elements
        else:
            result_expr = result
            shape = None

        if result_alias:
            stmtctx.declare_view(result_expr, alias=result_alias, ctx=sctx)
            result_expr = qlast.Path(
                steps=[qlast.ObjectRef(name=result_alias)]
            )

        expr = setgen.ensure_set(
            dispatch.compile(result_expr, ctx=sctx), ctx=sctx)

        result = compile_query_subject(
            expr, shape=shape, view_rptr=view_rptr, view_name=view_name,
            result_alias=result_alias,
            view_scls=view_scls,
            compile_views=ctx.stmt is ctx.toplevel_stmt,
            ctx=sctx)

        ctx.partial_path_prefix = result

    return result
Пример #26
0
    def _visit_query(self, node):
        # populate input variables with defaults, where applicable
        if node.variables:
            self.visit(node.variables)

        # base Query needs to be configured specially
        base = self._context.gql_schema.get('Query',
                                            modules=self._context.modules)

        # special treatment of the selection_set, different from inner
        # recursion
        query = qlast.SelectQuery(result=qlast.Shape(expr=qlast.Path(
            steps=[qlast.ObjectRef(name='Query', module='graphql')]),
                                                     elements=[]), )

        self._context.fields.append({})
        self._context.path.append([Step(None, base)])
        query.result.elements = self.visit(node.selection_set)
        self._context.fields.pop()
        self._context.path.pop()

        return query
Пример #27
0
 def get_path_prefix():
     path = self._context.path[0]
     return [
         qlast.ObjectRef(module=path[1].module, name=path[1].short_name)
     ]
Пример #28
0
    def visit_Field(self, node):
        if self._is_duplicate_field(node):
            return

        is_top, path, prevt, target, steps = \
            self._prepare_field(node)

        json_mode = False

        # determine if there needs to be extra subqueries
        if not prevt.dummy and target.dummy:
            json_mode = True

            # this is a special introspection type
            eql, shape, filterable = target.get_template()

            spec = qlast.ShapeElement(
                expr=qlast.Path(steps=[
                    qlast.Ptr(ptr=qlast.ObjectRef(
                        name=node.alias or node.name))
                ]),
                compexpr=eql,
            )

        elif prevt.is_field_shadowed(node.name):
            if prevt.has_native_field(node.name) and not node.alias:
                spec = filterable = shape = qlast.ShapeElement(
                    expr=qlast.Path(steps=steps), )
            else:
                prefix = qlast.Path(steps=self.get_path_prefix(-1))
                eql, shape, filterable = prevt.get_field_template(
                    node.name,
                    parent=prefix,
                    has_shape=bool(node.selection_set))
                spec = qlast.ShapeElement(
                    expr=qlast.Path(steps=[
                        qlast.Ptr(ptr=qlast.ObjectRef(
                            # this is already a sub-query
                            name=node.alias or node.name))
                    ]),
                    compexpr=eql)

        else:
            # if the parent is NOT a shadowed type, we need an explicit SELECT
            eql, shape, filterable = target.get_template()
            spec = qlast.ShapeElement(
                expr=qlast.Path(steps=[
                    qlast.Ptr(ptr=qlast.ObjectRef(
                        # this is already a sub-query
                        name=node.alias or node.name))
                ]),
                compexpr=eql)

        if node.selection_set is not None:
            if json_mode:
                pass

            else:
                # a single recursion target, so we can process
                # selection set now
                self._context.fields.append({})
                vals = self.visit(node.selection_set)
                self._context.fields.pop()

                if shape:
                    shape.elements = vals
                if filterable:
                    filterable.where = self._visit_path_where(node.arguments)

        path.pop()
        return spec
Пример #29
0
 def reduce_DUNDERTYPE(self, *kids):
     self.val = qlast.ObjectRef(name=kids[0].val)
Пример #30
0
 def reduce_DROP_MODULE_ModuleName(self, *kids):
     self.val = qlast.DropModule(
         name=qlast.ObjectRef(module=None, name='.'.join(kids[2].val)))