Refs #34320 -- Stopped recreating check constraints when renaming fields.

This also fixes test_rename_field_with_check_to_truncated_name() on
MariaDB 10.5.2+ as ALTER TABLE ... RENAME COLUMN statement doesn't
rename inline constraints.
This commit is contained in:
Mariusz Felisiak 2023-03-02 06:05:40 +01:00 committed by GitHub
parent ef00d6ef88
commit 9953c804a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 2 deletions

View File

@ -838,6 +838,17 @@ class BaseDatabaseSchemaEditor:
strict,
)
def _field_db_check(self, field, field_db_params):
# Always check constraints with the same mocked column name to avoid
# recreating constrains when the column is renamed.
check_constraints = self.connection.data_type_check_constraints
data = field.db_type_parameters(self.connection)
data["column"] = "__column_name__"
try:
return check_constraints[field.get_internal_type()] % data
except KeyError:
return None
def _alter_field(
self,
model,
@ -956,7 +967,9 @@ class BaseDatabaseSchemaEditor:
# is to look at its name (refs #28053).
self.execute(self._delete_index_sql(model, index_name))
# Change check constraints?
if old_db_params["check"] != new_db_params["check"] and old_db_params["check"]:
old_db_check = self._field_db_check(old_field, old_db_params)
new_db_check = self._field_db_check(new_field, new_db_params)
if old_db_check != new_db_check and old_db_check:
meta_constraint_names = {
constraint.name for constraint in model._meta.constraints
}
@ -1162,7 +1175,7 @@ class BaseDatabaseSchemaEditor:
self._create_fk_sql(rel.related_model, rel.field, "_fk")
)
# Does it have check constraints we need to add?
if old_db_params["check"] != new_db_params["check"] and new_db_params["check"]:
if old_db_check != new_db_check and new_db_check:
constraint_name = self._create_index_name(
model._meta.db_table, [new_field.column], suffix="_check"
)

View File

@ -230,6 +230,19 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
model, old_field, new_field, new_type, old_collation, new_collation
)
def _field_db_check(self, field, field_db_params):
if self.connection.mysql_is_mariadb and self.connection.mysql_version >= (
10,
5,
2,
):
return super()._field_db_check(field, field_db_params)
# On MySQL and MariaDB < 10.5.2 (no support for
# "ALTER TABLE ... RENAME COLUMN" statements), check constraints with
# the column name as it requires explicit recreation when the column is
# renamed.
return field_db_params["check"]
def _rename_field_sql(self, table, old_field, new_field, new_type):
new_type = self._set_field_new_type_null_status(old_field, new_type)
return super()._rename_field_sql(table, old_field, new_field, new_type)