aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2018-09-09 03:30:45 +0900
committerRyuta Kamizono <kamipo@gmail.com>2018-09-12 01:11:38 +0900
commita50eacb03cf3df1d1cbc227ea0115901e0327f1c (patch)
tree19e47b31a2aedbb8f34317fcf2dbe6b5d5aeb2c1 /activerecord/lib/active_record
parent82ac7555ab69c1ae11360d2b9bd8dfd723a13485 (diff)
downloadrails-a50eacb03cf3df1d1cbc227ea0115901e0327f1c.tar.gz
rails-a50eacb03cf3df1d1cbc227ea0115901e0327f1c.tar.bz2
rails-a50eacb03cf3df1d1cbc227ea0115901e0327f1c.zip
Eager loading/preloading should be worked regardless of large number of records
Since 213796f, bind params are used for IN clause if enabled prepared statements. Unfortunately, most adapter modules have a limitation for # of bind params (mysql2 65535, pg 65535, sqlite3 250000). So if eager loading large number of records at once, that query couldn't be sent to the database. Since eager loading/preloading queries are auto-generated by Active Record itself, so it should be worked regardless of large number of records like as before. Fixes #33702.
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder.rb6
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/array_handler.rb9
2 files changed, 10 insertions, 5 deletions
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index f734cd0ad8..cb70b8bcde 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -57,10 +57,14 @@ module ActiveRecord
end
def build_bind_attribute(column_name, value)
- attr = Relation::QueryAttribute.new(column_name.to_s, value, table.type(column_name))
+ attr = build_query_attribute(column_name, value)
Arel::Nodes::BindParam.new(attr)
end
+ def build_query_attribute(column_name, value)
+ Relation::QueryAttribute.new(column_name.to_s, value, table.type(column_name))
+ end
+
protected
def expand_from_hash(attributes)
return ["1=0"] if attributes.empty?
diff --git a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb
index e5191fa38a..0895b9fba6 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb
@@ -21,10 +21,11 @@ module ActiveRecord
when 0 then NullPredicate
when 1 then predicate_builder.build(attribute, values.first)
else
- bind_values = values.map do |v|
- predicate_builder.build_bind_attribute(attribute.name, v)
- end
- attribute.in(bind_values)
+ values.map! do |v|
+ attr = predicate_builder.build_query_attribute(attribute.name, v)
+ attr.value_for_database if attr.boundable?
+ end.compact!
+ values.empty? ? NullPredicate : attribute.in(values)
end
unless nils.empty?