-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RangeError when querying for big integer using #where in Rails 4.2 #21309
Comments
Yes, we do. That value won't fit into a PostgreSQL bigint, so we cannot run the query with it. Previous versions didn't use parameterized queries, so PostgreSQL was able to dynamically guess the type based on the size of the literal. |
@matthewd look, it's just a simple query to find something in the database development=> select * from products where associated_id = 1184827921141444343875083923; PostgreSQL 9.4.4 , no error. Anyway, perhaps it's easier to just add find_all_by method as I described above. def find_all_by(*args)
where(*args).load
rescue RangeError
none
end |
Great! Patch welcome.
We can't do that, for the same reason we don't currently rescue the RangeError everywhere: it would behave incorrectly any time the out-of-range value didn't imply no results. (e.g., |
If you use If you use IMHO, this behavior is kind of strange. ActiveRecord should be able to perform I believe that this validation of range must only happen when trying to save to the database. |
The for
The RBDMS will not allow you to query with an out of range integer (sometimes, depending on context specifically using prepared statements is the main problem). This change was made to allow you to handle a |
I'm OK with it but it would be good to add a method which returns multiple records, similar to find_by to FinderMethods module ##
# Like <tt>find_by</tt>, but returns multiple records or none relation
#
def find_all_by(*args)
where(*args).load
rescue RangeError
none
end UPDATE: for Rails 4.2.7.1 I had to add that method to AR Core class directly ( For Rails 5 such definition should go to |
@sgrif What about #21309 (comment)? |
@januszm If it were that simple, we would have just done that in @agis- I think that |
@sgrif Thing is, we are now forced to rescue |
@agis- I completely agree, something like @sgrif I would agree that |
Rails 3
Product.where(associated_id: 1311344470881970878875083923).first
=> nil
Rails 4.2.3
Product.where(associated_id: 1311344470881970878875083923).first
RangeError: 1311344470881970878875083923 is out of range for ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer with limit 8
from ~/.rvm/gems/ruby-2.2.1@gemset/gems/activerecord-4.2.3/lib/active_record/type/integer.rb:45:in
ensure_in_range
I'd expect that the finder returns nothing in Rails 4.2.3 as well in such a case. It's just searching for results, we don't need to call ensure_in_range.
As a workaround, someone could use
find_by
, but when there's a need for returning multiple records, then there's no such method asfind_all_by
that could be used. BTW. find_by works because it rescues from RangeError.The text was updated successfully, but these errors were encountered: