-
Notifications
You must be signed in to change notification settings - Fork 22k
Description
Steps to reproduce
Create an ActiveRecord scope using an Arel::Nodes::Or
as a condition to #where
.
Post.where(Arel::Nodes::Or.new([Post.arel_table[:author_id].eq(1), Post.arel_table[:author_id].eq(2)])
).find_each(batch_size: 10) { […] }
See gist for a complete working example.
The linked gist also contains two examples where #find_each
works as expected — one when using an SQL literal as a condition to #where
, the other with an Arel::Nodes::Grouping
as outer-most node of the condition.
Expected behavior
find_each
correctly loops the scope.
Actual behavior
ActiveRecord::Batches#batch_on_unloaded_relation
generates the invalid SQL […] author_id = 1 OR author_id = 2 AND id IN (1, 2)
. By SQL standard, this is parsed as author_id = 1 OR (author_id = 2 AND id IN (1, 2))
instead of the expected (author_id = 1 OR author_id = 2) AND id IN (1, 2)
.
With more data, this leads to an endless loop, because the list of ids does not change.
System configuration
Rails version: 8.0.2.1 (also tested with 8.0.3 with same result)
Ruby version: 3.4.2