AR should handle timestamp values of 'Infinity' #544

Closed
byrnejb opened this Issue May 13, 2011 · 2 comments

2 participants

@byrnejb

Ruby 1.8.7 and 1.9.2 understand the concept of 'infinity'.

$ irb
ruby-1.8.7-p334 :001 > infinity = 1.0/0
=> Infinity
ruby-1.8.7-p334 :002 > ninfinity = -1.0/0
=> -Infinity
ruby-1.8.7-p334 :003 >

Further, ActiveRecord::Migration, perhaps inadvertently, supports the concept of infinity as recognized by the PostgreSQL pg adapter:

def self.up
create_table :ca_customs_shipments do |t|
t.datetime :expected_at,
:default => 'infinity',
:null => false

Results in:

-- Column: expected_at

-- ALTER TABLE ca_customs_shipments DROP COLUMN expected_at;

ALTER TABLE ca_customs_shipments ADD COLUMN expected_at timestamp without time zone;
ALTER TABLE ca_customs_shipments ALTER COLUMN expected_at SET STORAGE PLAIN;
ALTER TABLE ca_customs_shipments ALTER COLUMN expected_at SET NOT NULL;
ALTER TABLE ca_customs_shipments ALTER COLUMN expected_at SET DEFAULT 'infinity'::timestamp without time zone;

However, when obtaining default values from its PostgreSQL adapter, postgresql.rb, AR evidently treats 'infinity' as nil. This appears to be a defect caused by the Ruby implementation of the Date class.

The coercion of Infinity to a date raises the following exceptions:

ruby-1.8.7-p334 :016 > x = 1.0/0
=> Infinity
ruby-1.8.7-p334 :017 > x.to_date
NoMethodError: undefined method to_date' for Infinity:Float
from (irb):17
ruby-1.8.7-p334 :018 > y = -1.0/0
=> -Infinity
ruby-1.8.7-p334 :019 > y.to_date
NoMethodError: undefined method
to_date' for -Infinity:Float
from (irb):19

Since these are distinctively related to infinity values it seems reasonable that one could trap them and override the exception by assigning 1.0/0 and -1.0/0 to the receiver instead. The effect of this is consistent with current behaviour inside Rails

ruby-1.8.7-p334 :003 > x = "19920101000000".to_date
=> Wed, 01 Jan 1992
ruby-1.8.7-p334 :004 > x.class
=> Date
ruby-1.8.7-p334 :005 > x < 1
=> false
ruby-1.8.7-p334 :006 > x < 1.0/0
=> true
ruby-1.8.7-p334 :007 > x < -1.0/0
=> false

Infinity and -Infinity are acceptable values for timestamp columns in current versions of PostgreSQl. Evidence suggests that the pg gem handles this. It seems that the ORM of Rails also should support this in some fashion.

@tenderlove tenderlove was assigned May 13, 2011
@byrnejb

Apparently Date understands infinity in some sense as well:

ruby-1.9.2-p0 :014 > require "date"
=> true
ruby-1.9.2-p0 :015 > x = Date::Infinity.new
=> #
ruby-1.9.2-p0 :016 > x.class
=> Date::Infinity

@tenderlove
Ruby on Rails member

It looks like Date::Infinity just tries to mimic Infinity, and it's nodoc'ed in trunk. I think just accepting and returning a regular Infinity would be appropriate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment