Refs #30591 -- Fixed introspection of check and unique column constraints on MariaDB.

Unnamed unique and check columns constraints have the same name as
a column. Ensure uniqueness by using custom names.

Thanks Adnan Umer for the report.
This commit is contained in:
Mariusz Felisiak 2019-08-26 09:15:37 +02:00 committed by GitHub
parent d0861fcb2d
commit 579909a13f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 1 deletions

View File

@ -207,6 +207,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
constraints[constraint]['unique'] = True constraints[constraint]['unique'] = True
# Add check constraints. # Add check constraints.
if self.connection.features.can_introspect_check_constraints: if self.connection.features.can_introspect_check_constraints:
unnamed_constraints_index = 0
columns = {info.name for info in self.get_table_description(cursor, table_name)} columns = {info.name for info in self.get_table_description(cursor, table_name)}
type_query = """ type_query = """
SELECT c.constraint_name, c.check_clause SELECT c.constraint_name, c.check_clause
@ -217,8 +218,15 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
""" """
cursor.execute(type_query, [table_name]) cursor.execute(type_query, [table_name])
for constraint, check_clause in cursor.fetchall(): for constraint, check_clause in cursor.fetchall():
constraint_columns = self._parse_constraint_columns(check_clause, columns)
# Ensure uniqueness of unnamed constraints. Unnamed unique
# and check columns constraints have the same name as
# a column.
if set(constraint_columns) == {constraint}:
unnamed_constraints_index += 1
constraint = '__unnamed_constraint_%s__' % unnamed_constraints_index
constraints[constraint] = { constraints[constraint] = {
'columns': self._parse_constraint_columns(check_clause, columns), 'columns': constraint_columns,
'primary_key': False, 'primary_key': False,
'unique': False, 'unique': False,
'index': False, 'index': False,

View File

@ -83,6 +83,7 @@ class Comment(models.Model):
class CheckConstraintModel(models.Model): class CheckConstraintModel(models.Model):
up_votes = models.PositiveIntegerField() up_votes = models.PositiveIntegerField()
voting_number = models.PositiveIntegerField(unique=True)
class Meta: class Meta:
required_db_features = { required_db_features = {

View File

@ -268,9 +268,15 @@ class IntrospectionTests(TransactionTestCase):
elif details['columns'] == ['up_votes'] and details['check']: elif details['columns'] == ['up_votes'] and details['check']:
assertDetails(details, ['up_votes'], check=True) assertDetails(details, ['up_votes'], check=True)
field_constraints.add(name) field_constraints.add(name)
elif details['columns'] == ['voting_number'] and details['check']:
assertDetails(details, ['voting_number'], check=True)
field_constraints.add(name)
elif details['columns'] == ['ref'] and details['unique']: elif details['columns'] == ['ref'] and details['unique']:
assertDetails(details, ['ref'], unique=True) assertDetails(details, ['ref'], unique=True)
field_constraints.add(name) field_constraints.add(name)
elif details['columns'] == ['voting_number'] and details['unique']:
assertDetails(details, ['voting_number'], unique=True)
field_constraints.add(name)
elif details['columns'] == ['article_id'] and details['index']: elif details['columns'] == ['article_id'] and details['index']:
assertDetails(details, ['article_id'], index=True) assertDetails(details, ['article_id'], index=True)
field_constraints.add(name) field_constraints.add(name)