4
4
# by build_arel. It returns an Arel::UpdateManager. This makes sure that internal call
5
5
# assembles the update query correctly.
6
6
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
+
7
16
module Unreliable
8
17
class SqlTestingData
9
18
class_attribute :update_manager_sql
@@ -27,26 +36,50 @@ def testing_compile_update(*args)
27
36
28
37
# rubocop:disable Layout/SpaceInsideParens,Layout/DotPosition
29
38
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"
31
41
Cat . where ( name : "foo" ) . update_all ( name : "bar" )
32
42
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
+ )
34
51
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)"
36
54
Cat . where ( id : Owner . where ( name : "bar" ) ) . update_all ( name : "baz" )
37
55
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
+ )
39
77
40
78
# Single ordered subquery: "update cats where id in (select cats where name=bar order by id limit ?)"
41
79
# The presence of the primary-key order means Unreliable does not apply its own order.
42
80
Cat . where ( name : "bar" ) . order ( :id ) . limit ( 1 ) . update_all ( name : "baz" )
43
81
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 ' ) )
50
83
51
84
# rubocop:enable Layout/SpaceInsideParens,Layout/DotPosition
52
85
ensure
0 commit comments