From a50eacb03cf3df1d1cbc227ea0115901e0327f1c Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Sun, 9 Sep 2018 03:30:45 +0900 Subject: 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. --- activerecord/lib/active_record/relation/predicate_builder.rb | 6 +++++- .../active_record/relation/predicate_builder/array_handler.rb | 9 +++++---- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'activerecord/lib/active_record') 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? -- cgit v1.2.3