Skip to content

Commit 1083a9c

Browse files
authored
Merge pull request rails#51609 from ClearlyClaire/fixes/arel-select-union-wrapping
Arel: only wrap SELECT statements in UNION if they involve ORDER BY, LIMIT or OFFSET
2 parents 1e6938a + 96bc054 commit 1083a9c

File tree

3 files changed

+9
-9
lines changed

3 files changed

+9
-9
lines changed

activerecord/lib/arel/visitors/to_sql.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -965,21 +965,21 @@ def infix_value_with_paren(o, collector, value, suppress_parens = false)
965965
collector = if o.left.class == o.class
966966
infix_value_with_paren(o.left, collector, value, true)
967967
else
968-
grouping_parentheses o.left, collector
968+
grouping_parentheses o.left, collector, false
969969
end
970970
collector << value
971971
collector = if o.right.class == o.class
972972
infix_value_with_paren(o.right, collector, value, true)
973973
else
974-
grouping_parentheses o.right, collector
974+
grouping_parentheses o.right, collector, false
975975
end
976976
collector << " )" unless suppress_parens
977977
collector
978978
end
979979

980980
# Used by some visitors to enclose select queries in parentheses
981-
def grouping_parentheses(o, collector)
982-
if o.is_a?(Nodes::SelectStatement)
981+
def grouping_parentheses(o, collector, always_wrap_selects = true)
982+
if o.is_a?(Nodes::SelectStatement) && (always_wrap_selects || o.orders.present? || o.limit.present? || o.offset.present?)
983983
collector << "("
984984
visit o, collector
985985
collector << ")"

activerecord/test/cases/arel/attributes/attribute_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ class AttributeTest < Arel::Spec
963963
union = mgr1.union(mgr2)
964964
node = relation[:id].in(union)
965965
_(node.to_sql).must_be_like %{
966-
"users"."id" IN (( (SELECT "users"."id" FROM "users") UNION (SELECT "users"."id" FROM "users") ))
966+
"users"."id" IN (( SELECT "users"."id" FROM "users" UNION SELECT "users"."id" FROM "users" ))
967967
}
968968
end
969969

activerecord/test/cases/arel/select_manager_test.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,15 +253,15 @@ def test_join_sources
253253

254254
# maybe FIXME: decide when wrapper parens are needed
255255
_(node.to_sql).must_be_like %{
256-
( (SELECT * FROM "users" WHERE "users"."age" < 18) UNION (SELECT * FROM "users" WHERE "users"."age" > 99) )
256+
( SELECT * FROM "users" WHERE "users"."age" < 18 UNION SELECT * FROM "users" WHERE "users"."age" > 99 )
257257
}
258258
end
259259

260260
it "should union all" do
261261
node = @m1.union :all, @m2
262262

263263
_(node.to_sql).must_be_like %{
264-
( (SELECT * FROM "users" WHERE "users"."age" < 18) UNION ALL (SELECT * FROM "users" WHERE "users"."age" > 99) )
264+
( SELECT * FROM "users" WHERE "users"."age" < 18 UNION ALL SELECT * FROM "users" WHERE "users"."age" > 99 )
265265
}
266266
end
267267
end
@@ -354,9 +354,9 @@ def test_join_sources
354354
sql = manager.to_sql
355355
_(sql).must_be_like %{
356356
WITH RECURSIVE "replies" AS (
357-
(SELECT "comments"."id", "comments"."parent_id" FROM "comments" WHERE "comments"."id" = 42)
357+
SELECT "comments"."id", "comments"."parent_id" FROM "comments" WHERE "comments"."id" = 42
358358
UNION
359-
(SELECT "comments"."id", "comments"."parent_id" FROM "comments" INNER JOIN "replies" ON "comments"."parent_id" = "replies"."id")
359+
SELECT "comments"."id", "comments"."parent_id" FROM "comments" INNER JOIN "replies" ON "comments"."parent_id" = "replies"."id"
360360
)
361361
SELECT * FROM "replies"
362362
}

0 commit comments

Comments
 (0)