@@ -143,31 +143,45 @@ def remove_column(table_name, column_name, type = nil, **options)
143143 def change_column ( table_name , column_name , type , options = { } )
144144 sql_commands = [ ]
145145 indexes = [ ]
146+
147+ if type == :datetime
148+ # If no precision then default it to 6.
149+ options [ :precision ] = 6 unless options . key? ( :precision )
150+
151+ # If there is precision then column must be of type 'datetime2'.
152+ type = :datetime2 unless options [ :precision ] . nil?
153+ end
154+
146155 column_object = schema_cache . columns ( table_name ) . find { |c | c . name . to_s == column_name . to_s }
147156 without_constraints = options . key? ( :default ) || options . key? ( :limit )
148157 default = if !options . key? ( :default ) && column_object
149158 column_object . default
150159 else
151160 options [ :default ]
152161 end
162+
153163 if without_constraints || ( column_object && column_object . type != type . to_sym )
154164 remove_default_constraint ( table_name , column_name )
155165 indexes = indexes ( table_name ) . select { |index | index . columns . include? ( column_name . to_s ) }
156166 remove_indexes ( table_name , column_name )
157167 end
168+
158169 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?
159170 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 ] ) } "
160171 alter_command += " COLLATE #{ options [ :collation ] } " if options [ :collation ] . present?
161172 alter_command += " NOT NULL" if !options [ :null ] . nil? && options [ :null ] == false
162173 sql_commands << alter_command
174+
163175 if without_constraints
164176 default = quote_default_expression ( default , column_object || column_for ( table_name , column_name ) )
165177 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 ) } "
166178 end
179+
167180 # Add any removed indexes back
168181 indexes . each do |index |
169182 sql_commands << "CREATE INDEX #{ quote_table_name ( index . name ) } ON #{ quote_table_name ( table_name ) } (#{ index . columns . map { |c | quote_column_name ( c ) } . join ( ', ' ) } )"
170183 end
184+
171185 sql_commands . each { |c | do_execute ( c ) }
172186 clear_cache!
173187 end
@@ -229,6 +243,7 @@ def extract_foreign_key_action(action, fk_name)
229243 def type_to_sql ( type , limit : nil , precision : nil , scale : nil , **)
230244 type_limitable = %w( string integer float char nchar varchar nvarchar ) . include? ( type . to_s )
231245 limit = nil unless type_limitable
246+
232247 case type . to_s
233248 when "integer"
234249 case limit
0 commit comments