diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 8e414d09d807b7be4d94280eebb9f6c16102cb08..f166d738014c7fb70b77b9ba35ef0b087754d314 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,11 @@ ## Rails 4.0.0 (unreleased) ## +* Fix postgresql adapter to handle BC timestamps correctly + + HistoryEvent.create!(:name => "something", :occured_at => Date.new(0) - 5.years) + + *Bogdan Gusiev* + * When running migrations on Postgresql, the `:limit` option for `binary` and `text` columns is silently dropped. Previously, these migrations caused sql exceptions, because Postgresql doesn't support limits on these types. diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb index 62d091357da1eceed7637306ff42b4add33920ef..c04a799b8d9852b3a766bce5d4d506caba852277 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb @@ -8,6 +8,8 @@ def string_to_time(string) case string when 'infinity'; 1.0 / 0.0 when '-infinity'; -1.0 / 0.0 + when / BC$/ + super("-" + string.sub(/ BC$/, "")) else super end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb index 9d3fa18e3aec6aab23c8e0e9e9e0ffd1a30f7513..62a4d769288256e8013fe98762287a9af2584e03 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb @@ -129,11 +129,15 @@ def quote_column_name(name) #:nodoc: # Quote date/time values for use in SQL input. Includes microseconds # if the value is a Time responding to usec. def quoted_date(value) #:nodoc: + result = super if value.acts_like?(:time) && value.respond_to?(:usec) - "#{super}.#{sprintf("%06d", value.usec)}" - else - super + result = "#{result}.#{sprintf("%06d", value.usec)}" + end + + if value.year < 0 + result = result.sub(/^-/, "") + " BC" end + result end end end diff --git a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb index 26507ad654d9659f88b7cac1e6d3a4f367edb421..630bdeec67f7689d1216cef54890008769ca16ec 100644 --- a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb +++ b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb @@ -75,6 +75,15 @@ def test_postgres_agrees_with_activerecord_about_precision assert_equal '4', pg_datetime_precision('foos', 'updated_at') end + def test_bc_timestamp + unless current_adapter?(:PostgreSQLAdapter) + return skip("only tested on postgresql") + end + date = Date.new(0) - 1.second + Developer.create!(:name => "aaron", :updated_at => date) + assert_equal date, Developer.find_by_name("aaron").updated_at + end + private def pg_datetime_precision(table_name, column_name)