Esempio n. 1
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        if op.property == 'bases':
            explicit_bases = self.get_explicit_bases(schema, context,
                                                     op.new_value)

            if explicit_bases:
                if isinstance(node, qlast.CreateObject):
                    node.bases = [
                        qlast.TypeName(maintype=utils.name_to_ast_ref(b))
                        for b in explicit_bases
                    ]
                else:
                    node.commands.append(
                        qlast.AlterAddInherit(bases=[
                            utils.name_to_ast_ref(b) for b in explicit_bases
                        ], ))
        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(schema, context, node, op)
Esempio n. 2
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        objtype = self.get_referrer_context(context)

        if op.property == 'target' and objtype:
            # Due to how SDL is processed the underlying AST may be an
            # AlterConcreteLink, which requires different handling.
            if isinstance(node, qlast.CreateConcreteLink):
                if not node.target:
                    expr = self.get_attribute_value('expr')
                    if expr is not None:
                        node.target = expr.qlast
                    else:
                        t = op.new_value
                        assert isinstance(t, (so.Object, so.ObjectShell))
                        node.target = utils.typeref_to_ast(schema, t)
            else:
                assert isinstance(op.new_value, (so.Object, so.ObjectShell))
                node.commands.append(
                    qlast.SetPointerType(value=utils.typeref_to_ast(
                        schema, op.new_value), ))
        elif op.property == 'on_target_delete':
            node.commands.append(qlast.OnTargetDelete(cascade=op.new_value))
        else:
            super()._apply_field_ast(schema, context, node, op)
Esempio n. 3
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        if op.property == 'delegated':
            if isinstance(node, qlast.CreateConcreteConstraint):
                assert isinstance(op.new_value, bool)
                node.delegated = op.new_value
            else:
                node.commands.append(
                    qlast.SetSpecialField(
                        name='delegated',
                        value=op.new_value,
                    )
                )
            return
        elif op.property == 'args':
            assert isinstance(op.new_value, s_expr.ExpressionList)
            node.args = [arg.qlast for arg in op.new_value]
            return

        super()._apply_field_ast(schema, context, node, op)
Esempio n. 4
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        # type ignore below, because the class is used as mixin
        link = context.get(PropertySourceContext)  # type: ignore

        if op.property == 'target' and link:
            if isinstance(node, qlast.CreateConcreteProperty):
                expr = self.get_attribute_value('expr')
                if expr is not None:
                    node.target = expr.qlast
                else:
                    ref = op.new_value
                    assert isinstance(ref, (so.Object, so.ObjectShell))
                    node.target = utils.typeref_to_ast(schema, ref)
            else:
                ref = op.new_value
                assert isinstance(ref, (so.Object, so.ObjectShell))
                node.commands.append(
                    qlast.SetPointerType(
                        value=utils.typeref_to_ast(schema, ref)
                    )
                )
        else:
            super()._apply_field_ast(schema, context, node, op)
Esempio n. 5
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        objtype = self.get_referrer_context(context)

        if op.property == 'target' and objtype:
            # Due to how SDL is processed the underlying AST may be an
            # AlterConcreteLink, which requires different handling.
            if isinstance(node, qlast.CreateConcreteLink):
                if not node.target:
                    expr = self.get_attribute_value('expr')
                    if expr is not None:
                        node.target = expr.qlast
                    else:
                        t = op.new_value
                        assert isinstance(t, (so.Object, so.ObjectShell))
                        node.target = utils.typeref_to_ast(schema, t)
            else:
                old_type = pointers.merge_target(
                    self.scls,
                    list(self.scls.get_bases(schema).objects(schema)),
                    'target',
                    ignore_local=True,
                    schema=schema,
                )
                assert isinstance(op.new_value, (so.Object, so.ObjectShell))
                new_type = (
                    op.new_value.resolve(schema)
                    if isinstance(op.new_value, so.ObjectShell)
                    else op.new_value)

                new_type_ast = utils.typeref_to_ast(schema, op.new_value)
                cast_expr = None
                # If the type isn't assignment castable, generate a
                # USING with a nonsense cast. It shouldn't matter,
                # since there should be no data to cast, but the DDL side
                # of things doesn't know that since the command is split up.
                if old_type and not old_type.assignment_castable_to(
                        new_type, schema):
                    cast_expr = qlast.TypeCast(
                        type=new_type_ast,
                        expr=qlast.Set(elements=[]),
                    )
                node.commands.append(
                    qlast.SetPointerType(
                        value=new_type_ast,
                        cast_expr=cast_expr,
                    )
                )

        elif op.property == 'on_target_delete':
            node.commands.append(qlast.OnTargetDelete(cascade=op.new_value))
        else:
            super()._apply_field_ast(schema, context, node, op)
