aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG.md15
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid.rb11
-rw-r--r--activerecord/test/cases/adapters/postgresql/datatype_test.rb7
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 @@ This is not reliable and will be removed in the future.
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 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase
@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 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase
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