Skip to content

Commit fe25ee5

Browse files
committed
Add support for search indexes
1 parent e04a64f commit fe25ee5

3 files changed

Lines changed: 197 additions & 0 deletions

File tree

internal/hammer/ddl.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ func (a AlterColumn) SQL() string {
8080
if a.Def.NotNull {
8181
str += " NOT NULL"
8282
}
83+
if !a.Def.Hidden.Invalid() {
84+
str += " HIDDEN"
85+
}
8386
if a.Def.DefaultSemantics != nil {
8487
str += " " + a.Def.DefaultSemantics.SQL()
8588
}

internal/hammer/diff.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ func NewDatabase(ddl DDL) (*Database, error) {
5151
} else {
5252
return nil, fmt.Errorf("cannot find ddl of table to apply index %s", stmt.Name.SQL())
5353
}
54+
case *ast.CreateSearchIndex:
55+
if t, ok := m[identsToComparable(stmt.TableName)]; ok {
56+
t.searchIndexes = append(t.searchIndexes, stmt)
57+
} else {
58+
return nil, fmt.Errorf("cannot find ddl of table to apply search index %s", stmt.Name.SQL())
59+
}
5460
case *ast.AlterTable:
5561
t, ok := m[identsToComparable(stmt.Name.Idents...)]
5662
if !ok {
@@ -109,6 +115,7 @@ type Table struct {
109115
*ast.CreateTable
110116

111117
indexes []*ast.CreateIndex
118+
searchIndexes []*ast.CreateSearchIndex
112119
children []*Table
113120
changeStreams []*ChangeStream
114121
}
@@ -305,6 +312,9 @@ func (g *Generator) generateDDLForCreateTableAndIndex(table *Table) DDL {
305312
for _, i := range table.indexes {
306313
ddl.Append(i)
307314
}
315+
for _, i := range table.searchIndexes {
316+
ddl.Append(i)
317+
}
308318
for _, cs := range table.changeStreams {
309319
g.willCreateOrAlterChangeStreamIDs[identsToComparable(cs.Name)] = cs
310320
}
@@ -323,6 +333,9 @@ func (g *Generator) generateDDLForDropConstraintIndexAndTable(table *Table) DDL
323333
for _, i := range table.indexes {
324334
ddl.Append(&ast.DropIndex{Name: i.Name})
325335
}
336+
for _, i := range table.searchIndexes {
337+
ddl.Append(&ast.DropSearchIndex{Name: i.Name})
338+
}
326339
for _, cs := range table.changeStreams {
327340
if !g.isDropedChangeStream(identsToComparable(cs.Name)) {
328341
ddl.Append(&ast.DropChangeStream{Name: cs.Name})
@@ -415,6 +428,7 @@ func (g *Generator) generateDDLForRowDeletionPolicy(from, to *Table) DDL {
415428

416429
return ddl
417430
}
431+
418432
func (g *Generator) generateDDLForColumns(from, to *Table) DDL {
419433
ddl := DDL{}
420434

@@ -519,6 +533,16 @@ func (g *Generator) generateDDLForDropAndCreateColumn(from, to *Table, fromCol,
519533
ddl.Append(&ast.DropIndex{Name: i.Name})
520534
}
521535

536+
searchIndexes := []*ast.CreateSearchIndex{}
537+
for _, i := range g.findSearchIndexByColumn(from.searchIndexes, identsToComparable(fromCol.Name)) {
538+
if !g.isDropedIndex(identsToComparable(i.Name)) {
539+
searchIndexes = append(searchIndexes, i)
540+
}
541+
}
542+
for _, i := range searchIndexes {
543+
ddl.Append(&ast.DropSearchIndex{Name: i.Name})
544+
}
545+
522546
ddl.AppendDDL(g.generateDDLForDropColumn(from.Name, fromCol.Name))
523547

524548
if toCol.NotNull && toCol.DefaultSemantics == nil {
@@ -530,6 +554,9 @@ func (g *Generator) generateDDLForDropAndCreateColumn(from, to *Table, fromCol,
530554
for _, i := range indexes {
531555
ddl.Append(i)
532556
}
557+
for _, i := range searchIndexes {
558+
ddl.Append(i)
559+
}
533560
return ddl
534561
}
535562

@@ -550,6 +577,22 @@ func (g *Generator) generateDDLForDropIndex(from, to *Table) DDL {
550577
g.dropedIndex = append(g.dropedIndex, identsToComparable(fromIndex.Name.Idents...))
551578
}
552579
}
580+
581+
for _, toIndex := range to.searchIndexes {
582+
fromIndex, exists := g.findSearchIndexByName(from.searchIndexes, identsToComparable(toIndex.Name))
583+
584+
if exists && !g.searchIndexEqual(*fromIndex, *toIndex) {
585+
ddl.Append(&ast.DropSearchIndex{Name: fromIndex.Name})
586+
g.dropedIndex = append(g.dropedIndex, identsToComparable(fromIndex.Name))
587+
}
588+
}
589+
for _, fromIndex := range from.searchIndexes {
590+
if _, exists := g.findSearchIndexByName(to.searchIndexes, identsToComparable(fromIndex.Name)); !exists {
591+
ddl.Append(&ast.DropSearchIndex{Name: fromIndex.Name})
592+
g.dropedIndex = append(g.dropedIndex, identsToComparable(fromIndex.Name))
593+
}
594+
}
595+
553596
return ddl
554597
}
555598

@@ -563,6 +606,15 @@ func (g *Generator) generateDDLForCreateIndex(from, to *Table) DDL {
563606
ddl.Append(toIndex)
564607
}
565608
}
609+
610+
for _, toIndex := range to.searchIndexes {
611+
fromIndex, exists := g.findSearchIndexByName(from.searchIndexes, identsToComparable(toIndex.Name))
612+
613+
if !exists || !g.searchIndexEqual(*fromIndex, *toIndex) {
614+
ddl.Append(toIndex)
615+
}
616+
}
617+
566618
return ddl
567619
}
568620

@@ -574,6 +626,7 @@ func (g *Generator) generateDDLForCreateChangeStream(from *Database, to *Table)
574626
}
575627
return ddl
576628
}
629+
577630
func (g *Generator) generateDDLForDropNamedConstraint(table *ast.Path, constraint *ast.TableConstraint) DDL {
578631
ddl := DDL{}
579632

@@ -633,6 +686,7 @@ func (g *Generator) isDropedChangeStream(name string) bool {
633686
}
634687
return false
635688
}
689+
636690
func (g *Generator) interleaveEqual(x, y *Table) bool {
637691
return cmp.Equal(x.Cluster, y.Cluster, cmpopts.IgnoreTypes(token.Pos(0)))
638692
}
@@ -711,6 +765,10 @@ func (g *Generator) indexEqual(x, y *ast.CreateIndex) bool {
711765
)
712766
}
713767

