From aac40bcc07b3defb2134b2c08a88e197c469a702 Mon Sep 17 00:00:00 2001 From: Innokenty Mihailov Date: Wed, 18 Dec 2013 23:12:53 +0200 Subject: [PATCH] pg, fix Infinity and NaN values conversion. Before this patch `Infinity`, `-Infinity` and `Nan` were read as `0`. --- activerecord/CHANGELOG.md | 15 +++++++++++++++ .../connection_adapters/postgresql/oid.rb | 11 ++++++++--- .../cases/adapters/postgresql/datatype_test.rb | 7 +++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 99f9f9d094..f44549ca45 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,18 @@ +* Fix `PostgreSQLAdapter::OID::Float#type_cast` to convert Infinity and + NaN PostgreSQL values into a native Ruby `Float::INFINITY` and `Float::NAN` + + Example: + + # Before + Point.create(value: 1.0/0) + Point.last.value # => 0.0 + + # After + Point.create(value: 1.0/0) + Point.last.value # => Infinity + + *Innokenty Mikhailov* + * Allow the PostgreSQL adapter to handle bigserial pk types again. Fixes #10410. diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb index 540b3694b5..14beb7bd25 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb @@ -249,9 +249,14 @@ class Float < Type def type; :float end def type_cast(value) - return if value.nil? - - value.to_f + case value + when nil; nil + when 'Infinity'; ::Float::INFINITY + when '-Infinity'; -::Float::INFINITY + when 'NaN'; ::Float::NAN + else + value.to_f + end end end diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb index e7dda1a1af..331481cb10 100644 --- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb +++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb @@ -50,7 +50,11 @@ def setup @second_money = PostgresqlMoney.find(2) @connection.execute("INSERT INTO postgresql_numbers (id, single, double) VALUES (1, 123.456, 123456.789)") + @connection.execute("INSERT INTO postgresql_numbers (id, single, double) VALUES (2, '-Infinity', 'Infinity')") + @connection.execute("INSERT INTO postgresql_numbers (id, single, double) VALUES (3, 123.456, 'NaN')") @first_number = PostgresqlNumber.find(1) + @second_number = PostgresqlNumber.find(2) + @third_number = PostgresqlNumber.find(3) @connection.execute("INSERT INTO postgresql_times (id, time_interval, scaled_time_interval) VALUES (1, '1 year 2 days ago', '3 weeks ago')") @first_time = PostgresqlTime.find(1) @@ -154,6 +158,9 @@ def test_update_tsvector def test_number_values assert_equal 123.456, @first_number.single assert_equal 123456.789, @first_number.double + assert_equal -::Float::INFINITY, @second_number.single + assert_equal ::Float::INFINITY, @second_number.double + assert_same ::Float::NAN, @third_number.double end def test_time_values