aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2018-11-03 14:45:25 +0900
committerRyuta Kamizono <kamipo@gmail.com>2018-11-03 14:54:57 +0900
commit19f0f140746bfae588f145fcd89df1c8f6df3910 (patch)
treecf68ea3a89158590af474d1b66740aec452b9432 /activerecord
parentb858c2c76cbe66b50df81372156d4b6f6e187be1 (diff)
downloadrails-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')
-rw-r--r--activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb12
-rw-r--r--activerecord/lib/arel/nodes/bind_param.rb4
-rw-r--r--activerecord/lib/arel/visitors/to_sql.rb12
-rw-r--r--activerecord/test/cases/bind_parameter_test.rb4
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