diff --git a/go/vt/schemadiff/diff_test.go b/go/vt/schemadiff/diff_test.go index aa323cec792..6f189d85c71 100644 --- a/go/vt/schemadiff/diff_test.go +++ b/go/vt/schemadiff/diff_test.go @@ -296,6 +296,17 @@ func TestDiffSchemas(t *testing.T) { from: "create table t(id int primary key)", to: "create table t(id int primary key)", }, + { + name: "change of table column", + from: "create table t(id int primary key, v varchar(10))", + to: "create table t(id int primary key, v varchar(20))", + diffs: []string{ + "alter table t modify column v varchar(20)", + }, + cdiffs: []string{ + "ALTER TABLE `t` MODIFY COLUMN `v` varchar(20)", + }, + }, { name: "change of table columns, added", from: "create table t(id int primary key)", @@ -329,7 +340,7 @@ func TestDiffSchemas(t *testing.T) { }, }, { - name: "create table (2)", + name: "create table 2", from: ";;; ; ; ;;;", to: "create table t(id int primary key)", diffs: []string{ @@ -501,11 +512,16 @@ func TestDiffSchemas(t *testing.T) { // Validate "apply()" on "from" converges with "to" schema1, err := NewSchemaFromSQL(ts.from) assert.NoError(t, err) + schema1SQL := schema1.ToSQL() + schema2, err := NewSchemaFromSQL(ts.to) assert.NoError(t, err) applied, err := schema1.Apply(diffs) require.NoError(t, err) + // validate schema1 unaffected by Apply + assert.Equal(t, schema1SQL, schema1.ToSQL()) + appliedDiff, err := schema2.Diff(applied, hints) require.NoError(t, err) assert.Empty(t, appliedDiff) diff --git a/go/vt/schemadiff/schema.go b/go/vt/schemadiff/schema.go index 916a1d37fcc..940ecd1571c 100644 --- a/go/vt/schemadiff/schema.go +++ b/go/vt/schemadiff/schema.go @@ -426,7 +426,11 @@ func (s *Schema) apply(diffs []EntityDiff) error { // These diffs are CREATE/DROP/ALTER TABLE/VIEW. // The operation does not modify this object. Instead, if successful, a new (modified) Schema is returned. func (s *Schema) Apply(diffs []EntityDiff) (*Schema, error) { - dup, err := NewSchemaFromStatements(s.ToStatements()) + // we export to queries, then import back. + // The reason we don't just clone this object's fields, or even export/import to Statements, + // is that we want this schema to be immutable an unaffected by the apply() on the duplicate. + // statements/slices/maps will have shared pointers and changes will propagate back to this schema. + dup, err := NewSchemaFromQueries(s.ToQueries()) if err != nil { return nil, err }