Skip to content

Commit ab4db04

Browse files
authored
sql/sqlcheck/datadepend: dont report MF101 diag on index recreation (#3429)
* sql/sqlcheck/datadepend: dont report MF101 diag on index recreation
1 parent cd3c0ee commit ab4db04

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

sql/sqlcheck/datadepend/datadepend.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ var (
8181
// Diagnostics runs the common analysis on the file and returns its diagnostics.
8282
func (a *Analyzer) Diagnostics(_ context.Context, p *sqlcheck.Pass) (diags []sqlcheck.Diagnostic) {
8383
for _, sc := range p.File.Changes {
84+
var dropI []*schema.DropIndex
85+
for _, sc := range p.File.Changes {
86+
for _, c := range sc.Changes {
87+
m, ok := c.(*schema.ModifyTable)
88+
if !ok {
89+
continue
90+
}
91+
for _, mc := range m.Changes {
92+
if d, ok := mc.(*schema.DropIndex); ok {
93+
dropI = append(dropI, d)
94+
}
95+
}
96+
}
97+
}
8498
for _, c := range sc.Changes {
8599
m, ok := c.(*schema.ModifyTable)
86100
if !ok {
@@ -89,6 +103,32 @@ func (a *Analyzer) Diagnostics(_ context.Context, p *sqlcheck.Pass) (diags []sql
89103
for _, c := range m.Changes {
90104
switch c := c.(type) {
91105
case *schema.AddIndex:
106+
// Check if the current index is not unique or if it matches any of the dropped unique indexes by comparing their parts.
107+
if !c.I.Unique || slices.ContainsFunc(dropI, func(drop *schema.DropIndex) bool {
108+
if !drop.I.Unique || len(drop.I.Parts) > len(c.I.Parts) {
109+
return false
110+
}
111+
for _, p1 := range c.I.Parts {
112+
switch {
113+
case p1.C != nil:
114+
if p.File.ColumnSpan(m.T, p1.C)&sqlcheck.SpanAdded == 0 && !slices.ContainsFunc(drop.I.Parts, func(p2 *schema.IndexPart) bool {
115+
return p2.C != nil && p2.C.Name == p1.C.Name
116+
}) {
117+
return false
118+
}
119+
case p1.X != nil:
120+
if rx1, ok := p1.X.(*schema.RawExpr); ok && !slices.ContainsFunc(drop.I.Parts, func(p2 *schema.IndexPart) bool {
121+
rx2, ok := p2.X.(*schema.RawExpr)
122+
return ok && rx1.X == rx2.X
123+
}) {
124+
return false
125+
}
126+
}
127+
}
128+
return true
129+
}) {
130+
continue
131+
}
92132
names := func() []string {
93133
var names []string
94134
for i := range c.I.Parts {

sql/sqlcheck/datadepend/datadepend_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,54 @@ func TestAnalyzer_AddUniqueIndex(t *testing.T) {
8282
require.Len(t, report.Diagnostics, 2)
8383
require.Equal(t, `Adding a unique index "idx_b" on table "users" might fail in case column "b" contains duplicate entries`, report.Diagnostics[0].Text)
8484
require.Equal(t, `Adding a unique index "idx_c_d" on table "users" might fail in case columns "c", "d" contain duplicate entries`, report.Diagnostics[1].Text)
85+
86+
// Dropping index and then creating it again with added columns should not report any diagnostics.
87+
*report = sqlcheck.Report{}
88+
pass.File = &sqlcheck.File{
89+
Changes: []*sqlcheck.Change{
90+
{
91+
Stmt: &migrate.Stmt{
92+
Text: "ALTER TABLE users",
93+
},
94+
Changes: schema.Changes{
95+
&schema.ModifyTable{
96+
T: schema.NewTable("users").
97+
SetSchema(schema.New("test")).
98+
AddColumns(
99+
schema.NewColumn("a"),
100+
schema.NewColumn("b"),
101+
schema.NewColumn("c"),
102+
),
103+
Changes: []schema.Change{
104+
&schema.DropIndex{
105+
I: schema.NewUniqueIndex("idx_a_b").
106+
AddColumns(
107+
schema.NewColumn("a"),
108+
schema.NewColumn("b"),
109+
).
110+
AddExprs(&schema.RawExpr{X: "a + b"}),
111+
},
112+
&schema.AddColumn{C: schema.NewColumn("c")},
113+
&schema.AddIndex{
114+
I: schema.NewUniqueIndex("idx_a_b_c").
115+
AddColumns(
116+
schema.NewColumn("a"),
117+
schema.NewColumn("b"),
118+
schema.NewColumn("c"),
119+
).
120+
AddExprs(&schema.RawExpr{X: "a + b"}),
121+
},
122+
},
123+
},
124+
},
125+
},
126+
},
127+
}
128+
az, err = datadepend.New(nil, datadepend.Handler{})
129+
require.NoError(t, err)
130+
err = az.Analyze(context.Background(), pass)
131+
require.NoError(t, err)
132+
require.Len(t, report.Diagnostics, 0)
85133
}
86134

87135
func TestAnalyzer_ModifyUniqueIndex(t *testing.T) {

0 commit comments

Comments
 (0)