1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Allow for handling quoted values in ranges

Since Active Record needs to eagerly cast values, we need to check for
quoted infinity in our range handling
This commit is contained in:
Sean Griffin 2014-12-26 15:45:34 -07:00
parent bf7c7558b5
commit cf03bd45e3
2 changed files with 61 additions and 6 deletions

View file

@ -25,15 +25,15 @@ module Arel
end
def between other
if other.begin == -Float::INFINITY
if other.end == Float::INFINITY
if equals_quoted?(other.begin, -Float::INFINITY)
if equals_quoted?(other.end, Float::INFINITY)
not_in([])
elsif other.exclude_end?
lt(other.end)
else
lteq(other.end)
end
elsif other.end == Float::INFINITY
elsif equals_quoted?(other.end, Float::INFINITY)
gteq(other.begin)
elsif other.exclude_end?
gteq(other.begin).and(lt(other.end))
@ -71,15 +71,15 @@ Passing a range to `#in` is deprecated. Call `#between`, instead.
end
def not_between other
if other.begin == -Float::INFINITY # The range begins with negative infinity
if other.end == Float::INFINITY
if equals_quoted?(other.begin, -Float::INFINITY)
if equals_quoted?(other.end, Float::INFINITY)
self.in([])
elsif other.exclude_end?
gteq(other.end)
else
gt(other.end)
end
elsif other.end == Float::INFINITY
elsif equals_quoted?(other.end, Float::INFINITY)
lt(other.begin)
else
left = lt(other.begin)
@ -211,5 +211,13 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
def quoted_array(others)
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
end
end
end

View file

@ -1,4 +1,5 @@
require 'helper'
require 'ostruct'
module Arel
module Attributes
@ -572,6 +573,16 @@ module Arel
)
end
it 'can be constructed with a quoted range starting from -Infinity' do
attribute = Attribute.new nil, nil
node = attribute.between(quoted_range(-::Float::INFINITY, 3, false))
node.must_equal Nodes::LessThanOrEqual.new(
attribute,
Nodes::Quoted.new(3)
)
end
it 'can be constructed with an exclusive range starting from -Infinity' do
attribute = Attribute.new nil, nil
node = attribute.between(-::Float::INFINITY...3)
@ -582,6 +593,16 @@ module Arel
)
end
it 'can be constructed with a quoted exclusive range starting from -Infinity' do
attribute = Attribute.new nil, nil
node = attribute.between(quoted_range(-::Float::INFINITY, 3, true))
node.must_equal Nodes::LessThan.new(
attribute,
Nodes::Quoted.new(3)
)
end
it 'can be constructed with an infinite range' do
attribute = Attribute.new nil, nil
node = attribute.between(-::Float::INFINITY..::Float::INFINITY)
@ -589,6 +610,14 @@ module Arel
node.must_equal Nodes::NotIn.new(attribute, [])
end
it 'can be constructed with a quoted infinite range' do
attribute = Attribute.new nil, nil
node = attribute.between(quoted_range(-::Float::INFINITY, ::Float::INFINITY, false))
node.must_equal Nodes::NotIn.new(attribute, [])
end
it 'can be constructed with a range ending at Infinity' do
attribute = Attribute.new nil, nil
node = attribute.between(0..::Float::INFINITY)
@ -599,6 +628,16 @@ module Arel
)
end
it 'can be constructed with a quoted range ending at Infinity' do
attribute = Attribute.new nil, nil
node = attribute.between(quoted_range(0, ::Float::INFINITY, false))
node.must_equal Nodes::GreaterThanOrEqual.new(
attribute,
Nodes::Quoted.new(0)
)
end
it 'can be constructed with an exclusive range' do
attribute = Attribute.new nil, nil
node = attribute.between(0...3)
@ -614,6 +653,14 @@ module Arel
)
])
end
def quoted_range(begin_val, end_val, exclude)
OpenStruct.new(
begin: Nodes::Quoted.new(begin_val),
end: Nodes::Quoted.new(end_val),
exclude_end?: exclude,
)
end
end
describe '#in' do