Skip to content

Commit 1f18154

Browse files
authored
Add support for renaming an index (#489)
1 parent 466cd19 commit 1f18154

9 files changed

Lines changed: 67 additions & 2 deletions

File tree

integration_test/sql/migration.exs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,20 @@ defmodule Ecto.Integration.MigrationTest do
271271
end
272272
end
273273

274+
defmodule RenameIndexMigration do
275+
use Ecto.Migration
276+
277+
def change do
278+
create table(:composite_parent) do
279+
add :key_id, :integer
280+
end
281+
282+
create unique_index(:composite_parent, [:id, :key_id], name: "old_index_name")
283+
284+
rename index(:composite_parent, [:id, :key_id], name: "old_index_name"), to: "new_index_name"
285+
end
286+
end
287+
274288
defmodule ReferencesRollbackMigration do
275289
use Ecto.Migration
276290

@@ -503,6 +517,11 @@ defmodule Ecto.Integration.MigrationTest do
503517
assert :ok == down(PoolRepo, num, CompositeForeignKeyMigration, log: false)
504518
end
505519

520+
test "rename index", %{migration_number: num} do
521+
assert :ok == up(PoolRepo, num, RenameIndexMigration, log: false)
522+
assert :ok == down(PoolRepo, num, RenameIndexMigration, log: false)
523+
end
524+
506525
test "rolls back references in change/1", %{migration_number: num} do
507526
assert :ok == up(PoolRepo, num, ReferencesRollbackMigration, log: false)
508527
assert :ok == down(PoolRepo, num, ReferencesRollbackMigration, log: false)

lib/ecto/adapters/myxql/connection.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,11 @@ if Code.ensure_loaded?(MyXQL) do
838838
def execute_ddl({:drop_if_exists, %Index{}, _}),
839839
do: error!(nil, "MySQL adapter does not support drop if exists for index")
840840

841+
def execute_ddl({:rename, %Index{} = index, new_name}) do
842+
[["ALTER TABLE ", quote_table(index.table), " RENAME INDEX ",
843+
quote_name(index.name), " TO ", quote_name(new_name)]]
844+
end
845+
841846
def execute_ddl({:rename, %Table{} = current_table, %Table{} = new_table}) do
842847
[["RENAME TABLE ", quote_table(current_table.prefix, current_table.name),
843848
" TO ", quote_table(new_table.prefix, new_table.name)]]

lib/ecto/adapters/postgres/connection.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,11 @@ if Code.ensure_loaded?(Postgrex) do
999999
drop_mode(mode)]]
10001000
end
10011001

1002+
def execute_ddl({:rename, %Index{} = current_index, new_name}) do
1003+
[["ALTER INDEX ", quote_name(current_index.name),
1004+
" RENAME TO ", quote_name(new_name)]]
1005+
end
1006+
10021007
def execute_ddl({:rename, %Table{} = current_table, %Table{} = new_table}) do
10031008
[["ALTER TABLE ", quote_table(current_table.prefix, current_table.name),
10041009
" RENAME TO ", quote_table(nil, new_table.name)]]

lib/ecto/adapters/tds/connection.ex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,15 @@ if Code.ensure_loaded?(Tds) do
11551155
]
11561156
end
11571157

1158+
def execute_ddl({:rename, %Index{} = current_index, new_name}) do
1159+
[[
1160+
"sp_rename ",
1161+
"N'#{current_index.table}.#{current_index.name}', ",
1162+
"N'#{new_name}', ",
1163+
"N'INDEX'"
1164+
]]
1165+
end
1166+
11581167
def execute_ddl({command, %Index{}, :cascade}) when command in @drops,
11591168
do: error!(nil, "MSSQL does not support `CASCADE` in DROP INDEX commands")
11601169

lib/ecto/migration.ex

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1066,17 +1066,26 @@ defmodule Ecto.Migration do
10661066
end
10671067

10681068
@doc """
1069-
Renames a table.
1069+
Renames a table or index.
10701070
10711071
## Examples
10721072
1073+
# rename a table
10731074
rename table("posts"), to: table("new_posts")
1075+
1076+
# rename an index
1077+
rename(index(:people, [:name], name: "persons_name_index"), to: "people_name_index")
10741078
"""
10751079
def rename(%Table{} = table_current, to: %Table{} = table_new) do
10761080
Runner.execute {:rename, __prefix__(table_current), __prefix__(table_new)}
10771081
table_new
10781082
end
10791083

