@@ -146,31 +146,45 @@ def remove_column(table_name, column_name, type = nil, **options)
146146 def change_column ( table_name , column_name , type , options = { } )
147147 sql_commands = [ ]
148148 indexes = [ ]
149+
150+ if type == :datetime
151+ # If no precision then default it to 6.
152+ options [ :precision ] = 6 unless options . key? ( :precision )
153+
154+ # If there is precision then column must be of type 'datetime2'.
155+ type = :datetime2 unless options [ :precision ] . nil?
156+ end
157+
149158 column_object = schema_cache . columns ( table_name ) . find { |c | c . name . to_s == column_name . to_s }
150159 without_constraints = options . key? ( :default ) || options . key? ( :limit )
151160 default = if !options . key? ( :default ) && column_object
152161 column_object . default
153162 else
154163 options [ :default ]
155164 end
165+
156166 if without_constraints || ( column_object && column_object . type != type . to_sym )
157167 remove_default_constraint ( table_name , column_name )
158168 indexes = indexes ( table_name ) . select { |index | index . columns . include? ( column_name . to_s ) }
159169 remove_indexes ( table_name , column_name )
160170 end
171+
161172 sql_commands << "UPDATE #{ quote_table_name ( table_name ) } SET #{ quote_column_name ( column_name ) } =#{ quote_default_expression ( options [ :default ] , column_object ) } WHERE #{ quote_column_name ( column_name ) } IS NULL" if !options [ :null ] . nil? && options [ :null ] == false && !options [ :default ] . nil?
162173 alter_command = "ALTER TABLE #{ quote_table_name ( table_name ) } ALTER COLUMN #{ quote_column_name ( column_name ) } #{ type_to_sql ( type , limit : options [ :limit ] , precision : options [ :precision ] , scale : options [ :scale ] ) } "
163174 alter_command += " COLLATE #{ options [ :collation ] } " if options [ :collation ] . present?
164175 alter_command += " NOT NULL" if !options [ :null ] . nil? && options [ :null ] == false
165176 sql_commands << alter_command
177+
166178 if without_constraints
167179 default = quote_default_expression ( default , column_object || column_for ( table_name , column_name ) )
168180 sql_commands << "ALTER TABLE #{ quote_table_name ( table_name ) } ADD CONSTRAINT #{ default_constraint_name ( table_name , column_name ) } DEFAULT #{ default } FOR #{ quote_column_name ( column_name ) } "
169181 end
182+
170183 # Add any removed indexes back
171184 indexes . each do |index |
172185 sql_commands << "CREATE INDEX #{ quote_table_name ( index . name ) } ON #{ quote_table_name ( table_name ) } (#{ index . columns . map { |c | quote_column_name ( c ) } . join ( ', ' ) } )"
173186 end
187+
174188 sql_commands . each { |c | execute ( c ) }
175189 clear_cache!
176190 end
@@ -232,6 +246,7 @@ def extract_foreign_key_action(action, fk_name)
232246 def type_to_sql ( type , limit : nil , precision : nil , scale : nil , **)
233247 type_limitable = %w( string integer float char nchar varchar nvarchar ) . include? ( type . to_s )
234248 limit = nil unless type_limitable
249+
235250 case type . to_s
236251 when "integer"
237252 case limit
0 commit comments