Esempio n. 6
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        objtype = self.get_referrer_context(context)

        if op.property == 'target' and objtype:
            # Due to how SDL is processed the underlying AST may be an
            # AlterConcreteLink, which requires different handling.
            if isinstance(node, qlast.CreateConcreteLink):
                if not node.target:
                    expr = self.get_attribute_value('expr')
                    if expr is not None:
                        node.target = expr.qlast
                    else:
                        t = op.new_value
                        assert isinstance(t, (so.Object, so.ObjectShell))
                        node.target = utils.typeref_to_ast(schema, t)
            else:
                assert isinstance(op.new_value, (so.Object, so.ObjectShell))
                top_op = self.get_top_referrer_op(context)
                conv_expr: Optional[qlast.Expr]
                if (top_op is not None and
                    (isinstance(top_op, sd.CreateObject) or
                     (top_op.orig_cmd_type is not None
                      and issubclass(top_op.orig_cmd_type, sd.CreateObject)))):
                    # This op is part of CREATE TYPE, so avoid tripping up
                    # the DDL check on SET TYPE by generating an appropriate
                    # conversion expression: USING (.foo[IS Type]).
                    lname = sn.shortname_from_fullname(self.classname).name
                    conv_expr = qlast.Path(
                        partial=True,
                        steps=[
                            qlast.Ptr(ptr=qlast.ObjectRef(name=lname)),
                            qlast.TypeIntersection(type=utils.typeref_to_ast(
                                schema, op.new_value))
                        ],
                    )
                else:
                    conv_expr = None
                node.commands.append(
                    qlast.SetPointerType(
                        value=utils.typeref_to_ast(schema, op.new_value),
                        expr=conv_expr,
                    ))
        elif op.property == 'on_target_delete':
            node.commands.append(qlast.OnTargetDelete(cascade=op.new_value))
        else:
            super()._apply_field_ast(schema, context, node, op)
Esempio n. 7
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        if op.property == 'bases':
            mcls = self.get_schema_metaclass()
            default_base = mcls.get_default_base_name()

            bases = op.new_value
            assert isinstance(bases, so.ObjectList)

            base_names: List[sn.SchemaName] = [
                b for b in bases.names(schema, allow_unresolved=True)
                if isinstance(b, sn.SchemaName)
                if b != default_base and sn.shortname_from_fullname(b) == b
            ]

            if base_names:
                if isinstance(node, qlast.CreateObject):
                    node.bases = [
                        qlast.TypeName(
                            maintype=qlast.ObjectRef(
                                name=b.name,
                                module=b.module
                            )
                        )
                        for b in base_names
                    ]
                else:
                    node.commands.append(
                        qlast.AlterAddInherit(
                            bases=[
                                qlast.ObjectRef(
                                    module=b.module,
                                    name=b.name
                                )
                                for b in base_names
                            ],
                        )
                    )

        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(schema, context, node, op)
