Skip to content

Commit 58158c0

Browse files
authored
Merge pull request rails#51478 from kmcphillips/mysql-parse-version-error
Raise named exception in `AbstractMysqlAdapter` when DB reports an invalid version
2 parents f613ba8 + d9995cc commit 58158c0

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-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: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,45 @@ 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_with_mariadb
230+
@connection.stub(:get_full_version, "5.5.5-10.6.5-MariaDB-1:10.6.5+maria~focal") do
231+
assert_equal "10.6.5", @connection.get_database_version.to_s
232+
end
233+
end
234+
235+
def test_version_string_invalid
236+
@connection.stub(:get_full_version, "some-database-proxy") do
237+
error = assert_raises(ActiveRecord::DatabaseVersionError) do
238+
@connection.get_database_version
239+
end
240+
assert_equal "Unable to parse MySQL version from \"some-database-proxy\"", error.message
241+
end
242+
243+
@connection.stub(:get_full_version, "") do
244+
error = assert_raises(ActiveRecord::DatabaseVersionError) do
245+
@connection.get_database_version
246+
end
247+
assert_equal "Unable to parse MySQL version from \"\"", error.message
248+
end
249+
250+
@connection.stub(:get_full_version, nil) do
251+
error = assert_raises(ActiveRecord::DatabaseVersionError) do
252+
@connection.get_database_version
253+
end
254+
assert_equal "Unable to parse MySQL version from nil", error.message
255+
end
256+
end
257+
219258
private
220259
def cause_server_side_disconnect
221260
@connection.update("set @@wait_timeout=1")

0 commit comments

Comments
 (0)