@@ -57,16 +57,23 @@ def visit_Arel_Nodes_UpdateStatement(o, collector)
5757 collect_nodes_for o . values , collector , " SET "
5858 collector << " FROM "
5959 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 , " " , ", "
6166
6267 if remaining_joins && !remaining_joins . empty?
6368 collector << " "
6469 remaining_joins . each do |join |
6570 visit join , collector
71+ collector << " "
6672 end
6773 end
6874
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 "
7077 else
7178 collector = visit o . relation , collector
7279 collect_nodes_for o . values , collector , " SET "
@@ -77,9 +84,13 @@ def visit_Arel_Nodes_UpdateStatement(o, collector)
7784 maybe_visit o . limit , collector
7885 end
7986
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.
8188 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 } )
8394 o
8495 else
8596 o . limit = Nodes ::Limit . new ( 9_223_372_036_854_775_807 ) if o . orders . any? && o . limit . nil?
0 commit comments