You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> Sometimes, operations on Times returns just float numbers of seconds, so, we
need to handle that.
> Example: Time.current - (Time.current + 1.hour) # => -3600.000001776 (Float)
When this happens, it's possible to endup with a pretty large number of seconds,
making the ISO 8601 formatted duration to trigger an `interval field value out
range error`.
PostgreSQL 15 has already improved overflow detection when casting values to
interval
However, to further reduce the likelihood of such issues and ensure
better-formatted duration types, it now implements the construction of
`ActiveSupport::Duration` during the serialization step.
How to reproduce (at least in versions prior to PG 15+):
``` ruby
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", github: "rails/rails", branch: "main"
gem "pg"
end
require "active_record"
require "minitest/autorun"
require "logger"
ActiveRecord::Base.establish_connection(
adapter: 'postgresql',
database: 'postgres',
username: 'postgres',
host: 'localhost'
)
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :projects, force: true do |t|
t.interval :duration
end
end
class Project < ActiveRecord::Base; end
class IntervalBugTest < Minitest::Test
def test_duration
project = Project.create(duration: 70.years)
assert_equal 70.years, project.duration
end
def test_duration_error
duration = 70.years.ago - Time.now()
assert_raises ActiveRecord::StatementInvalid do
Project.create(duration: duration)
end
end
end
```
0 commit comments