Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert DROP INDEX SQL to pgroll operation #524

Merged
merged 6 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pkg/sql2pgroll/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ func convert(sql string) (migrations.Operations, error) {
return convertAlterTableStmt(node.AlterTableStmt)
case *pgq.Node_RenameStmt:
return convertRenameStmt(node.RenameStmt)
case *pgq.Node_DropStmt:
return convertDropStatement(node.DropStmt)
default:
return makeRawSQLOperation(sql), nil
}
Expand Down
48 changes: 48 additions & 0 deletions pkg/sql2pgroll/drop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: Apache-2.0

package sql2pgroll

import (
"strings"

pgq "github.com/pganalyze/pg_query_go/v6"

"github.com/xataio/pgroll/pkg/migrations"
)

// convertDropStatement converts supported drop statements to pgroll operations
func convertDropStatement(stmt *pgq.DropStmt) (migrations.Operations, error) {
if stmt.RemoveType == pgq.ObjectType_OBJECT_INDEX {
return convertDropIndexStatement(stmt)
}
return nil, nil
}

// convertDropIndexStatement converts simple DROP INDEX statements to pgroll operations
func convertDropIndexStatement(stmt *pgq.DropStmt) (migrations.Operations, error) {
if !canConvertDropIndex(stmt) {
return nil, nil
}
items := stmt.GetObjects()[0].GetList().GetItems()
parts := make([]string, len(items))
for i, item := range items {
parts[i] = item.GetString_().GetSval()
}

return migrations.Operations{
&migrations.OpDropIndex{
Name: strings.Join(parts, "."),
},
}, nil
}

// canConvertDropIndex checks whether we can convert the statement without losing any information.
func canConvertDropIndex(stmt *pgq.DropStmt) bool {
if len(stmt.Objects) > 1 {
return false
}
if stmt.Behavior == pgq.DropBehavior_DROP_CASCADE {
return false
}
return true
}
74 changes: 74 additions & 0 deletions pkg/sql2pgroll/drop_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: Apache-2.0

package sql2pgroll_test

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/xataio/pgroll/pkg/migrations"
"github.com/xataio/pgroll/pkg/sql2pgroll"
"github.com/xataio/pgroll/pkg/sql2pgroll/expect"
)

func TestDropIndexStatements(t *testing.T) {
t.Parallel()

tests := []struct {
sql string
expectedOp migrations.Operation
}{
{
sql: "DROP INDEX foo",
expectedOp: expect.DropIndexOp1,
},
{
sql: "DROP INDEX myschema.foo",
expectedOp: expect.DropIndexOp2,
},
{
sql: "DROP INDEX foo RESTRICT",
expectedOp: expect.DropIndexOp1,
},
{
sql: "DROP INDEX IF EXISTS foo",
expectedOp: expect.DropIndexOp1,
},
{
sql: "DROP INDEX CONCURRENTLY foo",
expectedOp: expect.DropIndexOp1,
},
}

for _, tc := range tests {
t.Run(tc.sql, func(t *testing.T) {
ops, err := sql2pgroll.Convert(tc.sql)
require.NoError(t, err)

require.Len(t, ops, 1)

assert.Equal(t, tc.expectedOp, ops[0])
})
}
}

func TestUnconvertableDropIndexStatements(t *testing.T) {
t.Parallel()

tests := []string{
"DROP INDEX foo CASCADE",
}

for _, sql := range tests {
t.Run(sql, func(t *testing.T) {
ops, err := sql2pgroll.Convert(sql)
require.NoError(t, err)

require.Len(t, ops, 1)

assert.Equal(t, expect.RawSQLOp(sql), ops[0])
})
}
}
15 changes: 15 additions & 0 deletions pkg/sql2pgroll/expect/drop_index.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: Apache-2.0

package expect

import (
"github.com/xataio/pgroll/pkg/migrations"
)

var DropIndexOp1 = &migrations.OpDropIndex{
Name: "foo",
}

var DropIndexOp2 = &migrations.OpDropIndex{
Name: "myschema.foo",
}