Skip to content

Commit fc2e173

Browse files
committed
should be smarter now?
1 parent 475cf8c commit fc2e173

File tree

2 files changed

+60
-22
lines changed

2 files changed

+60
-22
lines changed

integration_test/sql/migration.exs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,21 @@ defmodule Ecto.Integration.MigrationTest do
134134
add :alter_fk_user_id, :id
135135
end
136136

137+
create table(:alter_fk_comments) do
138+
add :alter_fk_user_id, references(:alter_fk_users)
139+
end
140+
137141
alter table(:alter_fk_posts) do
138-
modify :alter_fk_user_id, references(:alter_fk_users, on_delete: :nilify_all)
142+
modify :alter_fk_user_id, references(:alter_fk_users, on_delete: :nilify_all), from: {:id, null: true}
143+
end
144+
145+
alter table(:alter_fk_comments) do
146+
modify :alter_fk_user_id, references(:alter_fk_users, on_delete: :delete_all), from: references(:alter_fk_users, on_delete: :nothing)
139147
end
140148
end
141149

142150
def down do
151+
drop table(:alter_fk_comments)
143152
drop table(:alter_fk_posts)
144153
drop table(:alter_fk_users)
145154
end

lib/ecto/adapters/postgres/connection.ex

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,35 +1546,54 @@ if Code.ensure_loaded?(Postgrex) do
15461546
end
15471547

15481548
defp column_change(table, {:modify, name, %Reference{} = ref, opts}) do
1549-
[
1550-
drop_reference_expr(opts[:from], table, name),
1551-
"ADD ",
1552-
reference_expr(ref, table, name),
1553-
modify_null(name, opts),
1554-
modify_default(name, ref.type, opts)
1555-
]
1549+
reference_column_type = reference_column_type(ref.type, opts)
1550+
from_column_type = extract_column_type(opts[:from])
1551+
1552+
drop_reference_expr = drop_reference_expr(opts[:from], table, name)
1553+
prefix_with_comma = (drop_reference_expr != [] && ", ") || ""
1554+
1555+
if reference_column_type == column_type(from_column_type, opts) do
1556+
[
1557+
drop_reference_expr,
1558+
prefix_with_comma,
1559+
"ADD ",
1560+
reference_expr(ref, table, name),
1561+
modify_null(name, opts),
1562+
modify_default(name, ref.type, opts)
1563+
]
1564+
else
1565+
[
1566+
drop_reference_expr,
1567+
prefix_with_comma,
1568+
"ALTER COLUMN ",
1569+
quote_name(name),
1570+
" TYPE ",
1571+
reference_column_type,
1572+
", ADD ",
1573+
reference_expr(ref, table, name),
1574+
modify_null(name, opts),
1575+
modify_default(name, ref.type, opts)
1576+
]
1577+
end
15561578
end
15571579

15581580
defp column_change(table, {:modify, name, type, opts}) do
15591581
column_type = column_type(type, opts)
1582+
from_column_type = extract_column_type(opts[:from])
15601583

1561-
extract_type = fn
1562-
{type, _} when is_atom(type) -> type
1563-
type when is_atom(type) -> type
1564-
_ -> nil
1565-
end
1566-
1567-
from_type = extract_type.(opts[:from])
1584+
drop_reference_expr = drop_reference_expr(opts[:from], table, name)
1585+
prefix_with_comma? = drop_reference_expr != []
15681586

1569-
if column_type == column_type(from_type, opts) do
1587+
if column_type == column_type(from_column_type, opts) do
15701588
[
1571-
drop_reference_expr(opts[:from], table, name),
1572-
modify_null(name, Keyword.put(opts, :prefix_with_comma, false)),
1589+
drop_reference_expr,
1590+
modify_null(name, Keyword.put(opts, :prefix_with_comma, prefix_with_comma?)),
15731591
modify_default(name, type, opts)
15741592
]
15751593
else
15761594
[
1577-
drop_reference_expr(opts[:from], table, name),
1595+
drop_reference_expr,
1596+
(prefix_with_comma? && ", ") || "",
15781597
"ALTER COLUMN ",
15791598
quote_name(name),
15801599
" TYPE ",
@@ -1588,7 +1607,9 @@ if Code.ensure_loaded?(Postgrex) do
15881607
defp column_change(_table, {:remove, name}), do: ["DROP COLUMN ", quote_name(name)]
15891608

15901609
defp column_change(table, {:remove, name, %Reference{} = ref, _opts}) do
1591-
[drop_reference_expr(ref, table, name), "DROP COLUMN ", quote_name(name)]
1610+
drop_reference_expr = drop_reference_expr(ref, table, name)
1611+
prefix_with_comma = (drop_reference_expr != [] && ", ") || ""
1612+
[drop_reference_expr, prefix_with_comma, "DROP COLUMN ", quote_name(name)]
15921613
end
15931614

15941615
defp column_change(_table, {:remove, name, _type, _opts}),
@@ -1620,9 +1641,12 @@ if Code.ensure_loaded?(Postgrex) do
16201641
end
16211642

16221643
defp modify_default(name, type, opts) do
1644+
prefix_with_comma = Keyword.get(opts, :prefix_with_comma, true)
1645+
prefix = if prefix_with_comma, do: ", ", else: ""
1646+
16231647
case Keyword.fetch(opts, :default) do
16241648
{:ok, val} ->
1625-
[", ALTER COLUMN ", quote_name(name), " SET", default_expr({:ok, val}, type)]
1649+
[prefix, "ALTER COLUMN ", quote_name(name), " SET", default_expr({:ok, val}, type)]
16261650

16271651
:error ->
16281652
[]
@@ -1814,6 +1838,11 @@ if Code.ensure_loaded?(Postgrex) do
18141838
[type, generated_expr(generated)]
18151839
end
18161840

1841+
defp extract_column_type({type, _}) when is_atom(type), do: type
1842+
defp extract_column_type(type) when is_atom(type), do: type
1843+
defp extract_column_type(%Reference{type: type}), do: type
1844+
defp extract_column_type(_), do: nil
1845+
18171846
defp generated_expr(nil), do: []
18181847

18191848
defp generated_expr(expr) when is_binary(expr) do
@@ -1850,7 +1879,7 @@ if Code.ensure_loaded?(Postgrex) do
18501879
do: drop_reference_expr(ref, table, name)
18511880

18521881
defp drop_reference_expr(%Reference{} = ref, table, name),
1853-
do: ["DROP CONSTRAINT ", reference_name(ref, table, name), ", "]
1882+
do: ["DROP CONSTRAINT ", reference_name(ref, table, name)]
18541883

18551884
defp drop_reference_expr(_, _, _),
18561885
do: []

0 commit comments

Comments
 (0)