Fix single quote escapes on default generated MySQL columns

MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression. This commit fixes the escaping of the default value for such expressions if a single quote is included.

See the following for more: https://dev.mysql.com/blog-archive/generated-columns-in-mysql-5-7-5/
This commit is contained in:
Yash Kapadia 2024-01-12 16:18:48 -05:00
parent 2fb05958a6
commit 0702c24e7b
4 changed files with 21 additions and 0 deletions

View File

@ -1,3 +1,15 @@
* Fix single quote escapes on default generated MySQL columns
MySQL 5.7.5+ supports generated columns, which can be used to create a column that is computed from an expression.
Previously, the schema dump would output a string with double escapes for generated columns with single quotes in the default expression.
This would result in issues when importing the schema on a fresh instance of a MySQL database.
Now, the string will not be escaped and will be valid Ruby upon importing of the schema.
*Yash Kapadia*
* Fix Migrations with versions older than 7.1 validating options given to
`add_reference` and `t.references`.

View File

@ -185,6 +185,7 @@ module ActiveRecord
default, default_function = nil, default
elsif type_metadata.extra == "DEFAULT_GENERATED"
default = +"(#{default})" unless default.start_with?("(")
default = default.gsub("\\'", "'")
default, default_function = nil, default
elsif type_metadata.type == :text && default&.start_with?("'")
# strip and unescape quotes

View File

@ -175,6 +175,13 @@ class MysqlDefaultExpressionTest < ActiveRecord::TestCase
output = dump_table_schema("defaults")
assert_match %r/t\.binary\s+"uuid",\s+limit: 36,\s+default: -> { "\(?uuid\(\)\)?" }/i, output
end
if current_adapter?(:Mysql2Adapter)
test "schema dump includes default expression with single quotes reflected correctly" do
output = dump_table_schema("defaults")
assert_match %r/t\.string\s+"char2_concatenated",\s+default: -> { "\(?concat\(`char2`,(_utf8mb4)?'-'\)\)?" }/i, output
end
end
end
if supports_datetime_with_precision?

View File

@ -23,6 +23,7 @@ ActiveRecord::Schema.define do
t.string :char2, limit: 50, default: "a varchar field"
if ActiveRecord::TestCase.supports_default_expression?
t.binary :uuid, limit: 36, default: -> { "(uuid())" }
t.string :char2_concatenated, default: -> { "(concat(`char2`, '-'))" }
end
end