Drop MySQL 5.5 support

MySQL 5.5 is the only version that does not support datetime with
precision, which we have supported in the core.
MySQL 5.5 is already EOL in December 2018, so let's drop this support and
clean up the code for it.
This commit is contained in:
Ryuta Kamizono 2024-09-06 20:16:13 +09:00
parent d2b6ae1f18
commit 6b1515aeb9
19 changed files with 52 additions and 159 deletions

View File

@ -1,3 +1,11 @@
* Drop MySQL 5.5 support.
MySQL 5.5 is the only version that does not support datetime with precision,
which we have supported in the core. Now we support MySQL 5.6.4 or later, which
is the first version to support datetime with precision.
*Ryuta Kamizono*
* Make Active Record asynchronous queries compatible with transactional fixtures.
Previously transactional fixtures would disable asynchronous queries, because transactional

View File

@ -138,7 +138,7 @@ module ActiveRecord
end
def supports_datetime_with_precision?
mariadb? || database_version >= "5.6.4"
true
end
def supports_virtual_columns?
@ -668,8 +668,8 @@ module ActiveRecord
end
def check_version # :nodoc:
if database_version < "5.5.8"
raise DatabaseVersionError, "Your version of MySQL (#{database_version}) is too old. Active Record supports MySQL >= 5.5.8."
if database_version < "5.6.4"
raise DatabaseVersionError, "Your version of MySQL (#{database_version}) is too old. Active Record supports MySQL >= 5.6.4."
end
end

View File

@ -1,47 +0,0 @@
# frozen_string_literal: true
require "cases/helper"
class DatetimePrecisionQuotingTest < ActiveRecord::AbstractMysqlTestCase
setup do
@connection = ActiveRecord::Base.lease_connection
end
test "microsecond precision for MySQL gte 5.6.4" do
stub_version "5.6.4" do
assert_microsecond_precision
end
end
test "no microsecond precision for MySQL lt 5.6.4" do
stub_version "5.6.3" do
assert_no_microsecond_precision
end
end
test "microsecond precision for MariaDB gte 5.3.0" do
stub_version "5.5.5-10.1.8-MariaDB-log" do
assert_microsecond_precision
end
end
private
def assert_microsecond_precision
assert_match_quoted_microsecond_datetime(/\.123456\z/)
end
def assert_no_microsecond_precision
assert_match_quoted_microsecond_datetime(/:55\z/)
end
def assert_match_quoted_microsecond_datetime(match)
assert_match match, @connection.quoted_date(Time.now.change(sec: 55, usec: 123456))
end
def stub_version(full_version_string, &block)
@connection.pool.pool_config.server_version = nil
@connection.stub(:get_full_version, full_version_string, &block)
ensure
@connection.pool.pool_config.server_version = nil
end
end

View File

@ -1466,8 +1466,6 @@ class CalculationsTest < ActiveRecord::TestCase
end
def assert_minimum_and_maximum_on_time_attributes(time_class)
skip unless supports_datetime_with_precision? # Remove once MySQL 5.5 support is dropped.
actual = Topic.minimum(:written_on)
assert_equal Time.utc(2003, 7, 16, 14, 28, 11, 223300), actual
assert_instance_of time_class, actual

View File

@ -106,7 +106,6 @@ module ActiveRecord
developers = Developer.where(name: "David")
cache_key = developers.cache_key
sleep 1.0 unless supports_datetime_with_precision? # Remove once MySQL 5.5 support is dropped.
developers.update_all(updated_at: Time.now.utc)
assert_not_equal cache_key, developers.cache_key
@ -116,7 +115,6 @@ module ActiveRecord
developers = Developer.includes(:projects).where("projects.name": "Active Record")
cache_key = developers.cache_key
sleep 1.0 unless supports_datetime_with_precision? # Remove once MySQL 5.5 support is dropped.
developers.update_all(updated_at: Time.now.utc)
assert_not_equal cache_key, developers.cache_key

View File

@ -72,7 +72,6 @@ class DateTimeTest < ActiveRecord::TestCase
end
def test_date_time_with_string_value_with_subsecond_precision
skip unless supports_datetime_with_precision?
string_value = "2017-07-04 14:19:00.5"
topic = Topic.create(written_on: string_value)
assert_equal topic, Topic.find_by(written_on: string_value)

