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)
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)
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)
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)
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)
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)
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)
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)
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)
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]
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))
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)
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)
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)
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)
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)
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)
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)
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)
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_') ]