aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2017-07-21 12:26:09 +0900
committerRyuta Kamizono <kamipo@gmail.com>2019-01-18 16:01:14 +0900
commitc196ca72a0dfbea5f1730f830ea20a9e02a3c737 (patch)
tree2017197758672519af2a2ef44eb674af35491a99
parent31ffbf8d5056137717da3f11d28c4fbd7fbc8f07 (diff)
downloadrails-c196ca72a0dfbea5f1730f830ea20a9e02a3c737.tar.gz
rails-c196ca72a0dfbea5f1730f830ea20a9e02a3c737.tar.bz2
rails-c196ca72a0dfbea5f1730f830ea20a9e02a3c737.zip
Ensure `StatementCache#execute` never raises `RangeError`
Since 31ffbf8d, finder methods no longer raise `RangeError`. So `StatementCache#execute` is the only place to raise the exception for finder queries. `StatementCache` is used for simple equality queries in the codebase. This means that if `StatementCache#execute` raises `RangeError`, the result could always be regarded as empty. So `StatementCache#execute` just return nil in that range error case, and treat that as empty in the caller side, then we can avoid catching the exception in much places.
-rw-r--r--activerecord/lib/active_record/associations/association.rb4
-rw-r--r--activerecord/lib/active_record/associations/singular_association.rb2
-rw-r--r--activerecord/lib/active_record/core.rb9
-rw-r--r--activerecord/lib/active_record/statement_cache.rb2
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb14
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb6
-rw-r--r--activerecord/test/models/reference.rb1
7 files changed, 19 insertions, 19 deletions
diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb
index fb205d9ba5..5d0927f17d 100644
--- a/activerecord/lib/active_record/associations/association.rb
+++ b/activerecord/lib/active_record/associations/association.rb
@@ -190,9 +190,7 @@ module ActiveRecord
end
binds = AssociationScope.get_bind_values(owner, reflection.chain)
- sc.execute(binds, conn) do |record|
- set_inverse_instance(record)
- end
+ sc.execute(binds, conn) { |record| set_inverse_instance(record) } || []
end
# The scope for this association.
diff --git a/activerecord/lib/active_record/associations/singular_association.rb b/activerecord/lib/active_record/associations/singular_association.rb
index c296f9882e..a92932fa4b 100644
--- a/activerecord/lib/active_record/associations/singular_association.rb
+++ b/activerecord/lib/active_record/associations/singular_association.rb
@@ -37,8 +37,6 @@ module ActiveRecord
def find_target
super.first
- rescue ::RangeError
- nil
end
def replace(record)
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 600825659b..369d63e40a 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -169,15 +169,12 @@ module ActiveRecord
where(key => params.bind).limit(1)
}
- record = statement.execute([id], connection).first
+ record = statement.execute([id], connection)&.first
unless record
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
name, primary_key, id)
end
record
- rescue ::RangeError
- raise RecordNotFound.new("Couldn't find #{name} with an out of range value for '#{primary_key}'",
- name, primary_key)
end
def find_by(*args) # :nodoc:
@@ -201,11 +198,9 @@ module ActiveRecord
where(wheres).limit(1)
}
begin
- statement.execute(hash.values, connection).first
+ statement.execute(hash.values, connection)&.first
rescue TypeError
raise ActiveRecord::StatementInvalid
- rescue ::RangeError
- nil
end
end
diff --git a/activerecord/lib/active_record/statement_cache.rb b/activerecord/lib/active_record/statement_cache.rb
index 1b1736dcab..95984e7ada 100644
--- a/activerecord/lib/active_record/statement_cache.rb
+++ b/activerecord/lib/active_record/statement_cache.rb
@@ -132,6 +132,8 @@ module ActiveRecord
sql = query_builder.sql_for bind_values, connection
klass.find_by_sql(sql, bind_values, preparable: true, &block)
+ rescue ::RangeError
+ nil
end
def self.unsupported_value?(value)
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index acafbe0b4d..a61569420e 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -1293,17 +1293,17 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
end
def test_belongs_to_with_out_of_range_value_assigning
- model = Class.new(Comment) do
+ model = Class.new(Author) do
def self.name; "Temp"; end
- validates :post, presence: true
+ validates :author_address, presence: true
end
- comment = model.new
- comment.post_id = 9223372036854775808 # out of range in the bigint
+ author = model.new
+ author.author_address_id = 9223372036854775808 # out of range in the bigint
- assert_nil comment.post
- assert_not_predicate comment, :valid?
- assert_equal [{ error: :blank }], comment.errors.details[:post]
+ assert_nil author.author_address
+ assert_not_predicate author, :valid?
+ assert_equal [{ error: :blank }], author.errors.details[:author_address]
end
def test_polymorphic_with_custom_primary_key
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 4b9b55f822..2f090d9862 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -27,6 +27,7 @@ require "models/categorization"
require "models/minivan"
require "models/speedometer"
require "models/reference"
+require "models/job"
require "models/college"
require "models/student"
require "models/pirate"
@@ -2926,6 +2927,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
end
+ def test_has_many_with_out_of_range_value
+ reference = Reference.create!(id: 2147483648) # out of range in the integer
+ assert_equal [], reference.ideal_jobs
+ end
+
private
def force_signal37_to_load_all_clients_of_firm
diff --git a/activerecord/test/models/reference.rb b/activerecord/test/models/reference.rb
index 2a7a1e3b77..82185040d6 100644
--- a/activerecord/test/models/reference.rb
+++ b/activerecord/test/models/reference.rb
@@ -4,6 +4,7 @@ class Reference < ActiveRecord::Base
belongs_to :person
belongs_to :job
+ has_many :ideal_jobs, class_name: "Job", foreign_key: :ideal_reference_id
has_many :agents_posts_authors, through: :person
class << self; attr_accessor :make_comments; end