From d94d3b4a9e546ed0d03227649d69aa95c9c85f30 Mon Sep 17 00:00:00 2001 From: Andrew Farries Date: Thu, 5 Dec 2024 08:02:53 +0000 Subject: [PATCH] Convert `RENAME COLUMN` to `pgroll` operation (#511) Convert SQL statements of the form: ```sql ALTER TABLE foo RENAME COLUMN a TO b ALTER TABLE foo RENAME a TO b ``` to the equivalent `OpAlterColumn` operation: ```json [ { "alter_column": { "table": "foo", "column": "a", "name": "b" } } ] ``` Part of #504 --- pkg/sql2pgroll/convert.go | 2 ++ pkg/sql2pgroll/expect/alter_table.go | 6 ++++ pkg/sql2pgroll/rename.go | 25 +++++++++++++++++ pkg/sql2pgroll/rename_test.go | 42 ++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 pkg/sql2pgroll/rename.go create mode 100644 pkg/sql2pgroll/rename_test.go diff --git a/pkg/sql2pgroll/convert.go b/pkg/sql2pgroll/convert.go index 372f25cf..663e5b0c 100644 --- a/pkg/sql2pgroll/convert.go +++ b/pkg/sql2pgroll/convert.go @@ -42,6 +42,8 @@ func convert(sql string) (migrations.Operations, error) { return convertCreateStmt(node.CreateStmt) case *pgq.Node_AlterTableStmt: return convertAlterTableStmt(node.AlterTableStmt) + case *pgq.Node_RenameStmt: + return convertRenameStmt(node.RenameStmt) default: return makeRawSQLOperation(sql), nil } diff --git a/pkg/sql2pgroll/expect/alter_table.go b/pkg/sql2pgroll/expect/alter_table.go index d2cccff6..e912a157 100644 --- a/pkg/sql2pgroll/expect/alter_table.go +++ b/pkg/sql2pgroll/expect/alter_table.go @@ -55,6 +55,12 @@ var AlterTableOp5 = &migrations.OpCreateConstraint{ }, } +var AlterTableOp6 = &migrations.OpAlterColumn{ + Table: "foo", + Column: "a", + Name: ptr("b"), +} + func ptr[T any](v T) *T { return &v } diff --git a/pkg/sql2pgroll/rename.go b/pkg/sql2pgroll/rename.go new file mode 100644 index 00000000..a9f58340 --- /dev/null +++ b/pkg/sql2pgroll/rename.go @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 + +package sql2pgroll + +import ( + pgq "github.com/pganalyze/pg_query_go/v6" + "github.com/xataio/pgroll/pkg/migrations" +) + +func convertRenameStmt(stmt *pgq.RenameStmt) (migrations.Operations, error) { + if stmt.GetRelationType() != pgq.ObjectType_OBJECT_TABLE { + return nil, nil + } + if stmt.GetRenameType() != pgq.ObjectType_OBJECT_COLUMN { + return nil, nil + } + + return migrations.Operations{ + &migrations.OpAlterColumn{ + Table: stmt.GetRelation().GetRelname(), + Column: stmt.GetSubname(), + Name: ptr(stmt.GetNewname()), + }, + }, nil +} diff --git a/pkg/sql2pgroll/rename_test.go b/pkg/sql2pgroll/rename_test.go new file mode 100644 index 00000000..217cb145 --- /dev/null +++ b/pkg/sql2pgroll/rename_test.go @@ -0,0 +1,42 @@ +// 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 TestConvertRenameColumnStatements(t *testing.T) { + t.Parallel() + + tests := []struct { + sql string + expectedOp migrations.Operation + }{ + { + sql: "ALTER TABLE foo RENAME COLUMN a TO b", + expectedOp: expect.AlterTableOp6, + }, + { + sql: "ALTER TABLE foo RENAME a TO b", + expectedOp: expect.AlterTableOp6, + }, + } + + 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]) + }) + } +}