Esempio n. 8
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        if op.property == 'default':
            if op.new_value:
                assert isinstance(op.new_value, list)
                op.new_value = op.new_value[0]
                super()._apply_field_ast(schema, context, node, op)

        elif op.property == 'bases':
            enum_values = self.get_attribute_value('enum_values')
            if enum_values:
                node.bases = [
                    qlast.TypeName(
                        maintype=qlast.ObjectRef(name='enum'),
                        subtypes=[
                            qlast.TypeExprLiteral(
                                val=qlast.StringConstant.from_python(v)
                            )
                            for v in enum_values
                        ]
                    )
                ]
            else:
                super()._apply_field_ast(schema, context, node, op)
        else:
            super()._apply_field_ast(schema, context, node, op)
Esempio n. 9
0
 def _apply_field_ast(self, schema: s_schema.Schema,
                      context: sd.CommandContext, node: qlast.DDLOperation,
                      op: sd.AlterObjectProperty) -> None:
     if op.property == 'inheritable':
         node.inheritable = op.new_value
     else:
         super()._apply_field_ast(schema, context, node, op)
Esempio n. 10
0
    def _apply_fields_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
    ) -> None:
        super()._apply_fields_ast(schema, context, node)

        if isinstance(node, qlast.CreateConstraint):
            params = []
            for op in self.get_subcommands(type=s_func.ParameterCommand):
                props = op.get_resolved_attributes(schema, context)
                pname = s_func.Parameter.paramname_from_fullname(props['name'])
                if pname == '__subject__':
                    continue
                num = props['num']
                default = props.get('default')
                param = qlast.FuncParam(
                    name=pname,
                    type=utils.typeref_to_ast(schema, props['type']),
                    typemod=props['typemod'],
                    kind=props['kind'],
                    default=default.qlast if default is not None else None,
                )
                params.append((num, param))

            params.sort(key=lambda e: e[0])

            node.params = [p[1] for p in params]
Esempio n. 11
0
 def _apply_field_ast(
     self,
     schema: s_schema.Schema,
     context: sd.CommandContext,
     node: qlast.DDLOperation,
     op: sd.AlterObjectProperty,
 ) -> None:
     assert isinstance(node, qlast.CreateMigration)
     if op.property == 'script':
         node.script = op.new_value
         node.body = qlast.MigrationBody(commands=tuple(
             qlparser.parse_block(op.new_value)), )
     elif op.property == 'parents':
         if op.new_value and (items := op.new_value.items):
             assert len(items) == 1
             parent = next(iter(items))
             node.parent = s_utils.name_to_ast_ref(parent.get_name(schema))
Esempio n. 12
0
 def _apply_field_ast(
     self,
     schema: s_schema.Schema,
     context: sd.CommandContext,
     node: qlast.DDLOperation,
     op: sd.AlterObjectProperty,
 ) -> None:
     assert isinstance(node, qlast.CreateExtensionPackage)
     if op.property == 'script':
         node.body = qlast.NestedQLBlock(
             text=op.new_value,
             commands=qlparser.parse_block(op.new_value),
         )
     elif op.property == 'version':
         node.version = qlast.StringConstant(value=str(op.new_value), )
     else:
         super()._apply_field_ast(schema, context, node, op)
Esempio n. 13
0
 def _apply_field_ast(self, schema: s_schema.Schema,
                      context: sd.CommandContext, node: qlast.DDLOperation,
                      op: sd.AlterObjectProperty) -> None:
     if op.property == 'value':
         assert isinstance(op.new_value, str)
         node.value = qlast.StringConstant.from_python(op.new_value)
     else:
         super()._apply_field_ast(schema, context, node, op)
Esempio n. 14
0
 def _apply_field_ast(
     self,
     schema: s_schema.Schema,
     context: sd.CommandContext,
     node: qlast.DDLOperation,
     op: sd.AlterObjectProperty,
 ) -> None:
     assert isinstance(node, qlast.CreateGlobal)
     if op.property == 'target':
         if not node.target:
             expr = self.get_attribute_value('expr')
             if expr is not None:
                 node.target = expr.qlast
             else:
                 t = op.new_value
                 assert isinstance(t, (so.Object, so.ObjectShell))
                 node.target = utils.typeref_to_ast(schema, t)
     else:
         super()._apply_field_ast(schema, context, node, op)
