diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2018-11-03 14:45:25 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2018-11-03 14:54:57 +0900 |
commit | 19f0f140746bfae588f145fcd89df1c8f6df3910 (patch) | |
tree | cf68ea3a89158590af474d1b66740aec452b9432 /activerecord | |
parent | b858c2c76cbe66b50df81372156d4b6f6e187be1 (diff) | |
download | rails-19f0f140746bfae588f145fcd89df1c8f6df3910.tar.gz rails-19f0f140746bfae588f145fcd89df1c8f6df3910.tar.bz2 rails-19f0f140746bfae588f145fcd89df1c8f6df3910.zip |
Checking boundable not only `IN` clause but also `NOT IN` clause
Diffstat (limited to 'activerecord')
4 files changed, 24 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb b/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb index f158946c6d..883747b84b 100644 --- a/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +++ b/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb @@ -12,15 +12,11 @@ module ActiveRecord def visit_Arel_Nodes_In(o, collector) @preparable = false + super + end - if Array === o.right && !o.right.empty? - o.right.delete_if do |bind| - if Arel::Nodes::BindParam === bind && Relation::QueryAttribute === bind.value - !bind.value.boundable? - end - end - end - + def visit_Arel_Nodes_NotIn(o, collector) + @preparable = false super end diff --git a/activerecord/lib/arel/nodes/bind_param.rb b/activerecord/lib/arel/nodes/bind_param.rb index 91e9b2b70f..ba8340558a 100644 --- a/activerecord/lib/arel/nodes/bind_param.rb +++ b/activerecord/lib/arel/nodes/bind_param.rb @@ -23,6 +23,10 @@ module Arel # :nodoc: all def nil? value.nil? end + + def boundable? + !value.respond_to?(:boundable?) || value.boundable? + end end end end diff --git a/activerecord/lib/arel/visitors/to_sql.rb b/activerecord/lib/arel/visitors/to_sql.rb index 7ce26884a5..8e56fb55a2 100644 --- a/activerecord/lib/arel/visitors/to_sql.rb +++ b/activerecord/lib/arel/visitors/to_sql.rb @@ -579,6 +579,10 @@ module Arel # :nodoc: all end def visit_Arel_Nodes_In(o, collector) + if Array === o.right && !o.right.empty? + o.right.keep_if { |value| boundable?(value) } + end + if Array === o.right && o.right.empty? collector << "1=0" else @@ -589,6 +593,10 @@ module Arel # :nodoc: all end def visit_Arel_Nodes_NotIn(o, collector) + if Array === o.right && !o.right.empty? + o.right.keep_if { |value| boundable?(value) } + end + if Array === o.right && o.right.empty? collector << "1=1" else @@ -788,6 +796,10 @@ module Arel # :nodoc: all } end + def boundable?(value) + !value.respond_to?(:boundable?) || value.boundable? + end + def has_join_sources?(o) o.relation.is_a?(Nodes::JoinSource) && !o.relation.right.empty? end diff --git a/activerecord/test/cases/bind_parameter_test.rb b/activerecord/test/cases/bind_parameter_test.rb index fddc2781b8..bd5f157ca1 100644 --- a/activerecord/test/cases/bind_parameter_test.rb +++ b/activerecord/test/cases/bind_parameter_test.rb @@ -36,8 +36,12 @@ if ActiveRecord::Base.connection.prepared_statements def test_too_many_binds bind_params_length = @connection.send(:bind_params_length) + topics = Topic.where(id: (1 .. bind_params_length).to_a << 2**63) assert_equal Topic.count, topics.count + + topics = Topic.where.not(id: (1 .. bind_params_length).to_a << 2**63) + assert_equal 0, topics.count end def test_bind_from_join_in_subquery |