Skip to content

Commit 971b6a0

Browse files
sql/ydb: removed sync index type and added cover columns
1 parent e6ef71c commit 971b6a0

File tree

3 files changed

+190
-26
lines changed

3 files changed

+190
-26
lines changed

sql/ydb/attributes.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ package ydb
88

99
import "ariga.io/atlas/sql/schema"
1010

11-
//[IndexAttributes] represents YDB-specific index attributes.
11+
// [IndexAttributes] represents YDB-specific index attributes.
1212
type IndexAttributes struct {
1313
schema.Attr
14-
Global bool // GLOBAL, LOCAL
15-
Sync bool // SYNC, ASYNC
14+
Async bool
15+
CoverColumns []*schema.Column
1616
}

sql/ydb/migrate.go

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -290,30 +290,30 @@ func (s *state) addIndexes(src schema.Change, t *schema.Table, indexes ...*schem
290290
indexAttrs := IndexAttributes{}
291291
hasAttrs := sqlx.Has(index.Attrs, &indexAttrs)
292292

293-
b := s.Build("ALTER TABLE").
293+
builder := s.Build("ALTER TABLE").
294294
Table(t).
295295
P("ADD INDEX").
296-
Ident(index.Name)
297-
298-
if hasAttrs && !indexAttrs.Global {
299-
b.P("LOCAL")
300-
} else {
301-
b.P("GLOBAL")
302-
}
296+
Ident(index.Name).
297+
P("GLOBAL")
303298

304299
if index.Unique {
305-
b.P("UNIQUE")
300+
builder.P("UNIQUE")
306301
}
307302

308-
if hasAttrs && !indexAttrs.Sync {
309-
b.P("ASYNC")
303+
if hasAttrs && indexAttrs.Async {
304+
builder.P("ASYNC")
310305
} else {
311-
b.P("SYNC")
306+
builder.P("SYNC")
312307
}
313308

314-
b.P("ON")
309+
builder.P("ON")
310+
311+
s.indexParts(builder, index.Parts)
315312

316-
s.indexParts(b, index.Parts)
313+
if hasAttrs && len(indexAttrs.CoverColumns) > 0 {
314+
builder.P("COVER")
315+
s.indexCoverColumns(builder, indexAttrs.CoverColumns)
316+
}
317317

318318
reverseOp := s.Build("ALTER TABLE").
319319
Table(t).
@@ -322,7 +322,7 @@ func (s *state) addIndexes(src schema.Change, t *schema.Table, indexes ...*schem
322322
String()
323323

324324
s.append(&migrate.Change{
325-
Cmd: b.String(),
325+
Cmd: builder.String(),
326326
Source: src,
327327
Comment: fmt.Sprintf("create index %q to table: %q", index.Name, t.Name),
328328
Reverse: reverseOp,
@@ -396,19 +396,25 @@ func (s *state) indexDef(b *sqlx.Builder, idx *schema.Index) {
396396
}
397397

398398
// indexParts writes the index parts (columns) to the builder.
399-
func (s *state) indexParts(b *sqlx.Builder, parts []*schema.IndexPart) {
400-
b.Wrap(func(b *sqlx.Builder) {
401-
b.MapComma(parts, func(i int, b *sqlx.Builder) {
402-
switch part := parts[i]; {
403-
case part.C != nil:
404-
b.Ident(part.C.Name)
405-
case part.X != nil:
406-
b.WriteString(part.X.(*schema.RawExpr).X)
399+
func (s *state) indexParts(builder *sqlx.Builder, parts []*schema.IndexPart) {
400+
builder.Wrap(func(b *sqlx.Builder) {
401+
b.MapComma(parts, func(i int, builder *sqlx.Builder) {
402+
if parts[i].C != nil {
403+
builder.Ident(parts[i].C.Name)
407404
}
408405
})
409406
})
410407
}
411408

409+
// indexCoverColumns writes the cover columns to the builder.
410+
func (s *state) indexCoverColumns(builder *sqlx.Builder, coverColumns []*schema.Column) {
411+
builder.Wrap(func(b *sqlx.Builder) {
412+
b.MapComma(coverColumns, func(i int, builder *sqlx.Builder) {
413+
builder.Ident(coverColumns[i].Name)
414+
})
415+
})
416+
}
417+
412418
// append adds changes to the plan.
413419
func (s *state) append(c ...*migrate.Change) {
414420
s.Changes = append(s.Changes, c...)

sql/ydb/migrate_test.go

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,103 @@ func TestPlanChanges_AddIndex(t *testing.T) {
583583
},
584584
},
585585
},
586+
{
587+
name: "add async index",
588+
changes: []schema.Change{
589+
&schema.ModifyTable{
590+
T: usersTable,
591+
Changes: []schema.Change{
592+
&schema.AddIndex{
593+
I: func() *schema.Index {
594+
idx := schema.NewIndex("idx_name_async").AddColumns(usersTable.Columns[1])
595+
idx.Attrs = append(idx.Attrs, &IndexAttributes{Async: true})
596+
return idx
597+
}(),
598+
},
599+
},
600+
},
601+
},
602+
wantPlan: &migrate.Plan{
603+
Transactional: false,
604+
Changes: []*migrate.Change{
605+
{
606+
Cmd: "ALTER TABLE `users` ADD INDEX `idx_name_async` GLOBAL ASYNC ON (`name`)",
607+
Reverse: "ALTER TABLE `users` DROP INDEX `idx_name_async`",
608+
Comment: `create index "idx_name_async" to table: "users"`,
609+
},
610+
},
611+
},
612+
},
613+
{
614+
name: "add index with cover columns",
615+
changes: []schema.Change{
616+
&schema.ModifyTable{
617+
T: usersTable,
618+
Changes: []schema.Change{
619+
&schema.AddIndex{
620+
I: func() *schema.Index {
621+
idx := schema.NewIndex("idx_name_cover").AddColumns(usersTable.Columns[1])
622+
idx.Attrs = append(
623+
idx.Attrs,
624+
&IndexAttributes{
625+
CoverColumns: []*schema.Column{
626+
{Name: "email"},
627+
},
628+
},
629+
)
630+
return idx
631+
}(),
632+
},
633+
},
634+
},
635+
},
636+
wantPlan: &migrate.Plan{
637+
Transactional: false,
638+
Changes: []*migrate.Change{
639+
{
640+
Cmd: "ALTER TABLE `users` ADD INDEX `idx_name_cover` GLOBAL SYNC ON (`name`) COVER (`email`)",
641+
Reverse: "ALTER TABLE `users` DROP INDEX `idx_name_cover`",
642+
Comment: `create index "idx_name_cover" to table: "users"`,
643+
},
644+
},
645+
},
646+
},
647+
{
648+
name: "add async index with cover columns",
649+
changes: []schema.Change{
650+
&schema.ModifyTable{
651+
T: usersTable,
652+
Changes: []schema.Change{
653+
&schema.AddIndex{
654+
I: func() *schema.Index {
655+
idx := schema.NewIndex("idx_name_async_cover").AddColumns(usersTable.Columns[1])
656+
idx.Attrs = append(
657+
idx.Attrs,
658+
&IndexAttributes{
659+
Async: true,
660+
CoverColumns: []*schema.Column{
661+
{Name: "email"},
662+
{Name: "id"},
663+
},
664+
},
665+
)
666+
return idx
667+
}(),
668+
},
669+
},
670+
},
671+
},
672+
wantPlan: &migrate.Plan{
673+
Transactional: false,
674+
Changes: []*migrate.Change{
675+
{
676+
Cmd: "ALTER TABLE `users` ADD INDEX `idx_name_async_cover` GLOBAL ASYNC ON (`name`) COVER (`email`, `id`)",
677+
Reverse: "ALTER TABLE `users` DROP INDEX `idx_name_async_cover`",
678+
Comment: `create index "idx_name_async_cover" to table: "users"`,
679+
},
680+
},
681+
},
682+
},
586683
{
587684
name: "add multiple indexes",
588685
changes: []schema.Change{
@@ -702,6 +799,67 @@ func TestPlanChanges_DropIndex(t *testing.T) {
702799
},
703800
},
704801
},
802+
{
803+
name: "drop async index",
804+
changes: []schema.Change{
805+
&schema.ModifyTable{
806+
T: usersTable,
807+
Changes: []schema.Change{
808+
&schema.DropIndex{
809+
I: func() *schema.Index {
810+
idx := schema.NewIndex("idx_name_async").AddColumns(usersTable.Columns[1])
811+
idx.Attrs = append(idx.Attrs, &IndexAttributes{Async: true})
812+
return idx
813+
}(),
814+
},
815+
},
816+
},
817+
},
818+
wantPlan: &migrate.Plan{
819+
Transactional: false,
820+
Changes: []*migrate.Change{
821+
{
822+
Cmd: "ALTER TABLE `users` DROP INDEX `idx_name_async`",
823+
Reverse: "ALTER TABLE `users` ADD INDEX `idx_name_async` GLOBAL ASYNC ON (`name`)",
824+
Comment: `drop index "idx_name_async" from table: "users"`,
825+
},
826+
},
827+
},
828+
},
829+
{
830+
name: "drop index with cover columns",
831+
changes: []schema.Change{
832+
&schema.ModifyTable{
833+
T: usersTable,
834+
Changes: []schema.Change{
835+
&schema.DropIndex{
836+
I: func() *schema.Index {
837+
idx := schema.NewIndex("idx_name_cover").AddColumns(usersTable.Columns[1])
838+
idx.Attrs = append(
839+
idx.Attrs,
840+
&IndexAttributes{
841+
CoverColumns: []*schema.Column{
842+
{Name: "email"},
843+
},
844+
},
845+
)
846+
return idx
847+
}(),
848+
},
849+
},
850+
},
851+
},
852+
wantPlan: &migrate.Plan{
853+
Transactional: false,
854+
Changes: []*migrate.Change{
855+
{
856+
Cmd: "ALTER TABLE `users` DROP INDEX `idx_name_cover`",
857+
Reverse: "ALTER TABLE `users` ADD INDEX `idx_name_cover` GLOBAL SYNC ON (`name`) COVER (`email`)",
858+
Comment: `drop index "idx_name_cover" from table: "users"`,
859+
},
860+
},
861+
},
862+
},
705863
}
706864

707865
for _, tt := range tests {

0 commit comments

Comments
 (0)