From 532219fd091837a9312a301c74e0fbf06abab3a8 Mon Sep 17 00:00:00 2001 From: Giles Alexander Date: Sat, 30 May 2009 17:44:50 +1000 Subject: [PATCH] Schema dumper now records scale 0 decimal columns as decimal not integer. The schema dumper would dump out any decimal or numeric column that had a zero scale as an integer column. This will cause problems for very large precision columns on some DBMSs, particularly PostgreSQL. It also looks strange to see your column change type after moving through schema.rb. Signed-off-by: Michael Koziarski [#2741 state:committed] --- activerecord/lib/active_record/schema_dumper.rb | 11 +++++++++-- activerecord/test/cases/schema_dumper_test.rb | 5 +++++ activerecord/test/schema/schema.rb | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb index de530a345663e..2d90ef35aaad0 100644 --- a/activerecord/lib/active_record/schema_dumper.rb +++ b/activerecord/lib/active_record/schema_dumper.rb @@ -99,8 +99,15 @@ def table(table, stream) next if column.name == pk spec = {} spec[:name] = column.name.inspect - spec[:type] = column.type.to_s - spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && column.type != :decimal + + # AR has an optimisation which handles zero-scale decimals as integers. This + # code ensures that the dumper still dumps the column as a decimal. + spec[:type] = if column.type == :integer && [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) } + 'decimal' + else + column.type.to_s + end + spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && spec[:type] != 'decimal' spec[:precision] = column.precision.inspect if !column.precision.nil? spec[:scale] = column.scale.inspect if !column.scale.nil? spec[:null] = 'false' if !column.null diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index f9ad7f3ba3c7f..4f02be3c06e30 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -190,4 +190,9 @@ def test_schema_dump_includes_decimal_options output = stream.string assert_match %r{:precision => 3,[[:space:]]+:scale => 2,[[:space:]]+:default => 2.78}, output end + + def test_schema_dump_keeps_large_precision_integer_columns_as_decimal + output = standard_dump + assert_match %r{t.decimal\s+"atoms_in_universe",\s+:precision => 55,\s+:scale => 0}, output + end end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 6e8813d8ab9ba..b2aaccb35206b 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -273,6 +273,7 @@ def create_table(*args, &block) t.decimal :my_house_population, :precision => 2, :scale => 0 t.decimal :decimal_number_with_default, :precision => 3, :scale => 2, :default => 2.78 t.float :temperature + t.decimal :atoms_in_universe, :precision => 55, :scale => 0 end create_table :orders, :force => true do |t|