Skip to content

Commit ac222a4

Browse files
authored
Convert DROP INDEX SQL to pgroll operation (#524)
Converts SQL in the following forms to the equivalent pgroll operation: ```sql DROP INDEX foo DROP INDEX schema.foo DROP INDEX foo RESTRICT DROP INDEX CONCURRENTLY foo DROP INDEX IF EXISTS foo ``` The following forms are left as raw SQL operations since we do not support them in pgroll yet: ```sql DROP INDEX foo CASCADE ``` Part of #504
1 parent ac10ab4 commit ac222a4

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed

pkg/sql2pgroll/convert.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ func convert(sql string) (migrations.Operations, error) {
4545
return convertAlterTableStmt(node.AlterTableStmt)
4646
case *pgq.Node_RenameStmt:
4747
return convertRenameStmt(node.RenameStmt)
48+
case *pgq.Node_DropStmt:
49+
return convertDropStatement(node.DropStmt)
4850
default:
4951
return makeRawSQLOperation(sql), nil
5052
}

pkg/sql2pgroll/drop.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package sql2pgroll
4+
5+
import (
6+
"strings"
7+
8+
pgq "github.com/pganalyze/pg_query_go/v6"
9+
10+
"github.com/xataio/pgroll/pkg/migrations"
11+
)
12+
13+
// convertDropStatement converts supported drop statements to pgroll operations
14+
func convertDropStatement(stmt *pgq.DropStmt) (migrations.Operations, error) {
15+
if stmt.RemoveType == pgq.ObjectType_OBJECT_INDEX {
16+
return convertDropIndexStatement(stmt)
17+
}
18+
return nil, nil
19+
}
20+
21+
// convertDropIndexStatement converts simple DROP INDEX statements to pgroll operations
22+
func convertDropIndexStatement(stmt *pgq.DropStmt) (migrations.Operations, error) {
23+
if !canConvertDropIndex(stmt) {
24+
return nil, nil
25+
}
26+
items := stmt.GetObjects()[0].GetList().GetItems()
27+
parts := make([]string, len(items))
28+
for i, item := range items {
29+
parts[i] = item.GetString_().GetSval()
30+
}
31+
32+
return migrations.Operations{
33+
&migrations.OpDropIndex{
34+
Name: strings.Join(parts, "."),
35+
},
36+
}, nil
37+
}
38+
39+
// canConvertDropIndex checks whether we can convert the statement without losing any information.
40+
func canConvertDropIndex(stmt *pgq.DropStmt) bool {
41+
if len(stmt.Objects) > 1 {
42+
return false
43+
}
44+
if stmt.Behavior == pgq.DropBehavior_DROP_CASCADE {
45+
return false
46+
}
47+
return true
48+
}

pkg/sql2pgroll/drop_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package sql2pgroll_test
4+
5+
import (
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/xataio/pgroll/pkg/migrations"
12+
"github.com/xataio/pgroll/pkg/sql2pgroll"
13+
"github.com/xataio/pgroll/pkg/sql2pgroll/expect"
14+
)
15+
16+
func TestDropIndexStatements(t *testing.T) {
17+
t.Parallel()
18+
19+
tests := []struct {
20+
sql string
21+
expectedOp migrations.Operation
22+
}{
23+
{
24+
sql: "DROP INDEX foo",
25+
expectedOp: expect.DropIndexOp1,
26+
},
27+
{
28+
sql: "DROP INDEX myschema.foo",
29+
expectedOp: expect.DropIndexOp2,
30+
},
31+
{
32+
sql: "DROP INDEX foo RESTRICT",
33+
expectedOp: expect.DropIndexOp1,
34+
},
35+
{
36+
sql: "DROP INDEX IF EXISTS foo",
37+
expectedOp: expect.DropIndexOp1,
38+
},
39+
{
40+
sql: "DROP INDEX CONCURRENTLY foo",
41+
expectedOp: expect.DropIndexOp1,
42+
},
43+
}
44+
45+
for _, tc := range tests {
46+
t.Run(tc.sql, func(t *testing.T) {
47+
ops, err := sql2pgroll.Convert(tc.sql)
48+
require.NoError(t, err)
49+
50+
require.Len(t, ops, 1)
51+
52+
assert.Equal(t, tc.expectedOp, ops[0])
53+
})
54+
}
55+
}
56+
57+
func TestUnconvertableDropIndexStatements(t *testing.T) {
58+
t.Parallel()
59+
60+
tests := []string{
61+
"DROP INDEX foo CASCADE",
62+
}
63+
64+
for _, sql := range tests {
65+
t.Run(sql, func(t *testing.T) {
66+
ops, err := sql2pgroll.Convert(sql)
67+
require.NoError(t, err)
68+
69+
require.Len(t, ops, 1)
70+
71+
assert.Equal(t, expect.RawSQLOp(sql), ops[0])
72+
})
73+
}
74+
}

pkg/sql2pgroll/expect/drop_index.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package expect
4+
5+
import (
6+
"github.com/xataio/pgroll/pkg/migrations"
7+
)
8+
9+
var DropIndexOp1 = &migrations.OpDropIndex{
10+
Name: "foo",
11+
}
12+
13+
var DropIndexOp2 = &migrations.OpDropIndex{
14+
Name: "myschema.foo",
15+
}

0 commit comments

Comments
 (0)