Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle BigDecimal Ranges #190

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 22 additions & 6 deletions lib/arel/predications.rb
Expand Up @@ -29,15 +29,15 @@ def in other
when Arel::SelectManager
Arel::Nodes::In.new(self, other.ast)
when Range
if other.begin == -Float::INFINITY
if other.end == Float::INFINITY
if negative_infinite?(other.begin)
if positive_infinite?(other.end)
Nodes::NotIn.new self, []
elsif other.exclude_end?
Nodes::LessThan.new(self, Nodes.build_quoted(other.end, self))
else
Nodes::LessThanOrEqual.new(self, Nodes.build_quoted(other.end, self))
end
elsif other.end == Float::INFINITY
elsif positive_infinite?(other.end)
Nodes::GreaterThanOrEqual.new(self, Nodes.build_quoted(other.begin, self))
elsif other.exclude_end?
left = Nodes::GreaterThanOrEqual.new(self, Nodes.build_quoted(other.begin, self))
Expand Down Expand Up @@ -66,15 +66,15 @@ def not_in other
when Arel::SelectManager
Arel::Nodes::NotIn.new(self, other.ast)
when Range
if other.begin == -Float::INFINITY # The range begins with negative infinity
if other.end == Float::INFINITY
if negative_infinite?(other.begin) # The range begins with negative infinity
if positive_infinite?(other.end)
Nodes::In.new self, [] # The range is infinite, so return an empty range
elsif other.exclude_end?
Nodes::GreaterThanOrEqual.new(self, Nodes.build_quoted(other.end, self))
else
Nodes::GreaterThan.new(self, Nodes.build_quoted(other.end, self))
end
elsif other.end == Float::INFINITY
elsif positive_infinite?(other.end)
Nodes::LessThan.new(self, Nodes.build_quoted(other.begin, self))
else
left = Nodes::LessThan.new(self, Nodes.build_quoted(other.begin, self))
Expand Down Expand Up @@ -185,5 +185,21 @@ def grouping_all method_id, others, *extras
nodes = others.map {|expr| send(method_id, expr, *extras)}
Nodes::Grouping.new Nodes::And.new(nodes)
end

def positive_infinite? value
if value.respond_to? :infinite?
value.infinite? == 1
else
value == Float::INFINITY
end
end

def negative_infinite? value
if value.respond_to? :infinite?
value.infinite? == -1
else
value == -Float::INFINITY
end
end
end
end
23 changes: 23 additions & 0 deletions test/visitors/test_to_sql.rb
Expand Up @@ -405,6 +405,29 @@ def dispatch
compile(node).must_be_like %{1=1}
end

it 'can handle BigDecimal ranges bounded by infinity' do
node = @attr.in BigDecimal.new(1)..BigDecimal.new('Infinity')
compile(node).must_be_like %{
"users"."id" >= 1
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not taking care of

node = @attr.in BigDecimal.new(1)...BigDecimal.new('Infinity')
          compile(node).must_be_like %{
            "users"."id" > 1
          }

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generated SQL would still be the same though wouldn't it? In your example you've changed >= to just >, but shouldn't the generated SQL still be >=? If so, I'll just add the test and re-push.

node = @attr.in BigDecimal.new(1)...BigDecimal.new('Infinity')
compile(node).must_be_like %{
"users"."id" >= 1
}
node = @attr.in BigDecimal.new('-Infinity')..BigDecimal.new(3)
compile(node).must_be_like %{
"users"."id" <= 3
}
node = @attr.in BigDecimal.new('-Infinity')...BigDecimal.new(3)
compile(node).must_be_like %{
"users"."id" < 3
}
node = @attr.in BigDecimal.new('-Infinity')..BigDecimal.new('Infinity')
compile(node).must_be_like %{1=1}
node = @attr.in BigDecimal.new('-Infinity')...BigDecimal.new('Infinity')
compile(node).must_be_like %{1=1}
end

it 'can handle subqueries' do
table = Table.new(:users)
subquery = table.project(:id).where(table[:name].eq('Aaron'))
Expand Down