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

Merge pull request #34437 from kbrock/union_all_paren

Fix: Arel now emits a single pair of parens for UNION and UNION ALL
This commit is contained in:
Rafael Mendonça França 2018-11-13 17:21:58 -05:00
commit 3dea7f0615
No known key found for this signature in database
GPG key ID: FC23B6D0F1EEE948
4 changed files with 41 additions and 42 deletions

View file

@ -4,34 +4,6 @@ module Arel # :nodoc: all
module Visitors
class MySQL < Arel::Visitors::ToSql
private
def visit_Arel_Nodes_Union(o, collector, suppress_parens = false)
unless suppress_parens
collector << "( "
end
case o.left
when Arel::Nodes::Union
visit_Arel_Nodes_Union o.left, collector, true
else
visit o.left, collector
end
collector << " UNION "
case o.right
when Arel::Nodes::Union
visit_Arel_Nodes_Union o.right, collector, true
else
visit o.right, collector
end
if suppress_parens
collector
else
collector << " )"
end
end
def visit_Arel_Nodes_Bin(o, collector)
collector << "BINARY "
visit o.expr, collector

View file

@ -268,13 +268,11 @@ module Arel # :nodoc: all
end
def visit_Arel_Nodes_Union(o, collector)
collector << "( "
infix_value(o, collector, " UNION ") << " )"
infix_value_with_paren(o, collector, " UNION ")
end
def visit_Arel_Nodes_UnionAll(o, collector)
collector << "( "
infix_value(o, collector, " UNION ALL ") << " )"
infix_value_with_paren(o, collector, " UNION ALL ")
end
def visit_Arel_Nodes_Intersect(o, collector)
@ -845,6 +843,23 @@ module Arel # :nodoc: all
visit o.right, collector
end
def infix_value_with_paren(o, collector, value, suppress_parens = false)
collector << "( " unless suppress_parens
collector = if o.left.class == o.class
infix_value_with_paren(o.left, collector, value, true)
else
visit o.left, collector
end
collector << value
collector = if o.right.class == o.class
infix_value_with_paren(o.right, collector, value, true)
else
visit o.right, collector
end
collector << " )" unless suppress_parens
collector
end
def aggregate(name, o, collector)
collector << "#{name}("
if o.distinct

View file

@ -13,16 +13,6 @@ module Arel
@visitor.accept(node, Collectors::SQLString.new).value
end
it "squashes parenthesis on multiple unions" do
subnode = Nodes::Union.new Arel.sql("left"), Arel.sql("right")
node = Nodes::Union.new subnode, Arel.sql("topright")
assert_equal 1, compile(node).scan("(").length
subnode = Nodes::Union.new Arel.sql("left"), Arel.sql("right")
node = Nodes::Union.new Arel.sql("topleft"), subnode
assert_equal 1, compile(node).scan("(").length
end
###
# :'(
# http://dev.mysql.com/doc/refman/5.0/en/select.html#id3482214

View file

@ -480,6 +480,28 @@ module Arel
end
end
describe "Nodes::Union" do
it "squashes parenthesis on multiple unions" do
subnode = Nodes::Union.new Arel.sql("left"), Arel.sql("right")
node = Nodes::Union.new subnode, Arel.sql("topright")
assert_equal("( left UNION right UNION topright )", compile(node))
subnode = Nodes::Union.new Arel.sql("left"), Arel.sql("right")
node = Nodes::Union.new Arel.sql("topleft"), subnode
assert_equal("( topleft UNION left UNION right )", compile(node))
end
end
describe "Nodes::UnionAll" do
it "squashes parenthesis on multiple union alls" do
subnode = Nodes::UnionAll.new Arel.sql("left"), Arel.sql("right")
node = Nodes::UnionAll.new subnode, Arel.sql("topright")
assert_equal("( left UNION ALL right UNION ALL topright )", compile(node))
subnode = Nodes::UnionAll.new Arel.sql("left"), Arel.sql("right")
node = Nodes::UnionAll.new Arel.sql("topleft"), subnode
assert_equal("( topleft UNION ALL left UNION ALL right )", compile(node))
end
end
describe "Nodes::NotIn" do
it "should know how to visit" do
node = @attr.not_in [1, 2, 3]