@@ -1546,35 +1546,76 @@ 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- "ALTER COLUMN " ,
1552- quote_name ( name ) ,
1553- " TYPE " ,
1554- reference_column_type ( ref . type , opts ) ,
1555- ", ADD " ,
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+ common_suffix = [
15561556 reference_expr ( ref , table , name ) ,
15571557 modify_null ( name , opts ) ,
15581558 modify_default ( name , ref . type , opts )
15591559 ]
1560+
1561+ if reference_column_type == reference_column_type ( from_column_type , opts ) do
1562+ [
1563+ drop_reference_expr ,
1564+ prefix_with_comma ,
1565+ "ADD " | common_suffix
1566+ ]
1567+ else
1568+ [
1569+ drop_reference_expr ,
1570+ prefix_with_comma ,
1571+ "ALTER COLUMN " ,
1572+ quote_name ( name ) ,
1573+ " TYPE " ,
1574+ reference_column_type ,
1575+ ", ADD " | common_suffix
1576+ ]
1577+ end
15601578 end
15611579
15621580 defp column_change ( table , { :modify , name , type , opts } ) do
1563- [
1564- drop_reference_expr ( opts [ :from ] , table , name ) ,
1565- "ALTER COLUMN " ,
1566- quote_name ( name ) ,
1567- " TYPE " ,
1568- column_type ( type , opts ) ,
1569- modify_null ( name , opts ) ,
1570- modify_default ( name , type , opts )
1571- ]
1581+ column_type = column_type ( type , opts )
1582+ from_column_type = extract_column_type ( opts [ :from ] )
1583+
1584+ drop_reference_expr = drop_reference_expr ( opts [ :from ] , table , name )
1585+ any_drop_ref? = drop_reference_expr != [ ]
1586+
1587+ if column_type == column_type ( from_column_type , opts ) do
1588+ modify_null = modify_null ( name , Keyword . put ( opts , :prefix_with_comma , any_drop_ref? ) )
1589+ any_modify_null? = modify_null != [ ]
1590+
1591+ modify_default =
1592+ modify_default (
1593+ name ,
1594+ type ,
1595+ Keyword . put ( opts , :prefix_with_comma , any_drop_ref? or any_modify_null? )
1596+ )
1597+
1598+ [ drop_reference_expr , modify_null , modify_default ]
1599+ else
1600+ [
1601+ drop_reference_expr ,
1602+ ( any_drop_ref? && ", " ) || "" ,
1603+ "ALTER COLUMN " ,
1604+ quote_name ( name ) ,
1605+ " TYPE " ,
1606+ column_type ,
1607+ modify_null ( name , opts ) ,
1608+ modify_default ( name , type , opts )
1609+ ]
1610+ end
15721611 end
15731612
15741613 defp column_change ( _table , { :remove , name } ) , do: [ "DROP COLUMN " , quote_name ( name ) ]
15751614
15761615 defp column_change ( table , { :remove , name , % Reference { } = ref , _opts } ) do
1577- [ drop_reference_expr ( ref , table , name ) , "DROP COLUMN " , quote_name ( name ) ]
1616+ drop_reference_expr = drop_reference_expr ( ref , table , name )
1617+ prefix_with_comma = ( drop_reference_expr != [ ] && ", " ) || ""
1618+ [ drop_reference_expr , prefix_with_comma , "DROP COLUMN " , quote_name ( name ) ]
15781619 end
15791620
15801621 defp column_change ( _table , { :remove , name , _type , _opts } ) ,
@@ -1595,17 +1636,23 @@ if Code.ensure_loaded?(Postgrex) do
15951636 do: [ "DROP COLUMN IF EXISTS " , quote_name ( name ) ]
15961637
15971638 defp modify_null ( name , opts ) do
1639+ prefix_with_comma = Keyword . get ( opts , :prefix_with_comma , true )
1640+ prefix = if prefix_with_comma , do: ", " , else: ""
1641+
15981642 case Keyword . get ( opts , :null ) do
1599- true -> [ ", ALTER COLUMN ", quote_name ( name ) , " DROP NOT NULL" ]
1600- false -> [ ", ALTER COLUMN ", quote_name ( name ) , " SET NOT NULL" ]
1643+ true -> [ prefix , " ALTER COLUMN ", quote_name ( name ) , " DROP NOT NULL" ]
1644+ false -> [ prefix , " ALTER COLUMN ", quote_name ( name ) , " SET NOT NULL" ]
16011645 nil -> [ ]
16021646 end
16031647 end
16041648
16051649 defp modify_default ( name , type , opts ) do
1650+ prefix_with_comma = Keyword . get ( opts , :prefix_with_comma , true )
1651+ prefix = if prefix_with_comma , do: ", " , else: ""
1652+
16061653 case Keyword . fetch ( opts , :default ) do
16071654 { :ok , val } ->
1608- [ ", ALTER COLUMN ", quote_name ( name ) , " SET" , default_expr ( { :ok , val } , type ) ]
1655+ [ prefix , " ALTER COLUMN ", quote_name ( name ) , " SET" , default_expr ( { :ok , val } , type ) ]
16091656
16101657 :error ->
16111658 [ ]
@@ -1797,6 +1844,11 @@ if Code.ensure_loaded?(Postgrex) do
17971844 [ type , generated_expr ( generated ) ]
17981845 end
17991846
1847+ defp extract_column_type ( { type , _ } ) when is_atom ( type ) , do: type
1848+ defp extract_column_type ( type ) when is_atom ( type ) , do: type
1849+ defp extract_column_type ( % Reference { type: type } ) , do: type
1850+ defp extract_column_type ( _ ) , do: nil
1851+
18001852 defp generated_expr ( nil ) , do: [ ]
18011853
18021854 defp generated_expr ( expr ) when is_binary ( expr ) do
@@ -1833,7 +1885,7 @@ if Code.ensure_loaded?(Postgrex) do
18331885 do: drop_reference_expr ( ref , table , name )
18341886
18351887 defp drop_reference_expr ( % Reference { } = ref , table , name ) ,
1836- do: [ "DROP CONSTRAINT " , reference_name ( ref , table , name ) , ", " ]
1888+ do: [ "DROP CONSTRAINT " , reference_name ( ref , table , name ) ]
18371889
18381890 defp drop_reference_expr ( _ , _ , _ ) ,
18391891 do: [ ]
0 commit comments