View File

@ -620,7 +620,6 @@ class DirtyTest < ActiveRecord::TestCase
end
def test_datetime_attribute_can_be_updated_with_fractional_seconds
skip "Fractional seconds are not supported" unless supports_datetime_with_precision?
in_time_zone "Paris" do
target = Class.new(ActiveRecord::Base)
target.table_name = "topics"

View File

@ -479,7 +479,7 @@ class InsertAllTest < ActiveRecord::TestCase
end
def test_upsert_all_respects_updated_at_precision_when_touched_implicitly
skip unless supports_insert_on_duplicate_update? && supports_datetime_with_precision?
skip unless supports_insert_on_duplicate_update?
Book.insert_all [{ id: 101, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 1), updated_at: 5.years.ago, updated_on: 5.years.ago }]
@ -569,7 +569,7 @@ class InsertAllTest < ActiveRecord::TestCase
end
def test_upsert_all_respects_created_at_precision_when_touched_implicitly
skip unless supports_insert_on_duplicate_update? && supports_datetime_with_precision?
skip unless supports_insert_on_duplicate_update?
# A single upsert can occur exactly at the seconds boundary (when usec is naturally zero), so try multiple times.
has_subsecond_precision = (1..100).any? do |i|

View File

@ -174,7 +174,6 @@ class IntegrationTest < ActiveRecord::TestCase
end
def test_cache_key_format_is_precise_enough
skip("Subsecond precision is not supported") unless supports_datetime_with_precision?
dev = Developer.first
key = dev.cache_key
travel_to dev.updated_at + 0.000001 do
@ -191,7 +190,6 @@ class IntegrationTest < ActiveRecord::TestCase
end
def test_cache_version_format_is_precise_enough
skip("Subsecond precision is not supported") unless supports_datetime_with_precision?
with_cache_versioning do
dev = Developer.first
version = dev.cache_version.to_param

View File

@ -179,7 +179,6 @@ class OptimisticLockingTest < ActiveRecord::TestCase
p1 = Person.find(1)
assert_equal 0, p1.lock_version
sleep 1.0 unless supports_datetime_with_precision? # Remove once MySQL 5.5 support is dropped.
p1.touch
assert_equal 1, p1.lock_version
@ -298,7 +297,6 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_equal 0, t1.lock_version
assert_nil t1.lock_version_before_type_cast
sleep 1.0 unless supports_datetime_with_precision? # Remove once MySQL 5.5 support is dropped.
t1.touch
assert_equal 1, t1.lock_version

View File

@ -294,8 +294,7 @@ module ActiveRecord
if current_adapter?(:PostgreSQLAdapter)
assert_equal "timestamp(6) without time zone", column.sql_type
elsif current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
sql_type = supports_datetime_with_precision? ? "datetime(6)" : "datetime"
assert_equal sql_type, column.sql_type
assert_equal "datetime(6)", column.sql_type
else
assert_equal connection.type_to_sql("datetime(6)"), column.sql_type
end

View File