Esempio n. 15
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        if op.property == 'is_superuser':
            node.superuser = op.new_value
            return

        super()._apply_field_ast(schema, context, node, op)
Esempio n. 16
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        if op.property == 'args':
            assert isinstance(op.old_value, s_expr.ExpressionList)
            node.args = [arg.qlast for arg in op.old_value]
            return

        super()._apply_field_ast(schema, context, node, op)
Esempio n. 17
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        assert isinstance(node, qlast.CreateCast)
        new_value: Any = op.new_value

        if op.property == 'from_type':
            # In a cast we can only have pure types, so this is going
            # to be a TypeName.
            node.from_type = cast(qlast.TypeName,
                                  utils.typeref_to_ast(schema, new_value))

        elif op.property == 'to_type':
            # In a cast we can only have pure types, so this is going
            # to be a TypeName.
            node.to_type = cast(qlast.TypeName,
                                utils.typeref_to_ast(schema, new_value))

        elif op.property == 'code':
            if node.code is None:
                node.code = qlast.CastCode()
            node.code.code = new_value

        elif op.property == 'language':
            if node.code is None:
                node.code = qlast.CastCode()
            node.code.language = new_value

        elif op.property == 'from_function' and new_value:
            if node.code is None:
                node.code = qlast.CastCode()
            node.code.from_function = new_value

        elif op.property == 'from_expr' and new_value:
            if node.code is None:
                node.code = qlast.CastCode()
            node.code.from_expr = new_value

        elif op.property == 'from_cast' and new_value:
            if node.code is None:
                node.code = qlast.CastCode()
            node.code.from_cast = new_value

        else:
            super()._apply_field_ast(schema, context, node, op)
Esempio n. 18
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        if (op.property == 'args' and isinstance(
                node,
            (qlast.CreateConcreteConstraint, qlast.AlterConcreteConstraint))):
            assert isinstance(op.new_value, s_expr.ExpressionList)
            args = []
            for arg in op.new_value:
                exprast = arg.qlast
                assert isinstance(exprast, qlast.Expr), "expected qlast.Expr"
                args.append(exprast)
            node.args = args
            return

        super()._apply_field_ast(schema, context, node, op)
Esempio n. 19
0
    def _apply_field_ast(
        self,
        schema: s_schema.Schema,
        context: sd.CommandContext,
        node: qlast.DDLOperation,
        op: sd.AlterObjectProperty,
    ) -> None:
        assert isinstance(node, qlast.CreateOperator)
        new_value: Any = op.new_value

        if op.property == 'return_type':
            node.returning = utils.typeref_to_ast(schema, new_value)

        elif op.property == 'return_typemod':
            node.returning_typemod = new_value

        elif op.property == 'code':
            if node.code is None:
                node.code = qlast.OperatorCode()
            node.code.code = new_value

        elif op.property == 'language':
            if node.code is None:
                node.code = qlast.OperatorCode()
            node.code.language = new_value

        elif op.property == 'from_function' and new_value:
            if node.code is None:
                node.code = qlast.OperatorCode()
            node.code.from_function = new_value

        elif op.property == 'from_expr' and new_value:
            if node.code is None:
                node.code = qlast.OperatorCode()
            node.code.from_expr = new_value

        elif op.property == 'from_operator' and new_value:
            if node.code is None:
                node.code = qlast.OperatorCode()
            node.code.from_operator = tuple(new_value)

        else:
            super()._apply_field_ast(schema, context, node, op)
Esempio n. 20
0
def _clear_nonessential_subcommands(node: qlast.DDLOperation) -> None:
    node.commands = [
        cmd for cmd in node.commands
        if isinstance(cmd, qlast.SetField) and cmd.name.startswith('orig_')
    ]