Skip to content

Commit

Permalink
Support search index
Browse files Browse the repository at this point in the history
  • Loading branch information
morikuni committed Dec 17, 2024
1 parent 3e445b0 commit a1cb5d6
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 0 deletions.
99 changes: 99 additions & 0 deletions internal/hammer/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ func NewDatabase(ddl DDL) (*Database, error) {
} else {
return nil, fmt.Errorf("cannot find ddl of table to apply index %s", stmt.Name.SQL())
}
case *ast.CreateSearchIndex:
if t, ok := m[stmt.TableName.SQL()]; ok {
t.searchIndexes = append(t.searchIndexes, stmt)
} else {
return nil, fmt.Errorf("cannot find ddl of table to apply index %s", stmt.Name.SQL())
}
case *ast.AlterTable:
t, ok := m[stmt.Name.SQL()]
if !ok {
Expand Down Expand Up @@ -113,6 +119,7 @@ type Table struct {
*ast.CreateTable

indexes []*ast.CreateIndex
searchIndexes []*ast.CreateSearchIndex
children []*Table
changeStreams []*ChangeStream
}
Expand Down Expand Up @@ -151,6 +158,7 @@ type Generator struct {

dropedTable []string
dropedIndex []string
dropedSearchIndex []string
dropedChangeStream []string
droppedConstraints []*ast.TableConstraint
willCreateOrAlterChangeStreamIDs map[string]*ChangeStream
Expand Down Expand Up @@ -189,8 +197,10 @@ func (g *Generator) GenerateDDL() DDL {
}

ddl.AppendDDL(g.generateDDLForDropIndex(fromTable, toTable))
ddl.AppendDDL(g.generateDDLForDropSearchIndex(fromTable, toTable))
ddl.AppendDDL(g.generateDDLForColumns(fromTable, toTable))
ddl.AppendDDL(g.generateDDLForCreateIndex(fromTable, toTable))
ddl.AppendDDL(g.generateDDLForCreateSearchIndex(fromTable, toTable))
ddl.AppendDDL(g.generateDDLForConstraints(fromTable, toTable))
ddl.AppendDDL(g.generateDDLForRowDeletionPolicy(fromTable, toTable))
ddl.AppendDDL(g.generateDDLForCreateChangeStream(g.from, toTable))
Expand Down Expand Up @@ -309,6 +319,9 @@ func (g *Generator) generateDDLForCreateTableAndIndex(table *Table) DDL {
for _, i := range table.indexes {
ddl.Append(i)
}
for _, si := range table.searchIndexes {
ddl.Append(si)
}
for _, cs := range table.changeStreams {
g.willCreateOrAlterChangeStreamIDs[cs.Name.SQL()] = cs
}
Expand All @@ -327,6 +340,9 @@ func (g *Generator) generateDDLForDropConstraintIndexAndTable(table *Table) DDL
for _, i := range table.indexes {
ddl.Append(&ast.DropIndex{Name: i.Name})
}
for _, si := range table.searchIndexes {
ddl.Append(&ast.DropSearchIndex{Name: si.Name})
}
for _, cs := range table.changeStreams {
if !g.isDropedChangeStream(cs.Name.SQL()) {
ddl.Append(&ast.DropChangeStream{Name: cs.Name})
Expand Down Expand Up @@ -512,6 +528,16 @@ func (g *Generator) generateDDLForDropAndCreateColumn(from, to *Table, fromCol,
ddl.Append(&ast.DropIndex{Name: i.Name})
}

searchIndexes := []*ast.CreateSearchIndex{}
for _, i := range g.findSearchIndexByColumn(from.searchIndexes, fromCol.Name.SQL()) {
if !g.isDropedSearchIndex(i.Name.SQL()) {
searchIndexes = append(searchIndexes, i)
}
}
for _, i := range searchIndexes {
ddl.Append(&ast.DropSearchIndex{Name: i.Name})
}

ddl.AppendDDL(g.generateDDLForDropColumn(from.Name, fromCol.Name))

if toCol.NotNull && toCol.GeneratedExpr == nil && toCol.DefaultExpr == nil {
Expand All @@ -523,6 +549,9 @@ func (g *Generator) generateDDLForDropAndCreateColumn(from, to *Table, fromCol,
for _, i := range indexes {
ddl.Append(i)
}
for _, i := range searchIndexes {
ddl.Append(i)
}
return ddl
}

Expand All @@ -546,6 +575,26 @@ func (g *Generator) generateDDLForDropIndex(from, to *Table) DDL {
return ddl
}

func (g *Generator) generateDDLForDropSearchIndex(from, to *Table) DDL {
ddl := DDL{}

for _, toIndex := range to.searchIndexes {
fromIndex, exists := g.findSearchIndexByName(from.searchIndexes, toIndex.Name.SQL())

if exists && !g.searchIndexEqual(fromIndex, toIndex) {
ddl.Append(&ast.DropSearchIndex{Name: fromIndex.Name})
g.dropedSearchIndex = append(g.dropedSearchIndex, fromIndex.Name.SQL())
}
}
for _, fromIndex := range from.searchIndexes {
if _, exists := g.findSearchIndexByName(to.searchIndexes, fromIndex.Name.SQL()); !exists {
ddl.Append(&ast.DropSearchIndex{Name: fromIndex.Name})
g.dropedSearchIndex = append(g.dropedSearchIndex, fromIndex.Name.SQL())
}
}
return ddl
}

func (g *Generator) generateDDLForCreateIndex(from, to *Table) DDL {
ddl := DDL{}

Expand All @@ -559,6 +608,19 @@ func (g *Generator) generateDDLForCreateIndex(from, to *Table) DDL {
return ddl
}

func (g *Generator) generateDDLForCreateSearchIndex(from, to *Table) DDL {
ddl := DDL{}

for _, toIndex := range to.searchIndexes {
fromIndex, exists := g.findSearchIndexByName(from.searchIndexes, toIndex.Name.SQL())

if !exists || !g.searchIndexEqual(fromIndex, toIndex) {
ddl.Append(toIndex)
}
}
return ddl
}

func (g *Generator) generateDDLForCreateChangeStream(from *Database, to *Table) DDL {
ddl := DDL{}

Expand Down Expand Up @@ -609,6 +671,15 @@ func (g *Generator) isDropedIndex(name string) bool {
return false
}

func (g *Generator) isDropedSearchIndex(name string) bool {
for _, t := range g.dropedSearchIndex {
if t == name {
return true
}
}
return false
}

func (g *Generator) isDroppedConstraint(constraint *ast.TableConstraint) bool {
for _, c := range g.droppedConstraints {
if g.constraintEqual(c, constraint) {
Expand Down Expand Up @@ -679,6 +750,11 @@ func (g *Generator) indexEqual(x, y *ast.CreateIndex) bool {
return cmp.Equal(x, y, cmpopts.IgnoreTypes(token.Pos(0)))
}

func (g *Generator) searchIndexEqual(x, y *ast.CreateSearchIndex) bool {
return cmp.Equal(x, y, cmpopts.IgnoreTypes(token.Pos(0)))

}

func (g *Generator) changeStreamForEqual(x, y ast.ChangeStreamFor) bool {
return cmp.Equal(x, y, cmpopts.IgnoreTypes(token.Pos(0)))
}
Expand Down Expand Up @@ -813,6 +889,15 @@ func (g *Generator) findIndexByName(indexes []*ast.CreateIndex, name string) (in
return nil, false
}

func (g *Generator) findSearchIndexByName(indexes []*ast.CreateSearchIndex, name string) (index *ast.CreateSearchIndex, exists bool) {
for _, i := range indexes {
if i.Name.SQL() == name {
return i, true
}
}
return nil, false
}

func (g *Generator) findIndexByColumn(indexes []*ast.CreateIndex, column string) []*ast.CreateIndex {
result := []*ast.CreateIndex{}
for _, i := range indexes {
Expand All @@ -826,6 +911,20 @@ func (g *Generator) findIndexByColumn(indexes []*ast.CreateIndex, column string)
return result
}

func (g *Generator) findSearchIndexByColumn(indexes []*ast.CreateSearchIndex, column string) []*ast.CreateSearchIndex {
result := []*ast.CreateSearchIndex{}
for _, i := range indexes {
for _, c := range i.TokenListPart {
if c.Name == column {
result = append(result, i)
break
}
}
}
return result

}

func (g *Generator) generateDDLForDropNamedConstraintsMatchingPredicate(predicate func(constraint *ast.TableConstraint) bool) DDL {
ddl := DDL{}

Expand Down
79 changes: 79 additions & 0 deletions internal/hammer/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,85 @@ CREATE INDEX idx_t1_2 ON t1(t1_3);
`CREATE INDEX idx_t1_2 ON t1 (t1_3)`,
},
},
{
name: "add search index",
from: `
CREATE TABLE t1 (
t1_1 INT64 NOT NULL,
t1_2 STRING(36) NOT NULL,
t1_3 TOKENLIST AS (TOKENIZE_FULLTEXT(t1_2)) HIDDEN,
t1_4 TOKENLIST AS (TOKENIZE_NGRAMS(t1_2)) HIDDEN,
) PRIMARY KEY(t1_1);
CREATE SEARCH INDEX idx_t1_1 ON t1(t1_3);
`,
to: `
CREATE TABLE t1 (
t1_1 INT64 NOT NULL,
t1_2 STRING(36) NOT NULL,
t1_3 TOKENLIST AS (TOKENIZE_FULLTEXT(t1_2)) HIDDEN,
t1_4 TOKENLIST AS (TOKENIZE_NGRAMS(t1_2)) HIDDEN,
) PRIMARY KEY(t1_1);
CREATE SEARCH INDEX idx_t1_1 ON t1(t1_3);
CREATE SEARCH INDEX idx_t1_2 ON t1(t1_4);
`,
expected: []string{
`CREATE SEARCH INDEX idx_t1_2 ON t1(t1_4)`,
},
},
{
name: "drop search index (different index positions)",
from: `
CREATE TABLE t1 (
t1_1 INT64 NOT NULL,
t1_2 STRING(36) NOT NULL,
t1_3 TOKENLIST AS (TOKENIZE_FULLTEXT(t1_2)) HIDDEN,
t1_4 TOKENLIST AS (TOKENIZE_NGRAMS(t1_2)) HIDDEN,
) PRIMARY KEY(t1_1);
CREATE SEARCH INDEX idx_t1_1 ON t1(t1_3);
CREATE SEARCH INDEX idx_t1_2 ON t1(t1_4);
`,
to: `
CREATE TABLE t1 (
t1_1 INT64 NOT NULL,
t1_2 STRING(36) NOT NULL,
t1_3 TOKENLIST AS (TOKENIZE_FULLTEXT(t1_2)) HIDDEN,
t1_4 TOKENLIST AS (TOKENIZE_NGRAMS(t1_2)) HIDDEN,
) PRIMARY KEY(t1_1);
CREATE SEARCH INDEX idx_t1_2 ON t1(t1_4);
`,
expected: []string{
`DROP SEARCH INDEX idx_t1_1`,
},
},
{
name: "change search indexed column",
from: `
CREATE TABLE t1 (
t1_1 INT64 NOT NULL,
t1_2 STRING(36) NOT NULL,
t1_3 TOKENLIST AS (TOKENIZE_FULLTEXT(t1_2)) HIDDEN,
t1_4 TOKENLIST AS (TOKENIZE_NGRAMS(t1_2)) HIDDEN,
) PRIMARY KEY(t1_1);
CREATE SEARCH INDEX idx_t1_1 ON t1(t1_3);
CREATE SEARCH INDEX idx_t1_2 ON t1(t1_4);
`,
to: `
CREATE TABLE t1 (
t1_1 INT64 NOT NULL,
t1_2 STRING(36) NOT NULL,
t1_3 TOKENLIST AS (TOKENIZE_FULLTEXT(t1_2)) HIDDEN,
t1_4 TOKENLIST AS (TOKENIZE_FULLTEXT(t1_2)) HIDDEN,
) PRIMARY KEY(t1_1);
CREATE SEARCH INDEX idx_t1_1 ON t1(t1_3);
CREATE SEARCH INDEX idx_t1_2 ON t1(t1_4);
`,
expected: []string{
`DROP SEARCH INDEX idx_t1_2`,
`ALTER TABLE t1 DROP COLUMN t1_4`,
`ALTER TABLE t1 ADD COLUMN t1_4 TOKENLIST AS (TOKENIZE_FULLTEXT(t1_2)) HIDDEN`,
`CREATE SEARCH INDEX idx_t1_2 ON t1(t1_4)`,
},
},
{
name: "change column (interleaved)",
from: `
Expand Down

0 comments on commit a1cb5d6

Please sign in to comment.