Repository: ariga/atlas
Pull request #506 (2022-01-27 09:28:19)

sql/postgres: support drop index reverse


Patch:
diff --git a/schema/schemaspec/schemahcl/hcl.go b/schema/schemaspec/schemahcl/hcl.go
index 03f2044e..943db72a 100644
--- a/schema/schemaspec/schemahcl/hcl.go
+++ b/schema/schemaspec/schemahcl/hcl.go
@@ -379,14 +379,11 @@ func hclRawList(items []string) hclwrite.Tokens {
 		Type:  hclsyntax.TokenOBrack,
 		Bytes: []byte("["),
 	}}
-	for _, item := range items {
-		t = append(t, &hclwrite.Token{
-			Type:  hclsyntax.TokenIdent,
-			Bytes: []byte(item),
-		}, &hclwrite.Token{
-			Type:  hclsyntax.TokenComma,
-			Bytes: []byte(","),
-		})
+	for i, item := range items {
+		if i > 0 {
+			t = append(t, &hclwrite.Token{Type: hclsyntax.TokenComma, Bytes: []byte(",")})
+		}
+		t = append(t, &hclwrite.Token{Type: hclsyntax.TokenIdent, Bytes: []byte(item)})
 	}
 	t = append(t, &hclwrite.Token{
 		Type:  hclsyntax.TokenCBrack,
diff --git a/sql/internal/specutil/convert.go b/sql/internal/specutil/convert.go
index 877aeedc..83ad0e3a 100644
--- a/sql/internal/specutil/convert.go
+++ b/sql/internal/specutil/convert.go
@@ -465,7 +465,7 @@ func FromIndex(idx *schema.Index) (*sqlspec.Index, error) {
 func columnsOnly(idx *schema.Index) ([]*schemaspec.Ref, bool) {
 	parts := make([]*schemaspec.Ref, len(idx.Parts))
 	for i, p := range idx.Parts {
-		if p.C == nil || p.Desc || len(p.Attrs) > 0 {
+		if p.C == nil || p.Desc {
 			return nil, false
 		}
 		parts[i] = colRef(p.C.Name, idx.Table.Name)
diff --git a/sql/postgres/migrate.go b/sql/postgres/migrate.go
index 67db315f..85f5478c 100644
--- a/sql/postgres/migrate.go
+++ b/sql/postgres/migrate.go
@@ -398,10 +398,13 @@ func (*state) indexComment(t *schema.Table, idx *schema.Index, to, from string)
 }
 
 func (s *state) dropIndexes(t *schema.Table, indexes ...*schema.Index) {
-	for _, idx := range indexes {
+	rs := &state{conn: s.conn}
+	rs.addIndexes(t, indexes...)
+	for i, idx := range indexes {
 		s.append(&migrate.Change{
-			Cmd:     Build("DROP INDEX").Ident(idx.Name).String(),
-			Comment: fmt.Sprintf("Drop index %q to table: %q", idx.Name, t.Name),
+			Cmd:     rs.Changes[i].Reverse,
+			Comment: fmt.Sprintf("Drop index %q from table: %q", idx.Name, t.Name),
+			Reverse: rs.Changes[i].Cmd,
 		})
 	}
 }
@@ -563,7 +566,7 @@ func (s *state) alterColumn(b *sqlx.Builder, k schema.ChangeKind, c *schema.Colu
 		case k.Is(schema.ChangeAttr):
 			id, ok := identity(c.Attrs)
 			if !ok {
-				return fmt.Errorf("unexpected attribute change: %v", c.Attrs)
+				return fmt.Errorf("unexpected attribute change (expect IDENTITY): %v", c.Attrs)
 			}
 			// The syntax for altering identity columns is identical to sequence_options.
 			// https://www.postgresql.org/docs/current/sql-altersequence.html


Test patch:
diff --git a/schema/schemaspec/schemahcl/context_test.go b/schema/schemaspec/schemahcl/context_test.go
index 4ef1b292..20c1b771 100644
--- a/schema/schemaspec/schemahcl/context_test.go
+++ b/schema/schemaspec/schemahcl/context_test.go
@@ -323,10 +323,10 @@ func TestSchemaRefParse(t *testing.T) {
 	require.NoError(t, err)
 	expected :=
 		`point {
-  z = [a, ]
+  z = [a]
 }
 point {
-  z = [b, ]
+  z = [b]
 }
 `
 	require.Equal(t, expected, string(b))
diff --git a/schema/schemaspec/schemahcl/hcl_test.go b/schema/schemaspec/schemahcl/hcl_test.go
index 49cb3c95..a086d6c9 100644
--- a/schema/schemaspec/schemahcl/hcl_test.go
+++ b/schema/schemaspec/schemahcl/hcl_test.go
@@ -14,8 +14,8 @@ func TestAttributes(t *testing.T) {
 	f := `i  = 1
 b  = true
 s  = "hello, world"
-sl = ["hello", "world", ]
-bl = [true, false, ]
+sl = ["hello", "world"]
+bl = [true, false]
 `
 	var test struct {
 		Int        int      `spec:"i"`
diff --git a/sql/mysql/sqlspec_test.go b/sql/mysql/sqlspec_test.go
index f72be8f0..2a04eefd 100644
--- a/sql/mysql/sqlspec_test.go
+++ b/sql/mysql/sqlspec_test.go
@@ -415,7 +415,7 @@ func TestMarshalSpec_Comment(t *testing.T) {
   }
   index "index" {
     unique  = true
-    columns = [table.users.column.a, ]
+    columns = [table.users.column.a]
     comment = "index comment"
   }
 }
diff --git a/sql/postgres/migrate_test.go b/sql/postgres/migrate_test.go
index 6e6ef1b5..ba9488c3 100644
--- a/sql/postgres/migrate_test.go
+++ b/sql/postgres/migrate_test.go
@@ -22,6 +22,44 @@ func TestPlanChanges(t *testing.T) {
 		mock    func(mock)
 		plan    *migrate.Plan
 	}{
+		{
+			changes: []schema.Change{
+				func() schema.Change {
+					users := &schema.Table{
+						Name: "users",
+						Columns: []*schema.Column{
+							{Name: "id", Type: &schema.ColumnType{Type: &schema.IntegerType{T: "bigint"}}},
+							{
+								Name: "name",
+								Type: &schema.ColumnType{Type: &schema.StringType{T: "varchar(255)"}},
+								Indexes: []*schema.Index{
+									schema.NewIndex("name_index").
+										AddParts(schema.NewColumnPart(schema.NewColumn("name"))),
+								},
+							}},
+					}
+					return &schema.ModifyTable{
+						T: users,
+						Changes: []schema.Change{
+							&schema.DropIndex{
+								I: schema.NewIndex("name_index").
+									AddParts(schema.NewColumnPart(schema.NewColumn("name"))),
+							},
+						},
+					}
+				}(),
+			},
+			plan: &migrate.Plan{
+				Reversible:    true,
+				Transactional: true,
+				Changes: []*migrate.Change{
+					{
+						Cmd:     `DROP INDEX "name_index"`,
+						Reverse: `CREATE INDEX "name_index" ON "users" ("name")`,
+					},
+				},
+			},
+		},
 		{
 			changes: []schema.Change{
 				&schema.AddSchema{S: &schema.Schema{Name: "test"}},
diff --git a/sql/postgres/sqlspec_test.go b/sql/postgres/sqlspec_test.go
index b93e696f..7f1000b3 100644
--- a/sql/postgres/sqlspec_test.go
+++ b/sql/postgres/sqlspec_test.go
@@ -226,7 +226,7 @@ schema "test" {
 }
 enum "account_type" {
   schema = schema.test
-  values = ["private", "business", ]
+  values = ["private", "business"]
 }
 `
 	require.EqualValues(t, expected, string(buf))