@@ -57,16 +57,23 @@ def visit_Arel_Nodes_UpdateStatement(o, collector)
57
57
collect_nodes_for o . values , collector , " SET "
58
58
collector << " FROM "
59
59
first_join , *remaining_joins = o . relation . right
60
- visit first_join . left , collector
60
+ from_items = remaining_joins . extract! do |join |
61
+ join . right . expr . right . relation == o . relation . left
62
+ end
63
+
64
+ from_where = [ first_join . left ] + from_items . map ( &:left )
65
+ collect_nodes_for from_where , collector , " " , ", "
61
66
62
67
if remaining_joins && !remaining_joins . empty?
63
68
collector << " "
64
69
remaining_joins . each do |join |
65
70
visit join , collector
71
+ collector << " "
66
72
end
67
73
end
68
74
69
- collect_nodes_for [ first_join . right . expr ] + o . wheres , collector , " WHERE " , " AND "
75
+ from_where = [ first_join . right . expr ] + from_items . map { |i | i . right . expr }
76
+ collect_nodes_for from_where + o . wheres , collector , " WHERE " , " AND "
70
77
else
71
78
collector = visit o . relation , collector
72
79
collect_nodes_for o . values , collector , " SET "
@@ -77,9 +84,13 @@ def visit_Arel_Nodes_UpdateStatement(o, collector)
77
84
maybe_visit o . limit , collector
78
85
end
79
86
80
- # Same as PostgreSQL except we need to add limit if using subquery.
87
+ # Same as PostgreSQL and SQLite except we need to add limit if using subquery.
81
88
def prepare_update_statement ( o )
82
- if has_join_sources? ( o ) && !has_limit_or_offset_or_orders? ( o ) && !has_group_by_and_having? ( o ) && o . relation . right . first . is_a? ( Arel ::Nodes ::InnerJoin )
89
+ if has_join_sources? ( o ) && !has_limit_or_offset_or_orders? ( o ) && !has_group_by_and_having? ( o ) &&
90
+ # The dialect isn't flexible enough to allow anything other than a inner join
91
+ # for the first join:
92
+ # UPDATE table SET .. FROM joined_table WHERE ...
93
+ ( o . relation . right . all? { |join | join . is_a? ( Arel ::Nodes ::InnerJoin ) || join . right . expr . right . relation != o . relation . left } )
83
94
o
84
95
else
85
96
o . limit = Nodes ::Limit . new ( 9_223_372_036_854_775_807 ) if o . orders . any? && o . limit . nil?
0 commit comments