protected void PlanMigrateColumn(SchemaMigrationPlan report, ColumnSchema existing, ColumnSchema target, MigrationOptions options)
        {
            if (existing == null)
            {
                if (target.KeyIndex > 0)
                {
                    throw new InvalidOperationException($"Cannot migrate column {target.Name} of {report.Target.Name}, keys can't be changed");
                }
                options.AssertNotFrozen($"Create column {target.Name} of {report.Target.Name}");

                report.Steps.Add(new MigrationStep()
                {
                    TargetName = target.Name,
                    Action     = MigrationAction.Create,
                    TargetType = MigrationTarget.Column,
                });
                return;
            }

            if (target == null)
            {
                if (existing.KeyIndex > 0)
                {
                    throw new InvalidOperationException($"Cannot migrate column {existing.Name} of {report.Target.Name}, keys can't be changed");
                }
                options.AssertColumnDeleteAllowed(report.Target.Name, existing.Name);

                report.Steps.Add(new MigrationStep()
                {
                    TargetName = existing.Name,
                    Action     = MigrationAction.Drop,
                    TargetType = MigrationTarget.Column,
                });
                return;
            }

            bool mismatched = false;

            if (target.KeyIndex != existing.KeyIndex)
            {
                throw new InvalidOperationException($"Cannot migrate column {target.Name} of {report.Target.Name}, keys can't be changed");
            }

            if (target.SqlType != existing.SqlType)
            {
                mismatched = true;
                options.AssertColumnDeleteAllowed(report.Target.Name, target.Name, "type");
            }

            if (target.Nullable != existing.Nullable)
            {
                mismatched = true;
                options.AssertColumnDeleteAllowed(report.Target.Name, target.Name, "nullable");
            }

            if (target.MaxLength != existing.MaxLength)
            {
                mismatched = true;
                options.AssertColumnDeleteAllowed(report.Target.Name, target.Name, "maxlength");
            }

            if (mismatched)
            {
                options.AssertColumnDeleteAllowed(report.Target.Name, target.Name);
                report.Steps.Add(new MigrationStep()
                {
                    TargetName = target.Name,
                    Action     = MigrationAction.Drop,
                    TargetType = MigrationTarget.Column,
                });
                report.Steps.Add(new MigrationStep()
                {
                    TargetName = target.Name,
                    Action     = MigrationAction.Create,
                    TargetType = MigrationTarget.Column,
                });
                return;
            }
        }