From 7f856c3c8db71e2600d6a84bbc6510eb4ddd0418 Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Thu, 3 Jan 2019 09:46:42 +0900
Subject: Consolidate the duplicated code that building range predicate

This slightly change the code in the Arel to allow +/-INFINITY as open
ended since the Active Record expects that behavior. See 5ecbeda.
---
 .../relation/predicate_builder/range_handler.rb    | 23 ++--------------------
 .../lib/active_record/relation/query_attribute.rb  |  6 +++---
 activerecord/lib/arel/nodes/bind_param.rb          |  4 ++++
 activerecord/lib/arel/nodes/casted.rb              |  4 ++++
 activerecord/lib/arel/predications.rb              | 20 ++++++++-----------
 5 files changed, 21 insertions(+), 36 deletions(-)

(limited to 'activerecord/lib')

diff --git a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
index 44bb2c7ab6..2ea27c8490 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
@@ -3,11 +3,7 @@
 module ActiveRecord
   class PredicateBuilder
     class RangeHandler # :nodoc:
-      class RangeWithBinds < Struct.new(:begin, :end)
-        def exclude_end?
-          false
-        end
-      end
+      RangeWithBinds = Struct.new(:begin, :end, :exclude_end?)
 
       def initialize(predicate_builder)
         @predicate_builder = predicate_builder
@@ -16,22 +12,7 @@ module ActiveRecord
       def call(attribute, value)
         begin_bind = predicate_builder.build_bind_attribute(attribute.name, value.begin)
         end_bind = predicate_builder.build_bind_attribute(attribute.name, value.end)
-
-        if begin_bind.value.infinity?
-          if end_bind.value.infinity?
-            attribute.not_in([])
-          elsif value.exclude_end?
-            attribute.lt(end_bind)
-          else
-            attribute.lteq(end_bind)
-          end
-        elsif end_bind.value.infinity?
-          attribute.gteq(begin_bind)
-        elsif value.exclude_end?
-          attribute.gteq(begin_bind).and(attribute.lt(end_bind))
-        else
-          attribute.between(RangeWithBinds.new(begin_bind, end_bind))
-        end
+        attribute.between(RangeWithBinds.new(begin_bind, end_bind, value.exclude_end?))
       end
 
       private
diff --git a/activerecord/lib/active_record/relation/query_attribute.rb b/activerecord/lib/active_record/relation/query_attribute.rb
index f64bd30d38..b45326bdda 100644
--- a/activerecord/lib/active_record/relation/query_attribute.rb
+++ b/activerecord/lib/active_record/relation/query_attribute.rb
@@ -30,12 +30,12 @@ module ActiveRecord
         @_boundable = false
       end
 
-      def infinity?
-        _infinity?(value_before_type_cast) || boundable? && _infinity?(value_for_database)
+      def infinite?
+        infinity?(value_before_type_cast) || boundable? && infinity?(value_for_database)
       end
 
       private
-        def _infinity?(value)
+        def infinity?(value)
           value.respond_to?(:infinite?) && value.infinite?
         end
     end
diff --git a/activerecord/lib/arel/nodes/bind_param.rb b/activerecord/lib/arel/nodes/bind_param.rb
index ba8340558a..f145e44ae3 100644
--- a/activerecord/lib/arel/nodes/bind_param.rb
+++ b/activerecord/lib/arel/nodes/bind_param.rb
@@ -24,6 +24,10 @@ module Arel # :nodoc: all
         value.nil?
       end
 
+      def infinite?
+        value.respond_to?(:infinite?) && value.infinite?
+      end
+
       def boundable?
         !value.respond_to?(:boundable?) || value.boundable?
       end
diff --git a/activerecord/lib/arel/nodes/casted.rb b/activerecord/lib/arel/nodes/casted.rb
index c1e6e97d6d..6e911b717d 100644
--- a/activerecord/lib/arel/nodes/casted.rb
+++ b/activerecord/lib/arel/nodes/casted.rb
@@ -27,6 +27,10 @@ module Arel # :nodoc: all
     class Quoted < Arel::Nodes::Unary # :nodoc:
       alias :val :value
       def nil?; val.nil?; end
+
+      def infinite?
+        value.respond_to?(:infinite?) && value.infinite?
+      end
     end
 
     def self.build_quoted(other, attribute = nil)
diff --git a/activerecord/lib/arel/predications.rb b/activerecord/lib/arel/predications.rb
index 77502dd199..28679ae892 100644
--- a/activerecord/lib/arel/predications.rb
+++ b/activerecord/lib/arel/predications.rb
@@ -35,15 +35,15 @@ module Arel # :nodoc: all
     end
 
     def between(other)
-      if equals_quoted?(other.begin, -Float::INFINITY)
-        if equals_quoted?(other.end, Float::INFINITY)
+      if infinity?(other.begin)
+        if infinity?(other.end)
           not_in([])
         elsif other.exclude_end?
           lt(other.end)
         else
           lteq(other.end)
         end
-      elsif equals_quoted?(other.end, Float::INFINITY)
+      elsif infinity?(other.end)
         gteq(other.begin)
       elsif other.exclude_end?
         gteq(other.begin).and(lt(other.end))
@@ -81,15 +81,15 @@ Passing a range to `#in` is deprecated. Call `#between`, instead.
     end
 
     def not_between(other)
-      if equals_quoted?(other.begin, -Float::INFINITY)
-        if equals_quoted?(other.end, Float::INFINITY)
+      if infinity?(other.begin)
+        if infinity?(other.end)
           self.in([])
         elsif other.exclude_end?
           gteq(other.end)
         else
           gt(other.end)
         end
-      elsif equals_quoted?(other.end, Float::INFINITY)
+      elsif infinity?(other.end)
         lt(other.begin)
       else
         left = lt(other.begin)
@@ -238,12 +238,8 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
         others.map { |v| quoted_node(v) }
       end
 
-      def equals_quoted?(maybe_quoted, value)
-        if maybe_quoted.is_a?(Nodes::Quoted)
-          maybe_quoted.val == value
-        else
-          maybe_quoted == value
-        end
+      def infinity?(value)
+        value.respond_to?(:infinite?) && value.infinite?
       end
   end
 end
-- 
cgit v1.2.3