@ -761,8 +761,6 @@ if ActiveRecord::Base.lease_connection.supports_foreign_keys?
if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
if ActiveRecord::Base.lease_connection.mariadb?
assert_match(/Duplicate key on write or update/, error.message)
elsif ActiveRecord::Base.lease_connection.database_version < "5.6"
assert_match(/Can't create table/, error.message)
elsif ActiveRecord::Base.lease_connection.database_version < "8.0"
assert_match(/Can't write; duplicate key in table/, error.message)
else

View File

@ -351,7 +351,7 @@ class PrimaryKeyAnyTypeTest < ActiveRecord::TestCase
assert_no_match %r{t\.index \["code"\]}, schema
end
if current_adapter?(:Mysql2Adapter, :TrilogyAdapter) && supports_datetime_with_precision?
if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
test "schema typed primary key column" do
@connection.create_table(:scheduled_logs, id: :timestamp, precision: 6, force: true)
schema = dump_table_schema("scheduled_logs")

View File

@ -934,13 +934,7 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
assert_match %r{t\.string\s+"string_with_default",.*?default: "Hello!"}, output
assert_match %r{t\.date\s+"date_with_default",\s+default: "2014-06-05"}, output
if supports_datetime_with_precision?
assert_match %r{t\.datetime\s+"datetime_with_default",\s+default: "2014-06-05 07:17:04"}, output
else
assert_match %r{t\.datetime\s+"datetime_with_default",\s+precision: nil,\s+default: "2014-06-05 07:17:04"}, output
end
assert_match %r{t\.datetime\s+"datetime_with_default",\s+default: "2014-06-05 07:17:04"}, output
assert_match %r{t\.time\s+"time_with_default",\s+default: "2000-01-01 07:17:04"}, output
assert_match %r{t\.decimal\s+"decimal_with_default",\s+precision: 20,\s+scale: 10,\s+default: "1234567890.0123456789"}, output
end

View File

@ -34,8 +34,6 @@ class TimestampTest < ActiveRecord::TestCase
end
def test_touching_a_record_updates_its_timestamp
sleep 1.0 unless supports_datetime_with_precision? # Remove once MySQL 5.5 support is dropped.
previous_salary = @developer.salary
@developer.salary = previous_salary + 10000
@developer.touch
@ -53,8 +51,6 @@ class TimestampTest < ActiveRecord::TestCase
end
def test_touching_a_record_with_default_scope_that_excludes_it_updates_its_timestamp
sleep 1.0 unless supports_datetime_with_precision? # Remove once MySQL 5.5 support is dropped.
developer = @developer.becomes(DeveloperCalledJamis)
developer.touch

View File

@ -7,7 +7,6 @@ module ActiveRecord
module Type
class DateTimeTest < ActiveRecord::TestCase
def test_datetime_seconds_precision_applied_to_timestamp
skip "This test is invalid if subsecond precision isn't supported" unless supports_datetime_with_precision?
p = Task.create!(starting: ::Time.now)
assert_equal p.starting.usec, p.reload.starting.usec
end

View File

@ -1,19 +1,17 @@
# frozen_string_literal: true
ActiveRecord::Schema.define do
if connection.supports_datetime_with_precision?
create_table :datetime_defaults, force: true do |t|
t.datetime :modified_datetime, precision: nil, default: -> { "CURRENT_TIMESTAMP" }
t.datetime :precise_datetime, default: -> { "CURRENT_TIMESTAMP(6)" }
t.datetime :updated_datetime, default: -> { "CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" }
end
create_table :datetime_defaults, force: true do |t|
t.datetime :modified_datetime, precision: nil, default: -> { "CURRENT_TIMESTAMP" }
t.datetime :precise_datetime, default: -> { "CURRENT_TIMESTAMP(6)" }
t.datetime :updated_datetime, default: -> { "CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" }
end
create_table :timestamp_defaults, force: true do |t|
t.timestamp :nullable_timestamp
t.timestamp :modified_timestamp, precision: nil, default: -> { "CURRENT_TIMESTAMP" }
t.timestamp :precise_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6)" }
t.timestamp :updated_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" }
end
create_table :timestamp_defaults, force: true do |t|
t.timestamp :nullable_timestamp
t.timestamp :modified_timestamp, precision: nil, default: -> { "CURRENT_TIMESTAMP" }
t.timestamp :precise_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6)" }
t.timestamp :updated_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" }
end
create_table :defaults, force: true do |t|

View File

@ -148,13 +148,8 @@ ActiveRecord::Schema.define do
t.index :isbn, where: "published_on IS NOT NULL", unique: true
t.index "(lower(external_id))", unique: true if supports_expression_index?
if supports_datetime_with_precision?
t.datetime :created_at, precision: 6
t.datetime :updated_at, precision: 6
else
t.datetime :created_at
t.datetime :updated_at
end
t.datetime :created_at
t.datetime :updated_at
t.date :updated_on
end
@ -541,17 +536,10 @@ ActiveRecord::Schema.define do
t.integer :salary, default: 70000
t.references :firm, index: false
t.integer :mentor_id
if supports_datetime_with_precision?
t.datetime :legacy_created_at, precision: 6
t.datetime :legacy_updated_at, precision: 6
t.datetime :legacy_created_on, precision: 6
t.datetime :legacy_updated_on, precision: 6
else
t.datetime :legacy_created_at
t.datetime :legacy_updated_at
t.datetime :legacy_created_on
t.datetime :legacy_updated_on
end
t.datetime :legacy_created_at
t.datetime :legacy_updated_at
t.datetime :legacy_created_on
t.datetime :legacy_updated_on
end
create_table :developers_projects, force: true, id: false do |t|
@ -685,11 +673,7 @@ ActiveRecord::Schema.define do
create_table :invoices, force: true do |t|
t.integer :balance
if supports_datetime_with_precision?
t.datetime :updated_at, precision: 6
else
t.datetime :updated_at
end
t.datetime :updated_at
end
create_table :iris, force: true do |t|
@ -882,11 +866,7 @@ ActiveRecord::Schema.define do
create_table :owners, primary_key: :owner_id, force: true do |t|
t.string :name
if supports_datetime_with_precision?
t.column :updated_at, :datetime, precision: 6
else
t.column :updated_at, :datetime
end
t.column :updated_at, :datetime
t.column :happy_at, :datetime
t.string :essay_id
end
@ -907,30 +887,18 @@ ActiveRecord::Schema.define do
t.string :parrot_sti_class
t.integer :killer_id
t.integer :updated_count, :integer, default: 0
if supports_datetime_with_precision?
t.datetime :created_at, precision: 0
t.datetime :created_on, precision: 0
t.datetime :updated_at, precision: 0
t.datetime :updated_on, precision: 0
else
t.datetime :created_at
t.datetime :created_on
t.datetime :updated_at
t.datetime :updated_on
end
t.datetime :created_at, precision: 0
t.datetime :created_on, precision: 0
t.datetime :updated_at, precision: 0
t.datetime :updated_on, precision: 0
end
create_table :pirates, force: :cascade do |t|
t.string :catchphrase
t.integer :parrot_id
t.integer :non_validated_parrot_id
if supports_datetime_with_precision?
t.datetime :created_on, precision: 6
t.datetime :updated_on, precision: 6
else
t.datetime :created_on
t.datetime :updated_on
end
t.datetime :created_on
t.datetime :updated_on
end
create_table :treasures, force: :cascade do |t|
@ -1154,11 +1122,7 @@ ActiveRecord::Schema.define do
create_table :ship_parts, force: true do |t|
t.string :name
t.integer :ship_id
if supports_datetime_with_precision?
t.datetime :updated_at, precision: 6
else
t.datetime :updated_at
end
t.datetime :updated_at
end
create_table :squeaks, force: true do |t|
@ -1234,11 +1198,7 @@ ActiveRecord::Schema.define do
t.string :title, limit: 250
t.string :author_name
t.string :author_email_address
if supports_datetime_with_precision?
t.datetime :written_on, precision: 6
else
t.datetime :written_on
end
t.datetime :written_on
t.time :bonus_time
t.date :last_read
t.text :content

View File

@ -1,19 +1,17 @@
# frozen_string_literal: true
ActiveRecord::Schema.define do
if connection.supports_datetime_with_precision?
create_table :datetime_defaults, force: true do |t|
t.datetime :modified_datetime, precision: nil, default: -> { "CURRENT_TIMESTAMP" }
t.datetime :precise_datetime, default: -> { "CURRENT_TIMESTAMP(6)" }
t.datetime :updated_datetime, default: -> { "CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" }
end
create_table :datetime_defaults, force: true do |t|
t.datetime :modified_datetime, precision: nil, default: -> { "CURRENT_TIMESTAMP" }
t.datetime :precise_datetime, default: -> { "CURRENT_TIMESTAMP(6)" }
t.datetime :updated_datetime, default: -> { "CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" }
end
create_table :timestamp_defaults, force: true do |t|
t.timestamp :nullable_timestamp
t.timestamp :modified_timestamp, precision: nil, default: -> { "CURRENT_TIMESTAMP" }
t.timestamp :precise_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6)" }
t.timestamp :updated_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" }
end
create_table :timestamp_defaults, force: true do |t|
t.timestamp :nullable_timestamp
t.timestamp :modified_timestamp, precision: nil, default: -> { "CURRENT_TIMESTAMP" }
t.timestamp :precise_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6)" }
t.timestamp :updated_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" }
end
create_table :defaults, force: true do |t|