summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHasan Ramezani <hasan.r67@gmail.com>2019-07-30 16:21:05 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-07-30 16:32:13 +0200
commite3fc9af4abd65262f2d3bdced96b687b65be618a (patch)
treea136c11065b41a32796443a1954c5775accc2fc3
parentb2aad9ad4d35ee3bb448ba698b8c56bb972bdd8a (diff)
Refs #30593 -- Fixed introspection of check constraints columns on MariaDB.
-rw-r--r--django/db/backends/mysql/introspection.py11
-rw-r--r--tests/backends/mysql/test_introspection.py17
2 files changed, 20 insertions, 8 deletions
diff --git a/django/db/backends/mysql/introspection.py b/django/db/backends/mysql/introspection.py
index 86133a254e..db1a387679 100644
--- a/django/db/backends/mysql/introspection.py
+++ b/django/db/backends/mysql/introspection.py
@@ -147,12 +147,16 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
return self.connection.features._mysql_storage_engine
return result[0]
- def _parse_constraint_columns(self, check_clause):
+ def _parse_constraint_columns(self, check_clause, columns):
check_columns = OrderedSet()
statement = sqlparse.parse(check_clause)[0]
tokens = (token for token in statement.flatten() if not token.is_whitespace)
for token in tokens:
- if token.ttype in [sqlparse.tokens.Name, sqlparse.tokens.Literal.String.Single]:
+ if (
+ token.ttype == sqlparse.tokens.Name and
+ self.connection.ops.quote_name(token.value) == token.value and
+ token.value[1:-1] in columns
+ ):
check_columns.add(token.value[1:-1])
return check_columns
@@ -201,6 +205,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
constraints[constraint]['unique'] = True
# Add check constraints.
if self.connection.features.can_introspect_check_constraints:
+ columns = {info.name for info in self.get_table_description(cursor, table_name)}
type_query = """
SELECT c.constraint_name, c.check_clause
FROM information_schema.check_constraints AS c
@@ -211,7 +216,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
cursor.execute(type_query, [table_name])
for constraint, check_clause in cursor.fetchall():
constraints[constraint] = {
- 'columns': self._parse_constraint_columns(check_clause),
+ 'columns': self._parse_constraint_columns(check_clause, columns),
'primary_key': False,
'unique': False,
'index': False,
diff --git a/tests/backends/mysql/test_introspection.py b/tests/backends/mysql/test_introspection.py
index 1b8fb94ed9..37fbcb1513 100644
--- a/tests/backends/mysql/test_introspection.py
+++ b/tests/backends/mysql/test_introspection.py
@@ -7,16 +7,23 @@ from django.test import TestCase
@skipUnless(connection.vendor == 'mysql', 'MySQL tests')
class ParsingTests(TestCase):
def test_parse_constraint_columns(self):
+ _parse_constraint_columns = connection.introspection._parse_constraint_columns
tests = (
- ('`height` >= 0', ['height']),
- ('`cost` BETWEEN 1 AND 10', ['cost']),
- ('`ref1` > `ref2`', ['ref1', 'ref2']),
+ ('`height` >= 0', ['height'], ['height']),
+ ('`cost` BETWEEN 1 AND 10', ['cost'], ['cost']),
+ ('`ref1` > `ref2`', ['id', 'ref1', 'ref2'], ['ref1', 'ref2']),
(
'`start` IS NULL OR `end` IS NULL OR `start` < `end`',
+ ['id', 'start', 'end'],
['start', 'end'],
),
+ ('JSON_VALID(`json_field`)', ['json_field'], ['json_field']),
+ ('CHAR_LENGTH(`name`) > 2', ['name'], ['name']),
+ ("lower(`ref1`) != 'test'", ['id', 'owe', 'ref1'], ['ref1']),
+ ("lower(`ref1`) != 'test'", ['id', 'lower', 'ref1'], ['ref1']),
+ ("`name` LIKE 'test%'", ['name'], ['name']),
)
- for check_clause, expected_columns in tests:
+ for check_clause, table_columns, expected_columns in tests:
with self.subTest(check_clause):
- check_columns = connection.introspection._parse_constraint_columns(check_clause)
+ check_columns = _parse_constraint_columns(check_clause, table_columns)
self.assertEqual(list(check_columns), expected_columns)