# Buggy code
def _process_create_or_alter_ast(
    self,
    schema: s_schema.Schema,
    astnode: qlast.CreateConcretePointer,
    context: sd.CommandContext,
) -> None:
    """Handle the CREATE {PROPERTY|LINK} AST node.

    This may be called in the context of either Create or Alter.
    """
    if astnode.is_required is not None:
        self.set_attribute_value(
            "required",
            astnode.is_required,
            source_context=astnode.context,
        )

    if astnode.cardinality is not None:
        if isinstance(self, sd.CreateObject):
            self.set_attribute_value(
                "cardinality",
                astnode.cardinality,
                source_context=astnode.context,
            )
        else:
            handler = sd.get_special_field_alter_handler_for_context(
                "cardinality", context
            )
            assert handler is not None
            set_field = qlast.SetField(
                name="cardinality",
                value=qlast.StringConstant.from_python(
                    str(astnode.cardinality),
                ),
                special_syntax=True,
                context=astnode.context,
            )
            apc = handler._cmd_tree_from_ast(schema, set_field, context)
            self.add(apc)

    parent_ctx = self.get_referrer_context_or_die(context)
    source_name = context.get_referrer_name(parent_ctx)
    self.set_attribute_value("source", so.ObjectShell(name=source_name))

    # FIXME: this is an approximate solution
    targets = qlast.get_targets(astnode.target)
    target_ref: Union[None, s_types.TypeShell, ComputableRef]

    if len(targets) > 1:
        assert isinstance(source_name, sn.QualName)

        new_targets = [
            utils.ast_to_type_shell(
                t,
                modaliases=context.modaliases,
                schema=schema,
            )
            for t in targets
        ]

        target_ref = s_types.UnionTypeShell(
            new_targets,
            module=source_name.module,
        )
    elif targets:
        target_expr = targets[0]
        if isinstance(target_expr, qlast.TypeName):
            target_ref = utils.ast_to_type_shell(
                target_expr,
                modaliases=context.modaliases,
                schema=schema,
            )
        else:
            # computable
            qlcompiler.normalize(
                target_expr, schema=schema, modaliases=context.modaliases
            )
            target_ref = ComputableRef(target_expr)
    else:
        # Target is inherited.
        target_ref = None

    if isinstance(self, sd.CreateObject):
        assert astnode.target is not None
        self.set_attribute_value(
            "target",
            target_ref,
            source_context=astnode.target.context,
        )

    elif target_ref is not None:
        assert astnode.target is not None
        self.set_attribute_value(
            "target",
            target_ref,
            source_context=astnode.target.context,
        )


# Traceback (AttributeError)
ERROR: InternalServerError: 'UnionType' object has no attribute 'get_name'
Hint: This is most likely a bug in EdgeDB. Please consider opening an issue ticket at https://github.com/edgedb/edgedb/issues/new?template=bug_report.md
Server traceback:
Traceback (most recent call last):
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/server/procpool/worker.py", line 75, in worker
res = await meth(*args)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/server/compiler/compiler.py", line 1808, in compile_eql_tokens
return self._compile(ctx=ctx, tokens=eql_tokens)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/server/compiler/compiler.py", line 1442, in _compile
comp: dbstate.BaseQuery = self._compile_dispatch_ql(ctx, stmt)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/server/compiler/compiler.py", line 1365, in _compile_dispatch_ql
return self._compile_ql_migration(ctx, ql)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/server/compiler/compiler.py", line 794, in _compile_ql_migration
target_schema = s_ddl.apply_sdl(
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/schema/ddl.py", line 371, in apply_sdl
ddl_stmts = s_decl.sdl_to_ddl(current_schema, documents)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/edgeql/declarative.py", line 230, in sdl_to_ddl
trace_dependencies(decl_ast, ctx=ctx)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/functools.py", line 875, in wrapper
return dispatch(args[0].__class__)(*args, **kw)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/edgeql/declarative.py", line 499, in trace_default
_register_item(node, ctx=ctx)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/edgeql/declarative.py", line 623, in _register_item
trace_dependencies(cmd, ctx=ctx)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/functools.py", line 875, in wrapper
return dispatch(args[0].__class__)(*args, **kw)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/edgeql/declarative.py", line 443, in trace_ConcretePointer
_register_item(
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/edgeql/declarative.py", line 638, in _register_item
tdeps = qltracer.trace_refs(
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/edgeql/tracer.py", line 162, in trace_refs
trace(qltree, ctx=ctx)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/functools.py", line 875, in wrapper
return dispatch(args[0].__class__)(*args, **kw)
File "/usr/lib/x86_64-linux-gnu/edgedb-server-1-alpha6/lib/python3.8/site-packages/edb/edgeql/tracer.py", line 653, in trace_Select
ctx.path_prefix = tip.get_name(ctx.schema)
AttributeError: 'UnionType' object has no attribute 'get_name'

# Fixed code
def _process_create_or_alter_ast(
    self,
    schema: s_schema.Schema,
    astnode: qlast.CreateConcretePointer,
    context: sd.CommandContext,
) -> None:
    """Handle the CREATE {PROPERTY|LINK} AST node.

    This may be called in the context of either Create or Alter.
    """
    if astnode.is_required is not None:
        self.set_attribute_value(
            "required",
            astnode.is_required,
            source_context=astnode.context,
        )

    if astnode.cardinality is not None:
        if isinstance(self, sd.CreateObject):
            self.set_attribute_value(
                "cardinality",
                astnode.cardinality,
                source_context=astnode.context,
            )
        else:
            handler = sd.get_special_field_alter_handler_for_context(
                "cardinality", context
            )
            assert handler is not None
            set_field = qlast.SetField(
                name="cardinality",
                value=qlast.StringConstant.from_python(
                    str(astnode.cardinality),
                ),
                special_syntax=True,
                context=astnode.context,
            )
            apc = handler._cmd_tree_from_ast(schema, set_field, context)
            self.add(apc)

    parent_ctx = self.get_referrer_context_or_die(context)
    source_name = context.get_referrer_name(parent_ctx)
    self.set_attribute_value("source", so.ObjectShell(name=source_name))

    # FIXME: this is an approximate solution
    targets = qlast.get_targets(astnode.target)
    target_ref: Union[None, s_types.TypeShell, ComputableRef]

    if len(targets) > 1:
        assert isinstance(source_name, sn.QualName)

        new_targets = [
            utils.ast_to_type_shell(
                t,
                modaliases=context.modaliases,
                schema=schema,
            )
            for t in targets
        ]

        target_ref = s_types.UnionTypeShell(
            components=new_targets,
            module=source_name.module,
        )
    elif targets:
        target_expr = targets[0]
        if isinstance(target_expr, qlast.TypeName):
            target_ref = utils.ast_to_type_shell(
                target_expr,
                modaliases=context.modaliases,
                schema=schema,
            )
        else:
            # computable
            qlcompiler.normalize(
                target_expr, schema=schema, modaliases=context.modaliases
            )
            target_ref = ComputableRef(target_expr)
    else:
        # Target is inherited.
        target_ref = None

    if isinstance(self, sd.CreateObject):
        assert astnode.target is not None
        self.set_attribute_value(
            "target",
            target_ref,
            source_context=astnode.target.context,
        )

    elif target_ref is not None:
        assert astnode.target is not None
        self.set_attribute_value(
            "target",
            target_ref,
            source_context=astnode.target.context,
        )