768+
func (g *Generator) searchIndexEqual(x, y ast.CreateSearchIndex) bool {
769+
return cmp.Equal(x, y, cmpopts.IgnoreTypes(token.Pos(0)))
770+
}
771+
714772
func (g *Generator) changeStreamForEqual(x, y ast.ChangeStreamFor) bool {
715773
return cmp.Equal(x, y, cmpopts.IgnoreTypes(token.Pos(0)))
716774
}
@@ -869,6 +927,28 @@ func (g *Generator) findIndexByColumn(indexes []*ast.CreateIndex, column string)
869927
return result
870928
}
871929

930+
func (g *Generator) findSearchIndexByName(indexes []*ast.CreateSearchIndex, name string) (index *ast.CreateSearchIndex, exists bool) {
931+
for _, i := range indexes {
932+
if identsToComparable(i.Name) == name {
933+
return i, true
934+
}
935+
}
936+
return nil, false
937+
}
938+
939+
func (g *Generator) findSearchIndexByColumn(indexes []*ast.CreateSearchIndex, column string) []*ast.CreateSearchIndex {
940+
result := []*ast.CreateSearchIndex{}
941+
for _, i := range indexes {
942+
for _, c := range i.TokenListPart {
943+
if c.Name == column {
944+
result = append(result, i)
945+
break
946+
}
947+
}
948+
}
949+
return result
950+
}
951+
872952
func (g *Generator) generateDDLForDropNamedConstraintsMatchingPredicate(predicate func(constraint *ast.TableConstraint) bool) DDL {
873953
ddl := DDL{}
874954

internal/hammer/diff_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,23 @@ CREATE TABLE t1 (
402402
`ALTER TABLE t1 ALTER COLUMN t1_2 SET OPTIONS (allow_commit_timestamp = null)`,
403403
},
404404
},
405+
{
406+
name: "add hidden column",
407+
from: `
408+
CREATE TABLE t1 (
409+
t1_1 STRING(36) NOT NULL,
410+
) PRIMARY KEY(t1_1);
411+
`,
412+
to: `
413+
CREATE TABLE t1 (
414+
t1_1 STRING(36) NOT NULL,
415+
t1_2 TOKENLIST AS (TOKENIZE_NUMBER(Value, comparison_type => "all", min => 1, max => 5)) HIDDEN,
416+
) PRIMARY KEY(t1_1);
417+
`,
418+
expected: []string{
419+
`ALTER TABLE t1 ADD COLUMN t1_2 TOKENLIST AS (TOKENIZE_NUMBER(Value, comparison_type => "all", min => 1, max => 5)) HIDDEN`,
420+
},
421+
},
405422
{
406423
name: "add generated column",
407424
from: `
@@ -535,6 +552,103 @@ CREATE INDEX idx_t1_2 ON t1(t1_3);
535552
`CREATE INDEX idx_t1_2 ON t1(t1_3)`,
536553
},
537554
},
555+
{
556+
name: "add search index",
557+
from: `
558+
CREATE TABLE t1 (
559+
t1_1 STRING(MAX) NOT NULL,
560+
t1_2 INT64 NOT NULL,
561+
t1_3 TOKENLIST AS (TOKENIZE_FULLTEXT(Name)) HIDDEN,
562+
) PRIMARY KEY(t1_1);
563+
CREATE INDEX idx_t1_1 ON t1(t1_2);
564+
`,
565+
to: `
566+
CREATE TABLE t1 (
567+
t1_1 STRING(MAX) NOT NULL,
568+
t1_2 INT64 NOT NULL,
569+
t1_3 TOKENLIST AS (TOKENIZE_FULLTEXT(Name)) HIDDEN,
570+
) PRIMARY KEY(t1_1);
571+
CREATE INDEX idx_t1_1 ON t1(t1_2);
572+
CREATE SEARCH INDEX idx_t1_3 ON t1(t1_3);
573+
`,
574+
expected: []string{
575+
`CREATE SEARCH INDEX idx_t1_3 ON t1(t1_3)`,
576+
},
577+
},
578+
{
579+
name: "add advanced search index",
580+
from: `
581+
CREATE TABLE t1 (
582+
t1_1 STRING(MAX) NOT NULL,
583+
t1_2 INT64 NOT NULL,
584+
t1_3 TOKENLIST AS (TOKENIZE_SUBSTRING(Name)) HIDDEN,
585+
t1_4 INT64 NOT NULL,
586+
) PRIMARY KEY(t1_1);
587+
`,
588+
to: `
589+
CREATE TABLE t1 (
590+
t1_1 STRING(MAX) NOT NULL,
591+
t1_2 INT64 NOT NULL,
592+
t1_3 TOKENLIST AS (TOKENIZE_SUBSTRING(Name)) HIDDEN,
593+
t1_4 INT64 NOT NULL,
594+
) PRIMARY KEY(t1_1);
595+
CREATE SEARCH INDEX idx_t1_3 ON t1(t1_3) STORING (t1_4)
596+
PARTITION BY t1_4
597+
ORDER BY t1_1 DESC, INTERLEAVE IN (t1)
598+
OPTIONS (sort_order_sharding=true);
599+
`,
600+
expected: []string{
601+
`CREATE SEARCH INDEX idx_t1_3 ON t1(t1_3) STORING (t1_4) PARTITION BY t1_4 ORDER BY t1_1 DESC, INTERLEAVE IN (t1) OPTIONS (sort_order_sharding = true)`,
602+
},
603+
},
604+
{
605+
name: "alter search index",
606+
from: `
607+
CREATE TABLE t1 (
608+
t1_1 STRING(MAX) NOT NULL,
609+
t1_2 TOKENLIST AS (TOKENIZE_FULLTEXT(Name)) HIDDEN,
610+
t1_3 STRING(MAX) NOT NULL,
611+
t1_4 TOKENLIST AS (TOKENIZE_FULLTEXT(Name)) HIDDEN,
612+
) PRIMARY KEY(t1_1);
613+
CREATE SEARCH INDEX idx_t1_2 ON t1(t1_2);
614+
`,
615+
to: `
616+
CREATE TABLE t1 (
617+
t1_1 STRING(MAX) NOT NULL,
618+
t1_2 TOKENLIST AS (TOKENIZE_FULLTEXT(Name)) HIDDEN,
619+
t1_3 STRING(MAX) NOT NULL,
620+
t1_4 TOKENLIST AS (TOKENIZE_FULLTEXT(Name)) HIDDEN,
621+
) PRIMARY KEY(t1_1);
622+
CREATE SEARCH INDEX idx_t1_2 ON t1(t1_2, t1_4);
623+
`,
624+
expected: []string{
625+
`DROP SEARCH INDEX idx_t1_2`,
626+
`CREATE SEARCH INDEX idx_t1_2 ON t1(t1_2, t1_4)`,
627+
},
628+
},
629+
{
630+
name: "drop search index",
631+
from: `
632+
CREATE TABLE t1 (
633+
t1_1 STRING(MAX) NOT NULL,
634+
t1_2 TOKENLIST AS (TOKENIZE_FULLTEXT(Name)) HIDDEN,
635+
t1_3 STRING(MAX) NOT NULL,
636+
t1_4 TOKENLIST AS (TOKENIZE_FULLTEXT(Name)) HIDDEN,
637+
) PRIMARY KEY(t1_1);
638+
CREATE SEARCH INDEX idx_t1_2 ON t1(t1_2);
639+
`,
640+
to: `
641+
CREATE TABLE t1 (
642+
t1_1 STRING(MAX) NOT NULL,
643+
t1_2 TOKENLIST AS (TOKENIZE_FULLTEXT(Name)) HIDDEN,
644+
t1_3 STRING(MAX) NOT NULL,
645+
t1_4 TOKENLIST AS (TOKENIZE_FULLTEXT(Name)) HIDDEN,
646+
) PRIMARY KEY(t1_1);
647+
`,
648+
expected: []string{
649+
`DROP SEARCH INDEX idx_t1_2`,
650+
},
651+
},
538652
{
539653
name: "change column (interleaved)",
540654
from: `

0 commit comments

Comments
 (0)