Merge pull request #41788 from pbstriker38/check_table_name_constraint_mariadb

Add support for check_constraints with the same name on different tables
This commit is contained in:
Ryuta Kamizono 2021-04-07 09:16:59 +09:00 committed by GitHub
commit bc488431ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 1 deletions

View File

@ -427,7 +427,7 @@ module ActiveRecord
if supports_check_constraints?
scope = quoted_scope(table_name)
chk_info = exec_query(<<~SQL, "SCHEMA")
sql = <<~SQL
SELECT cc.constraint_name AS 'name',
cc.check_clause AS 'expression'
FROM information_schema.check_constraints cc
@ -437,6 +437,9 @@ module ActiveRecord
AND tc.table_name = #{scope[:name]}
AND cc.constraint_schema = #{scope[:schema]}
SQL
sql += " AND cc.table_name = #{scope[:name]}" if mariadb?
chk_info = exec_query(sql, "SCHEMA")
chk_info.map do |row|
options = {

View File

@ -54,6 +54,15 @@ def supports_default_expression?
end
end
def supports_non_unique_constraint_name?
if current_adapter?(:Mysql2Adapter)
conn = ActiveRecord::Base.connection
conn.mariadb?
else
false
end
end
%w[
supports_savepoints?
supports_partial_index?

View File

@ -18,10 +18,16 @@ if ActiveRecord::Base.connection.supports_check_constraints?
t.integer :price
t.integer :quantity
end
@connection.create_table "purchases", force: true do |t|
t.integer :price
t.integer :quantity
end
end
teardown do
@connection.drop_table "trades", if_exists: true rescue nil
@connection.drop_table "purchases", if_exists: true rescue nil
end
def test_check_constraints
@ -56,6 +62,25 @@ if ActiveRecord::Base.connection.supports_check_constraints?
end
end
if supports_non_unique_constraint_name?
def test_add_constraint_with_same_name_to_different_table
@connection.add_check_constraint :trades, "quantity > 0", name: "greater_than_zero"
@connection.add_check_constraint :purchases, "quantity > 0", name: "greater_than_zero"
trades_check_constraints = @connection.check_constraints("trades")
assert_equal 1, trades_check_constraints.size
trade_constraint = trades_check_constraints.first
assert_equal "trades", trade_constraint.table_name
assert_equal "greater_than_zero", trade_constraint.name
purchases_check_constraints = @connection.check_constraints("purchases")
assert_equal 1, purchases_check_constraints.size
purchase_constraint = purchases_check_constraints.first
assert_equal "purchases", purchase_constraint.table_name
assert_equal "greater_than_zero", purchase_constraint.name
end
end
def test_add_check_constraint_with_non_existent_table_raises
e = assert_raises(ActiveRecord::StatementInvalid) do
@connection.add_check_constraint :refunds, "quantity > 0", name: "quantity_check"