From 347c078e41e3d7b0ed7eae03e34c3eff1cc87aa5 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 15 Aug 2022 13:55:36 +0300 Subject: [PATCH 1/2] schemadiff: FullTextKeyStrategy, handling multiple 'ADD FULLTEXT key' options Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schemadiff/table.go | 34 ++++++++++++++++++++++++++++++---- go/vt/schemadiff/table_test.go | 25 +++++++++++++++++++++++++ go/vt/schemadiff/types.go | 6 ++++++ 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/go/vt/schemadiff/table.go b/go/vt/schemadiff/table.go index 25de4e1418d..5e196ba5895 100644 --- a/go/vt/schemadiff/table.go +++ b/go/vt/schemadiff/table.go @@ -621,7 +621,9 @@ func (c *CreateTableEntity) TableDiff(other *CreateTableEntity, hints *DiffHints Table: otherStmt.Table, } diffedTableCharset := "" + var parentAlterTableEntityDiff *AlterTableEntityDiff var partitionSpecs []*sqlparser.PartitionSpec + var superfluousFulltextKeys []*sqlparser.AddIndexDefinition { t1Options := c.CreateTable.TableSpec.Options t2Options := other.CreateTable.TableSpec.Options @@ -639,7 +641,7 @@ func (c *CreateTableEntity) TableDiff(other *CreateTableEntity, hints *DiffHints // ordered keys for both tables: t1Keys := c.CreateTable.TableSpec.Indexes t2Keys := other.CreateTable.TableSpec.Indexes - c.diffKeys(alterTable, t1Keys, t2Keys, hints) + superfluousFulltextKeys = c.diffKeys(alterTable, t1Keys, t2Keys, hints) } { // diff constraints @@ -668,11 +670,20 @@ func (c *CreateTableEntity) TableDiff(other *CreateTableEntity, hints *DiffHints return nil, err } } - var parentAlterTableEntityDiff *AlterTableEntityDiff tableSpecHasChanged := len(alterTable.AlterOptions) > 0 || alterTable.PartitionOption != nil || alterTable.PartitionSpec != nil if tableSpecHasChanged { parentAlterTableEntityDiff = &AlterTableEntityDiff{alterTable: alterTable, from: c, to: other} } + for _, superfluousFulltextKey := range superfluousFulltextKeys { + alterTable := &sqlparser.AlterTable{ + Table: otherStmt.Table, + AlterOptions: []sqlparser.AlterOption{superfluousFulltextKey}, + } + diff := &AlterTableEntityDiff{alterTable: alterTable, from: c, to: other} + // if we got superfluous fulltext keys, that means the table spec has changed, ie + // parentAlterTableEntityDiff is not nil + parentAlterTableEntityDiff.addSubsequentDiff(diff) + } for _, partitionSpec := range partitionSpecs { alterTable := &sqlparser.AlterTable{ Table: otherStmt.Table, @@ -1103,7 +1114,7 @@ func (c *CreateTableEntity) diffKeys(alterTable *sqlparser.AlterTable, t1Keys []*sqlparser.IndexDefinition, t2Keys []*sqlparser.IndexDefinition, hints *DiffHints, -) { +) (superfluousFulltextKeys []*sqlparser.AddIndexDefinition) { t1KeysMap := map[string]*sqlparser.IndexDefinition{} t2KeysMap := map[string]*sqlparser.IndexDefinition{} for _, key := range t1Keys { @@ -1134,6 +1145,7 @@ func (c *CreateTableEntity) diffKeys(alterTable *sqlparser.AlterTable, } } + addedFulltextKeys := 0 for _, t2Key := range t2Keys { t2KeyName := t2Key.Info.Name.String() // evaluate modified & added keys: @@ -1164,9 +1176,23 @@ func (c *CreateTableEntity) diffKeys(alterTable *sqlparser.AlterTable, addKey := &sqlparser.AddIndexDefinition{ IndexDefinition: t2Key, } - alterTable.AlterOptions = append(alterTable.AlterOptions, addKey) + addedAsSuperfluousStatement := false + if t2Key.Info.Fulltext { + if addedFulltextKeys > 0 && hints.FullTextKeyStrategy == FullTextKeyDistinctStatements { + // Special case: MySQL does not support multiple ADD FULLTEXT KEY statements in a single ALTER + fmt.Printf("Added superfluous key: %v\n", sqlparser.CanonicalString(t2Key)) + superfluousFulltextKeys = append(superfluousFulltextKeys, addKey) + addedAsSuperfluousStatement = true + } + addedFulltextKeys++ + } + if !addedAsSuperfluousStatement { + fmt.Printf("Added key: %v\n", sqlparser.CanonicalString(t2Key)) + alterTable.AlterOptions = append(alterTable.AlterOptions, addKey) + } } } + return superfluousFulltextKeys } // indexOnlyVisibilityChange checks whether the change on an index is only diff --git a/go/vt/schemadiff/table_test.go b/go/vt/schemadiff/table_test.go index c79ae9e2c52..770e1568834 100644 --- a/go/vt/schemadiff/table_test.go +++ b/go/vt/schemadiff/table_test.go @@ -40,6 +40,7 @@ func TestCreateTableDiff(t *testing.T) { errorMsg string autoinc int rotation int + fulltext int colrename int constraint int }{ @@ -422,6 +423,29 @@ func TestCreateTableDiff(t *testing.T) { diff: "alter table t1 alter index i_idx invisible", cdiff: "ALTER TABLE `t1` ALTER INDEX `i_idx` INVISIBLE", }, + // FULLTEXT keys + { + name: "add one fulltext key", + from: "create table t1 (id int primary key, name tinytext not null)", + to: "create table t1 (id int primary key, name tinytext not null, fulltext key name_ft(name))", + diff: "alter table t1 add fulltext key name_ft (`name`)", + cdiff: "ALTER TABLE `t1` ADD FULLTEXT KEY `name_ft` (`name`)", + }, + { + name: "add two fulltext keys, distinct statements", + from: "create table t1 (id int primary key, name1 tinytext not null, name2 tinytext not null)", + to: "create table t1 (id int primary key, name1 tinytext not null, name2 tinytext not null, fulltext key name1_ft(name1), fulltext key name2_ft(name2))", + diffs: []string{"alter table t1 add fulltext key name1_ft (name1)", "alter table t1 add fulltext key name2_ft (name2)"}, + cdiffs: []string{"ALTER TABLE `t1` ADD FULLTEXT KEY `name1_ft` (`name1`)", "ALTER TABLE `t1` ADD FULLTEXT KEY `name2_ft` (`name2`)"}, + }, + { + name: "add two fulltext keys, unify statements", + from: "create table t1 (id int primary key, name1 tinytext not null, name2 tinytext not null)", + to: "create table t1 (id int primary key, name1 tinytext not null, name2 tinytext not null, fulltext key name1_ft(name1), fulltext key name2_ft(name2))", + fulltext: FullTextKeyUnifyStatements, + diff: "alter table t1 add fulltext key name1_ft (name1), add fulltext key name2_ft (name2)", + cdiff: "ALTER TABLE `t1` ADD FULLTEXT KEY `name1_ft` (`name1`), ADD FULLTEXT KEY `name2_ft` (`name2`)", + }, // CHECK constraints { name: "identical check constraints", @@ -981,6 +1005,7 @@ func TestCreateTableDiff(t *testing.T) { hints.RangeRotationStrategy = ts.rotation hints.ConstraintNamesStrategy = ts.constraint hints.ColumnRenameStrategy = ts.colrename + hints.FullTextKeyStrategy = ts.fulltext alter, err := c.Diff(other, &hints) require.Equal(t, len(ts.diffs), len(ts.cdiffs)) diff --git a/go/vt/schemadiff/types.go b/go/vt/schemadiff/types.go index b6de2c49f1c..e8a1ad3c5a9 100644 --- a/go/vt/schemadiff/types.go +++ b/go/vt/schemadiff/types.go @@ -81,6 +81,11 @@ const ( TableRenameHeuristicStatement ) +const ( + FullTextKeyDistinctStatements = iota + FullTextKeyUnifyStatements +) + // DiffHints is an assortment of rules for diffing entities type DiffHints struct { StrictIndexOrdering bool @@ -89,4 +94,5 @@ type DiffHints struct { ConstraintNamesStrategy int ColumnRenameStrategy int TableRenameStrategy int + FullTextKeyStrategy int } From 2ff830653eda7d3ab80d36a443ad6438f3668d6d Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 15 Aug 2022 16:21:34 +0300 Subject: [PATCH 2/2] removed debug info Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schemadiff/table.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/go/vt/schemadiff/table.go b/go/vt/schemadiff/table.go index 5e196ba5895..b15c2aaaeda 100644 --- a/go/vt/schemadiff/table.go +++ b/go/vt/schemadiff/table.go @@ -1180,14 +1180,12 @@ func (c *CreateTableEntity) diffKeys(alterTable *sqlparser.AlterTable, if t2Key.Info.Fulltext { if addedFulltextKeys > 0 && hints.FullTextKeyStrategy == FullTextKeyDistinctStatements { // Special case: MySQL does not support multiple ADD FULLTEXT KEY statements in a single ALTER - fmt.Printf("Added superfluous key: %v\n", sqlparser.CanonicalString(t2Key)) superfluousFulltextKeys = append(superfluousFulltextKeys, addKey) addedAsSuperfluousStatement = true } addedFulltextKeys++ } if !addedAsSuperfluousStatement { - fmt.Printf("Added key: %v\n", sqlparser.CanonicalString(t2Key)) alterTable.AlterOptions = append(alterTable.AlterOptions, addKey) } }