diff --git a/go/vt/schemadiff/capability.go b/go/vt/schemadiff/capability.go index fd4c8389240..5c4674141c8 100644 --- a/go/vt/schemadiff/capability.go +++ b/go/vt/schemadiff/capability.go @@ -10,6 +10,14 @@ import ( // alterOptionAvailableViaInstantDDL checks if the specific alter option is eligible to run via ALGORITHM=INSTANT // reference: https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html func alterOptionCapableOfInstantDDL(alterOption sqlparser.AlterOption, createTable *sqlparser.CreateTable, capableOf capabilities.CapableOf) (bool, error) { + // A table with FULLTEXT index won't support adding/removing columns instantly. + tableHasFulltextIndex := false + for _, key := range createTable.TableSpec.Indexes { + if key.Info.Type == sqlparser.IndexTypeFullText { + tableHasFulltextIndex = true + break + } + } findColumn := func(colName string) *sqlparser.ColumnDefinition { if createTable == nil { return nil @@ -42,6 +50,13 @@ func alterOptionCapableOfInstantDDL(alterOption sqlparser.AlterOption, createTab } return nil } + tableIsCompressed := false + if opt := findTableOption("ROW_FORMAT"); opt != nil { + if strings.EqualFold(opt.String, "COMPRESSED") { + tableIsCompressed = true + } + } + isVirtualColumn := func(colName string) bool { col := findColumn(colName) if col == nil { @@ -87,6 +102,14 @@ func alterOptionCapableOfInstantDDL(alterOption sqlparser.AlterOption, createTab // in another table. Which is a bit too much to compute here. return false, nil case *sqlparser.AddColumns: + if tableHasFulltextIndex { + // not supported if the table has a FULLTEXT index + return false, nil + } + // Not supported in COMPRESSED tables + if tableIsCompressed { + return false, nil + } if opt.First || opt.After != nil { // not a "last" column. Only supported as of 8.0.29 return capableOf(capabilities.InstantAddDropColumnFlavorCapability) @@ -94,11 +117,13 @@ func alterOptionCapableOfInstantDDL(alterOption sqlparser.AlterOption, createTab // Adding a *last* column is supported in 8.0 return capableOf(capabilities.InstantAddLastColumnFlavorCapability) case *sqlparser.DropColumn: + if tableHasFulltextIndex { + // not supported if the table has a FULLTEXT index + return false, nil + } // Not supported in COMPRESSED tables - if opt := findTableOption("ROW_FORMAT"); opt != nil { - if strings.EqualFold(opt.String, "COMPRESSED") { - return false, nil - } + if tableIsCompressed { + return false, nil } if findIndexCoveringColumn(opt.Name.Name.String()) != nil { // not supported if the column is part of an index diff --git a/go/vt/schemadiff/capability_test.go b/go/vt/schemadiff/capability_test.go index 4bbcb0ecf54..a98c52951f7 100644 --- a/go/vt/schemadiff/capability_test.go +++ b/go/vt/schemadiff/capability_test.go @@ -61,6 +61,18 @@ func TestAlterTableCapableOfInstantDDL(t *testing.T) { capableOf: incapableOf, expectCapableOfInstantDDL: false, }, + { + name: "add column fails on COMPRESSED tables", + create: "create table t1 (id int, i1 int) row_format=compressed", + alter: "alter table t1 add column i2 int", + expectCapableOfInstantDDL: false, + }, + { + name: "add column fails on table with FULLTEXT index", + create: "create table t(id int, name varchar(128), primary key(id), fulltext key (name))", + alter: "alter table t1 add column i2 int", + expectCapableOfInstantDDL: false, + }, { name: "drop virtual column", create: "create table t(id int, i1 int not null, i2 int generated always as (i1 + 1) virtual, primary key(id))", @@ -97,6 +109,12 @@ func TestAlterTableCapableOfInstantDDL(t *testing.T) { alter: "alter table t drop column i1", expectCapableOfInstantDDL: false, }, + { + name: "drop column fail due to fulltext index in table", + create: "create table t(id int, i1 int not null, name varchar(128), primary key(id), fulltext key (name))", + alter: "alter table t drop column i1", + expectCapableOfInstantDDL: false, + }, { name: "add two columns", create: "create table t(id int, i1 int not null, primary key(id))", @@ -122,6 +140,12 @@ func TestAlterTableCapableOfInstantDDL(t *testing.T) { alter: "alter table t modify column i1 int not null default 3", expectCapableOfInstantDDL: true, }, + { + name: "change a default column value on a table with FULLTEXT index", + create: "create table t(id int, i1 int not null, name varchar(128), primary key(id), fulltext key (name))", + alter: "alter table t modify column i1 int not null default 3", + expectCapableOfInstantDDL: true, + }, { name: "change default column value to null", create: "create table t(id int, i1 int not null, primary key(id))",