1084+
def rename(%Index{} = current_index, to: new_name) do
1085+
Runner.execute({:rename, current_index, new_name})
1086+
%{current_index | name: new_name}
1087+
end
1088+
10801089
@doc """
10811090
Renames a column.
10821091

lib/ecto/migration/runner.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ defmodule Ecto.Migration.Runner do
224224
do: {:create, index}
225225
defp reverse({:drop_if_exists, %Index{} = index, _}),
226226
do: {:create_if_not_exists, index}
227-
227+
defp reverse({:rename, %Index{} = index, new_name}),
228+
do: {:rename, %{index | name: new_name}, index.name}
228229
defp reverse({:create, %Table{} = table, _columns}),
229230
do: {:drop, table, :restrict}
230231
defp reverse({:create_if_not_exists, %Table{} = table, _columns}),
@@ -418,6 +419,8 @@ defmodule Ecto.Migration.Runner do
418419
do: "drop index #{quote_name(index.prefix, index.name)}#{drop_mode(mode)}"
419420
defp command({:drop_if_exists, %Index{} = index, mode}),
420421
do: "drop index if exists #{quote_name(index.prefix, index.name)}#{drop_mode(mode)}"
422+
defp command({:rename, %Index{} = index_current, new_name}),
423+
do: "rename index #{quote_name(index_current.name)} to #{new_name}"
421424
defp command({:rename, %Table{} = current_table, %Table{} = new_table}),
422425
do: "rename table #{quote_name(current_table.prefix, current_table.name)} to #{quote_name(new_table.prefix, new_table.name)}"
423426
defp command({:rename, %Table{} = table, current_column, new_column}),

test/ecto/adapters/myxql_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,6 +1558,11 @@ defmodule Ecto.Adapters.MyXQLTest do
15581558
assert execute_ddl(drop) == [~s|DROP INDEX `posts$main` ON `foo`.`posts`|]
15591559
end
15601560

1561+
test "rename index" do
1562+
rename = {:rename, index(:people, [:name], name: "persons_name_index"), "people_name_index"}
1563+
assert execute_ddl(rename) == [~s|ALTER TABLE `people` RENAME INDEX `persons_name_index` TO `people_name_index`|]
1564+
end
1565+
15611566
test "rename table" do
15621567
rename = {:rename, table(:posts), table(:new_posts)}
15631568
assert execute_ddl(rename) == [~s|RENAME TABLE `posts` TO `new_posts`|]

test/ecto/adapters/postgres_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,6 +1964,11 @@ defmodule Ecto.Adapters.PostgresTest do
19641964
assert execute_ddl(drop) == [~s|DROP INDEX "foo"."posts$main" CASCADE|]
19651965
end
19661966

1967+
test "rename index" do
1968+
rename = {:rename, index(:people, [:name], name: "persons_name_index"), "people_name_index"}
1969+
assert execute_ddl(rename) == [~s|ALTER INDEX "persons_name_index" RENAME TO "people_name_index"|]
1970+
end
1971+
19671972
test "create check constraint" do
19681973
create = {:create, constraint(:products, "price_must_be_positive", check: "price > 0")}
19691974
assert execute_ddl(create) ==

test/ecto/adapters/tds_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,11 @@ defmodule Ecto.Adapters.TdsTest do
16701670
assert execute_ddl(drop) == [~s|DROP INDEX [posts$main] ON [posts] LOCK=NONE; |]
16711671
end
16721672

1673+
test "rename index" do
1674+
rename = {:rename, index(:people, [:name], name: "persons_name_index"), "people_name_index"}
1675+
assert execute_ddl(rename) == [~s|sp_rename N'people.persons_name_index', N'people_name_index', N'INDEX'|]
1676+
end
1677+
16731678
defp remove_newlines(string) when is_binary(string) do
16741679
string |> String.trim() |> String.replace("\n", " ")
16751680
end

0 commit comments

Comments
 (0)