Skip to content

Commit 58ec493

Browse files
committed
Recognize update_manager behavior differs for mysql
1 parent 6266086 commit 58ec493

File tree

1 file changed

+43
-10
lines changed

1 file changed

+43
-10
lines changed

spec/model_update_arel_10_spec.rb

+43-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
# by build_arel. It returns an Arel::UpdateManager. This makes sure that internal call
55
# assembles the update query correctly.
66

7+
# For three of the four tests in this file, we special-case MySQL to check for the
8+
# different query it produces. The reason MySQL is handled differently is described
9+
# in Arel 10 here:
10+
# https://github.com/rails/rails/blob/v7.1.2/activerecord/lib/arel/visitors/to_sql.rb#L924-L942
11+
# As it says, MySQL forbids using the *same* table in a subquery UPDATE:
12+
# https://dev.mysql.com/doc/refman/8.0/en/subquery-errors.html
13+
# Different tables are allowed though, as in our "update cats where id in (select owners..."
14+
# test below.
15+
716
module Unreliable
817
class SqlTestingData
918
class_attribute :update_manager_sql
@@ -27,26 +36,50 @@ def testing_compile_update(*args)
2736

2837
# rubocop:disable Layout/SpaceInsideParens,Layout/DotPosition
2938

30-
# Single subquery: "update cats where id in (select cats where name=bar)"
39+
# Single subquery for sqlite/postgresql: "update cats where id in (select cats where name=bar)"
40+
# Direct update for mysql: "update cats where name=bar"
3141
Cat.where(name: "foo").update_all(name: "bar")
3242
expect(Unreliable::SqlTestingData.update_manager_sql).
33-
to end_with(adapter_text("ORDER BY RANDOM())"))
43+
to end_with(
44+
case UnreliableTest.find_adapter
45+
when "mysql2"
46+
"ORDER BY RAND()"
47+
else
48+
adapter_text("ORDER BY RANDOM())")
49+
end
50+
)
3451

35-
# Double-nested subquery: "update cats where id in (select cats where id in (select owners where name=baz))"
52+
# Double-nested subquery for sqlite/postgresql: "update cats where id in (select cats where id in (select owners where name=baz))"
53+
# Single-nested for mysql: "update cats where id in (select owners where name=baz)"
3654
Cat.where( id: Owner.where(name: "bar") ).update_all(name: "baz")
3755
expect(Unreliable::SqlTestingData.update_manager_sql).
38-
to end_with(adapter_text("ORDER BY RANDOM()) ORDER BY RANDOM())"))
56+
to end_with(
57+
case UnreliableTest.find_adapter
58+
when "mysql2"
59+
"ORDER BY RAND()"
60+
else
61+
adapter_text("ORDER BY RANDOM()) ORDER BY RANDOM())")
62+
end
63+
)
64+
65+
# Single ordered subquery for sqlite/postgresql: "update cats where id in (select cats where name=bar limit ?)"
66+
# Direct update for mysql: "update cats where name=baz"
67+
Cat.where(name: "bar").limit(1).update_all(name: "baz")
68+
expect(Unreliable::SqlTestingData.update_manager_sql).
69+
to match(
70+
case UnreliableTest.find_adapter
71+
when "mysql2"
72+
'ORDER BY RAND\(\) LIMIT '
73+
else
74+
adapter_text('ORDER BY RANDOM\(\) LIMIT ')
75+
end
76+
)
3977

4078
# Single ordered subquery: "update cats where id in (select cats where name=bar order by id limit ?)"
4179
# The presence of the primary-key order means Unreliable does not apply its own order.
4280
Cat.where(name: "bar").order(:id).limit(1).update_all(name: "baz")
4381
expect(Unreliable::SqlTestingData.update_manager_sql).
44-
to end_with(adapter_text("ORDER BY \"cats\".\"id\" ASC LIMIT ?)"))
45-
46-
# Single ordered subquery: "update cats where id in (select cats where name=bar limit ?)"
47-
Cat.where(name: "bar").limit(1).update_all(name: "baz")
48-
expect(Unreliable::SqlTestingData.update_manager_sql).
49-
to end_with(adapter_text("ORDER BY RANDOM() LIMIT ?)"))
82+
to match(adapter_text('ORDER BY "cats"\."id" ASC LIMIT '))
5083

5184
# rubocop:enable Layout/SpaceInsideParens,Layout/DotPosition
5285
ensure

0 commit comments

Comments
 (0)