Skip to content

Commit 212fb0a

Browse files
authored
Update all subquery fixes (#1303)
1 parent 5832c04 commit 212fb0a

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

lib/arel/visitors/sqlserver.rb

+15-4
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)