mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Prevent making bind param if casted value is nil
If casted value is nil, generated SQL should be `IS NULL`. But currently it is generated as `= NULL`. To prevent this behavior, avoid making bind param if casted value is nil. Fixes #28945.
This commit is contained in:
parent
7c800fe5e3
commit
67a4a9feb9
5 changed files with 24 additions and 9 deletions
|
@ -1,3 +1,7 @@
|
|||
* Prevent making bind param if casted value is nil.
|
||||
|
||||
*Ryuta Kamizono*
|
||||
|
||||
* Deprecate passing arguments and block at the same time to `count` and `sum` in `ActiveRecord::Calculations`.
|
||||
|
||||
*Ryuta Kamizono*
|
||||
|
|
|
@ -107,21 +107,26 @@ module ActiveRecord
|
|||
first = value.begin
|
||||
last = value.end
|
||||
unless first.respond_to?(:infinite?) && first.infinite?
|
||||
binds << build_bind_param(column_name, first)
|
||||
binds << build_bind_attribute(column_name, first)
|
||||
first = Arel::Nodes::BindParam.new
|
||||
end
|
||||
unless last.respond_to?(:infinite?) && last.infinite?
|
||||
binds << build_bind_param(column_name, last)
|
||||
binds << build_bind_attribute(column_name, last)
|
||||
last = Arel::Nodes::BindParam.new
|
||||
end
|
||||
|
||||
result[column_name] = RangeHandler::RangeWithBinds.new(first, last, value.exclude_end?)
|
||||
when value.is_a?(Relation)
|
||||
binds.concat(value.bound_attributes)
|
||||
else
|
||||
if can_be_bound?(column_name, value)
|
||||
result[column_name] = Arel::Nodes::BindParam.new
|
||||
binds << build_bind_param(column_name, value)
|
||||
elsif value.is_a?(Relation)
|
||||
binds.concat(value.bound_attributes)
|
||||
bind_attribute = build_bind_attribute(column_name, value)
|
||||
if value.is_a?(StatementCache::Substitute) || !bind_attribute.value_for_database.nil?
|
||||
result[column_name] = Arel::Nodes::BindParam.new
|
||||
binds << bind_attribute
|
||||
else
|
||||
result[column_name] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -164,7 +169,7 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def build_bind_param(column_name, value)
|
||||
def build_bind_attribute(column_name, value)
|
||||
Relation::QueryAttribute.new(column_name.to_s, value, table.type(column_name))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -57,7 +57,7 @@ module ActiveRecord
|
|||
else
|
||||
column = klass.column_for_attribute(attribute)
|
||||
|
||||
binds << predicate_builder.send(:build_bind_param, attribute, value)
|
||||
binds << predicate_builder.send(:build_bind_attribute, attribute, value)
|
||||
value = Arel::Nodes::BindParam.new
|
||||
|
||||
predicate = if options[:case_sensitive]
|
||||
|
|
|
@ -60,6 +60,7 @@ class EnumTest < ActiveRecord::TestCase
|
|||
assert_not_equal @book, Book.where(status: [:written]).first
|
||||
assert_not_equal @book, Book.where.not(status: :published).first
|
||||
assert_equal @book, Book.where.not(status: :written).first
|
||||
assert_equal books(:ddd), Book.where(read_status: :forgotten).first
|
||||
end
|
||||
|
||||
test "find via where with strings" do
|
||||
|
@ -69,6 +70,7 @@ class EnumTest < ActiveRecord::TestCase
|
|||
assert_not_equal @book, Book.where(status: ["written"]).first
|
||||
assert_not_equal @book, Book.where.not(status: "published").first
|
||||
assert_equal @book, Book.where.not(status: "written").first
|
||||
assert_equal books(:ddd), Book.where(read_status: "forgotten").first
|
||||
end
|
||||
|
||||
test "build from scope" do
|
||||
|
|
|
@ -15,7 +15,7 @@ require "models/vertex"
|
|||
|
||||
module ActiveRecord
|
||||
class WhereTest < ActiveRecord::TestCase
|
||||
fixtures :posts, :edges, :authors, :author_addresses, :binaries, :essays, :cars, :treasures, :price_estimates
|
||||
fixtures :posts, :edges, :authors, :author_addresses, :binaries, :essays, :cars, :treasures, :price_estimates, :topics
|
||||
|
||||
def test_where_copies_bind_params
|
||||
author = authors(:david)
|
||||
|
@ -48,6 +48,10 @@ module ActiveRecord
|
|||
assert_equal [chef], chefs.to_a
|
||||
end
|
||||
|
||||
def test_where_with_casted_value_is_nil
|
||||
assert_equal 4, Topic.where(last_read: "").count
|
||||
end
|
||||
|
||||
def test_rewhere_on_root
|
||||
assert_equal posts(:welcome), Post.rewhere(title: "Welcome to the weblog").first
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue