Skip to content

Commit 869d802

Browse files
committed
Raise a descriptive error if the MySQL adapter fails to parse the version string.
1 parent 3d418c0 commit 869d802

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

activerecord/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Raise an `ActiveRecord::ActiveRecordError` error when the MySQL database returns an invalid version string.
2+
3+
*Kevin McPhillips*
4+
15
* `ActiveRecord::Base.transaction` now yields an `ActiveRecord::Transation` object.
26

37
This allows to register callbacks on it.

activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ def build_insert_sql(insert) # :nodoc:
680680

681681
def check_version # :nodoc:
682682
if database_version < "5.5.8"
683-
raise "Your version of MySQL (#{database_version}) is too old. Active Record supports MySQL >= 5.5.8."
683+
raise DatabaseVersionError, "Your version of MySQL (#{database_version}) is too old. Active Record supports MySQL >= 5.5.8."
684684
end
685685
end
686686

@@ -1023,7 +1023,11 @@ def mismatched_foreign_key(message, sql:, binds:, connection_pool:)
10231023
end
10241024

10251025
def version_string(full_version_string)
1026-
full_version_string.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
1026+
if full_version_string && matches = full_version_string.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)
1027+
matches[1]
1028+
else
1029+
raise DatabaseVersionError, "Unable to parse MySQL version from #{full_version_string.inspect}"
1030+
end
10271031
end
10281032
end
10291033
end

activerecord/lib/active_record/errors.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,4 +575,9 @@ class ConnectionFailed < QueryAborted
575575
# values, such as request parameters or model attributes to query methods.
576576
class UnknownAttributeReference < ActiveRecordError
577577
end
578+
579+
# DatabaseVersionError will be raised when the database version is not supported, or when
580+
# the database version cannot be determined.
581+
class DatabaseVersionError < ActiveRecordError
582+
end
578583
end

activerecord/test/cases/adapters/abstract_mysql_adapter/connection_test.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,39 @@ def test_release_non_existent_advisory_lock
216216
"expected release_advisory_lock to return false when there was no lock to release"
217217
end
218218

219+
def test_version_string
220+
@connection.stub(:get_full_version, "8.0.35-0ubuntu0.22.04.1") do
221+
assert_equal "8.0.35", @connection.get_database_version.to_s
222+
end
223+
224+
@connection.stub(:get_full_version, "5.7.0") do
225+
assert_equal "5.7.0", @connection.get_database_version.to_s
226+
end
227+
end
228+
229+
def test_version_string_invalid
230+
@connection.stub(:get_full_version, "some-database-proxy") do
231+
error = assert_raises(ActiveRecord::DatabaseVersionError) do
232+
@connection.get_database_version
233+
end
234+
assert_equal "Unable to parse MySQL version from \"some-database-proxy\"", error.message
235+
end
236+
237+
@connection.stub(:get_full_version, "") do
238+
error = assert_raises(ActiveRecord::DatabaseVersionError) do
239+
@connection.get_database_version
240+
end
241+
assert_equal "Unable to parse MySQL version from \"\"", error.message
242+
end
243+
244+
@connection.stub(:get_full_version, nil) do
245+
error = assert_raises(ActiveRecord::DatabaseVersionError) do
246+
@connection.get_database_version
247+
end
248+
assert_equal "Unable to parse MySQL version from nil", error.message
249+
end
250+
end
251+
219252
private
220253
def cause_server_side_disconnect
221254
@connection.update("set @@wait_timeout=1")

0 commit comments

Comments
 (0)