Skip to content

Commit 946fc17

Browse files
authored
Merge pull request rails#47851 from stevehill1981/fix-mysql-check-constraint-schema-dump
Correctly dump check constraints for MySQL 8.0.16+
2 parents c7f06b5 + ef14d13 commit 946fc17

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,8 @@ def check_constraints(table_name)
526526
name: row["name"]
527527
}
528528
expression = row["expression"]
529-
expression = expression[1..-2] unless mariadb? # remove parentheses added by mysql
529+
expression = expression[1..-2] if expression.start_with?("(") && expression.end_with?(")")
530+
expression = strip_whitespace_characters(expression)
530531
CheckConstraintDefinition.new(table_name, expression, options)
531532
end
532533
else
@@ -714,6 +715,12 @@ def extract_precision(sql_type)
714715
EMULATE_BOOLEANS_TRUE = { emulate_booleans: true }.freeze
715716

716717
private
718+
def strip_whitespace_characters(expression)
719+
expression = expression.gsub(/\\n|\\\\/, "")
720+
expression = expression.gsub(/\s{2,}/, " ")
721+
expression
722+
end
723+
717724
def text_type?(type)
718725
TYPE_MAP.lookup(type).is_a?(Type::String) || TYPE_MAP.lookup(type).is_a?(Type::Text)
719726
end

activerecord/test/cases/migration/check_constraint_test.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,21 @@ class Trade < ActiveRecord::Base
2323
t.integer :price
2424
t.integer :quantity
2525
end
26+
27+
if current_adapter?(:Mysql2Adapter)
28+
@connection.create_table "constraint_test", force: true do |t|
29+
t.json :options, default: nil
30+
end
31+
end
2632
end
2733

2834
teardown do
2935
@connection.drop_table "trades", if_exists: true rescue nil
3036
@connection.drop_table "purchases", if_exists: true rescue nil
37+
38+
if current_adapter?(:Mysql2Adapter)
39+
@connection.drop_table "constraint_test", if_exists: true rescue nil
40+
end
3141
end
3242

3343
def test_check_constraints
@@ -44,6 +54,28 @@ def test_check_constraints
4454
assert_equal "price > discounted_price", constraint.expression
4555
end
4656

57+
if current_adapter?(:Mysql2Adapter)
58+
begin
59+
@connection.add_check_constraint(:constraint_test, <<~SQL,
60+
json_contains('
61+
{
62+
"a": 1,
63+
"b": 2,
64+
"c": {
65+
"d": 4
66+
}
67+
}
68+
', options)
69+
SQL
70+
name: "non_empty_test_array")
71+
72+
constraint = @connection.check_constraints("constraint_test").find { |c| c.name == "non_empty_test_array" }
73+
assert_includes constraint.expression, "json_contains"
74+
ensure
75+
@connection.remove_check_constraint(:constraint_test, name: "non_empty_test_array", if_exists: true)
76+
end
77+
end
78+
4779
if current_adapter?(:PostgreSQLAdapter)
4880
begin
4981
# Test that complex expression is correctly parsed from the database

0 commit comments

Comments
 (0)