diff options
author | yuuji.yaginuma <yuuji.yaginuma@gmail.com> | 2018-01-02 11:24:53 +0900 |
---|---|---|
committer | Yuji Yaginuma <yuuji.yaginuma@gmail.com> | 2018-01-04 06:44:53 +0900 |
commit | bce675eac49a8673d63ea41991f020aa3aa8c506 (patch) | |
tree | 9bd6b77f30370c90e45b379657699fe532b1bf04 | |
parent | ff4f69ff2d7c4880a04f5c963e0025af041b8e9d (diff) | |
download | rails-bce675eac49a8673d63ea41991f020aa3aa8c506.tar.gz rails-bce675eac49a8673d63ea41991f020aa3aa8c506.tar.bz2 rails-bce675eac49a8673d63ea41991f020aa3aa8c506.zip |
Correctly handle infinity value in PostgreSQL range type
An empty string is an invalid value in Ruby's range class.
So need to handle `Float::INFINITY` as it is and cast it in
`encode_range`.
Fixes #31612
3 files changed, 22 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/range.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/range.rb index a89aa5ea09..6edb7cfd3c 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/range.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/range.rb @@ -60,7 +60,7 @@ module ActiveRecord end def type_cast_single_for_database(value) - infinity?(value) ? "" : @subtype.serialize(value) + infinity?(value) ? value : @subtype.serialize(value) end def extract_bounds(value) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb index 9fdeab06c1..e75202b0be 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb @@ -138,7 +138,7 @@ module ActiveRecord end def encode_range(range) - "[#{type_cast(range.first)},#{type_cast(range.last)}#{range.exclude_end? ? ')' : ']'}" + "[#{type_cast_range_value(range.first)},#{type_cast_range_value(range.last)}#{range.exclude_end? ? ')' : ']'}" end def determine_encoding_of_strings_in_array(value) @@ -154,6 +154,14 @@ module ActiveRecord else _type_cast(values) end end + + def type_cast_range_value(value) + infinity?(value) ? "" : type_cast(value) + end + + def infinity?(value) + value.respond_to?(:infinite?) && value.infinite? + end end end end diff --git a/activerecord/test/cases/adapters/postgresql/range_test.rb b/activerecord/test/cases/adapters/postgresql/range_test.rb index 813a8721a2..261c24634e 100644 --- a/activerecord/test/cases/adapters/postgresql/range_test.rb +++ b/activerecord/test/cases/adapters/postgresql/range_test.rb @@ -358,6 +358,18 @@ _SQL end end + def test_infinity_values + PostgresqlRange.create!(int4_range: 1..Float::INFINITY, + int8_range: -Float::INFINITY..0, + float_range: -Float::INFINITY..Float::INFINITY) + + record = PostgresqlRange.first + + assert_equal(1...Float::INFINITY, record.int4_range) + assert_equal(-Float::INFINITY...1, record.int8_range) + assert_equal(-Float::INFINITY...Float::INFINITY, record.float_range) + end + private def assert_equal_round_trip(range, attribute, value) round_trip(range, attribute, value) |