From fa73cf727521e9eb7911ada4d30ac10406446e7d Mon Sep 17 00:00:00 2001 From: Bogdan Gusiev Date: Wed, 21 Nov 2012 16:11:14 +0200 Subject: [PATCH] Fix postgresql adapter to handle bc timestamps correctly --- activerecord/CHANGELOG.md | 6 ++++++ .../connection_adapters/postgresql/cast.rb | 2 ++ .../connection_adapters/postgresql/quoting.rb | 10 +++++++--- .../test/cases/adapters/postgresql/timestamp_test.rb | 9 +++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 8e414d09d8..f166d73801 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 62d091357d..c04a799b8d 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 9d3fa18e3a..62a4d76928 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 26507ad654..630bdeec67 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) -- GitLab