summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcan <cansarigol@derinbilgi.com.tr>2019-04-30 11:20:41 +0300
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-04-30 13:43:02 +0200
commit58391b4d164ac83b8001a2ec70f3b1e4d39e4681 (patch)
tree21f48cddd339198f73735d167729e46edc18e0e4
parent54fcdf168ab1f53fbdb7cd63f916bd44845a78d3 (diff)
[2.2.x] Fixed #30412 -- Fixed crash when adding check constraints with OR'ed condition on Oracle and SQLite.
Backport of 719b7466203181066d9537d2e3bec687dffc9f41 from master
-rw-r--r--django/db/models/sql/query.py2
-rw-r--r--docs/releases/2.2.1.txt3
-rw-r--r--tests/migrations/test_operations.py23
-rw-r--r--tests/queries/test_query.py15
4 files changed, 42 insertions, 1 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index ffa8db86f2..b99f0e90ef 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1309,7 +1309,7 @@ class Query:
if isinstance(child, Node):
child_clause, needed_inner = self._add_q(
child, used_aliases, branch_negated,
- current_negated, allow_joins, split_subq)
+ current_negated, allow_joins, split_subq, simple_col)
joinpromoter.add_votes(needed_inner)
else:
child_clause, needed_inner = self.build_filter(
diff --git a/docs/releases/2.2.1.txt b/docs/releases/2.2.1.txt
index 90c9a06e79..38e8052b7d 100644
--- a/docs/releases/2.2.1.txt
+++ b/docs/releases/2.2.1.txt
@@ -74,3 +74,6 @@ Bugfixes
* Fixed a migration crash on Oracle and PostgreSQL when adding a check
constraint with a ``contains``, ``startswith``, or ``endswith`` lookup (or
their case-insensitive variant) (:ticket:`30408`).
+
+* Fixed a migration crash on Oracle and SQLite when adding a check constraint
+ with ``condition`` contains ``|`` (``OR``) operator (:ticket:`30412`).
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py
index 520a2b2204..3b2129a933 100644
--- a/tests/migrations/test_operations.py
+++ b/tests/migrations/test_operations.py
@@ -1899,6 +1899,29 @@ class OperationTests(OperationTestBase):
self.assertEqual(Author.objects.get(), author)
@skipUnlessDBFeature('supports_table_check_constraints')
+ def test_add_or_constraint(self):
+ app_label = 'test_addorconstraint'
+ constraint_name = 'add_constraint_or'
+ from_state = self.set_up_test_model(app_label)
+ check = models.Q(pink__gt=2, weight__gt=2) | models.Q(weight__lt=0)
+ constraint = models.CheckConstraint(check=check, name=constraint_name)
+ operation = migrations.AddConstraint('Pony', constraint)
+ to_state = from_state.clone()
+ operation.state_forwards(app_label, to_state)
+ with connection.schema_editor() as editor:
+ operation.database_forwards(app_label, editor, from_state, to_state)
+ Pony = to_state.apps.get_model(app_label, 'Pony')
+ with self.assertRaises(IntegrityError), transaction.atomic():
+ Pony.objects.create(pink=2, weight=3.0)
+ with self.assertRaises(IntegrityError), transaction.atomic():
+ Pony.objects.create(pink=3, weight=1.0)
+ Pony.objects.bulk_create([
+ Pony(pink=3, weight=-1.0),
+ Pony(pink=1, weight=-1.0),
+ Pony(pink=3, weight=3.0),
+ ])
+
+ @skipUnlessDBFeature('supports_table_check_constraints')
def test_remove_constraint(self):
project_state = self.set_up_test_model("test_removeconstraint", constraints=[
models.CheckConstraint(check=models.Q(pink__gt=2), name="test_remove_constraint_pony_pink_gt_2"),
diff --git a/tests/queries/test_query.py b/tests/queries/test_query.py
index bef79c992e..c6a659fe97 100644
--- a/tests/queries/test_query.py
+++ b/tests/queries/test_query.py
@@ -23,6 +23,21 @@ class TestQuery(SimpleTestCase):
self.assertEqual(lookup.rhs, 2)
self.assertEqual(lookup.lhs.target, Author._meta.get_field('num'))
+ def test_simplecol_query(self):
+ query = Query(Author)
+ where = query.build_where(Q(num__gt=2, name__isnull=False) | Q(num__lt=F('id')))
+
+ name_isnull_lookup, num_gt_lookup = where.children[0].children
+ self.assertIsInstance(num_gt_lookup, GreaterThan)
+ self.assertIsInstance(num_gt_lookup.lhs, SimpleCol)
+ self.assertIsInstance(name_isnull_lookup, IsNull)
+ self.assertIsInstance(name_isnull_lookup.lhs, SimpleCol)
+
+ num_lt_lookup = where.children[1]
+ self.assertIsInstance(num_lt_lookup, LessThan)
+ self.assertIsInstance(num_lt_lookup.rhs, SimpleCol)
+ self.assertIsInstance(num_lt_lookup.lhs, SimpleCol)
+
def test_complex_query(self):
query = Query(Author)
where = query.build_where(Q(num__gt=2) | Q(num__lt=0))