From 769d7cce4aedfcbba59f1b68577225d07701c206 Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Sat, 23 Jul 2022 13:31:35 +0100 Subject: [PATCH] Used AND, OR, XOR constants instead of hard-coded values. --- django/db/models/sql/compiler.py | 3 ++- django/db/models/sql/query.py | 6 +++--- tests/queries/test_q.py | 4 ++-- tests/queries/test_query.py | 4 ++-- tests/queries/tests.py | 14 +++++++------- tests/utils_tests/test_tree.py | 7 ++++--- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 461e1ae156..cfac22a019 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -19,6 +19,7 @@ from django.db.models.sql.constants import ( SINGLE, ) from django.db.models.sql.query import Query, get_order_dir +from django.db.models.sql.where import AND from django.db.transaction import TransactionManagementError from django.utils.functional import cached_property from django.utils.hashable import make_hashable @@ -1435,7 +1436,7 @@ class SQLCompiler: for index, select_col in enumerate(self.query.select): lhs_sql, lhs_params = self.compile(select_col) rhs = "%s.%s" % (qn(alias), qn2(columns[index])) - self.query.where.add(RawSQL("%s = %s" % (lhs_sql, rhs), lhs_params), "AND") + self.query.where.add(RawSQL("%s = %s" % (lhs_sql, rhs), lhs_params), AND) sql, params = self.as_sql() return "EXISTS (%s)" % sql, params diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index cf7566d771..14ed0c0a63 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -2658,7 +2658,7 @@ class JoinPromoter: # to rel_a would remove a valid match from the query. So, we need # to promote any existing INNER to LOUTER (it is possible this # promotion in turn will be demoted later on). - if self.effective_connector == "OR" and votes < self.num_children: + if self.effective_connector == OR and votes < self.num_children: to_promote.add(table) # If connector is AND and there is a filter that can match only # when there is a joinable row, then use INNER. For example, in @@ -2670,8 +2670,8 @@ class JoinPromoter: # (rel_a__col__icontains=Alex | rel_a__col__icontains=Russell) # then if rel_a doesn't produce any rows, the whole condition # can't match. Hence we can safely use INNER join. - if self.effective_connector == "AND" or ( - self.effective_connector == "OR" and votes == self.num_children + if self.effective_connector == AND or ( + self.effective_connector == OR and votes == self.num_children ): to_demote.add(table) # Finally, what happens in cases where we have: diff --git a/tests/queries/test_q.py b/tests/queries/test_q.py index 4801eb4807..289305d33f 100644 --- a/tests/queries/test_q.py +++ b/tests/queries/test_q.py @@ -114,7 +114,7 @@ class QTests(SimpleTestCase): ("price", F("discounted_price")), ), ) - self.assertEqual(kwargs, {"_connector": "OR"}) + self.assertEqual(kwargs, {"_connector": Q.OR}) def test_deconstruct_xor(self): q1 = Q(price__gt=F("discounted_price")) @@ -128,7 +128,7 @@ class QTests(SimpleTestCase): ("price", F("discounted_price")), ), ) - self.assertEqual(kwargs, {"_connector": "XOR"}) + self.assertEqual(kwargs, {"_connector": Q.XOR}) def test_deconstruct_and(self): q1 = Q(price__gt=F("discounted_price")) diff --git a/tests/queries/test_query.py b/tests/queries/test_query.py index 9884116cd0..b0a5058f6c 100644 --- a/tests/queries/test_query.py +++ b/tests/queries/test_query.py @@ -16,7 +16,7 @@ from django.db.models.functions import Lower from django.db.models.lookups import Exact, GreaterThan, IsNull, LessThan from django.db.models.sql.constants import SINGLE from django.db.models.sql.query import JoinPromoter, Query, get_field_names_from_opts -from django.db.models.sql.where import OR +from django.db.models.sql.where import AND, OR from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature from django.test.utils import register_lookup @@ -214,6 +214,6 @@ class TestQueryNoModel(TestCase): class JoinPromoterTest(SimpleTestCase): def test_repr(self): self.assertEqual( - repr(JoinPromoter("AND", 3, True)), + repr(JoinPromoter(AND, 3, True)), "JoinPromoter(connector='AND', num_children=3, negated=True)", ) diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 00213f0dfc..1238f021be 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -10,7 +10,7 @@ from django.db import DEFAULT_DB_ALIAS, connection from django.db.models import Count, Exists, F, Max, OuterRef, Q from django.db.models.expressions import RawSQL from django.db.models.sql.constants import LOUTER -from django.db.models.sql.where import NothingNode, WhereNode +from django.db.models.sql.where import AND, OR, NothingNode, WhereNode from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature from django.test.utils import CaptureQueriesContext, ignore_warnings from django.utils.deprecation import RemovedInDjango50Warning @@ -3559,16 +3559,16 @@ class WhereNodeTest(SimpleTestCase): def test_empty_full_handling_disjunction(self): compiler = WhereNodeTest.MockCompiler() - w = WhereNode(children=[NothingNode()], connector="OR") + w = WhereNode(children=[NothingNode()], connector=OR) with self.assertRaises(EmptyResultSet): w.as_sql(compiler, connection) w.negate() self.assertEqual(w.as_sql(compiler, connection), ("", [])) - w = WhereNode(children=[self.DummyNode(), self.DummyNode()], connector="OR") + w = WhereNode(children=[self.DummyNode(), self.DummyNode()], connector=OR) self.assertEqual(w.as_sql(compiler, connection), ("(dummy OR dummy)", [])) w.negate() self.assertEqual(w.as_sql(compiler, connection), ("NOT (dummy OR dummy)", [])) - w = WhereNode(children=[NothingNode(), self.DummyNode()], connector="OR") + w = WhereNode(children=[NothingNode(), self.DummyNode()], connector=OR) self.assertEqual(w.as_sql(compiler, connection), ("dummy", [])) w.negate() self.assertEqual(w.as_sql(compiler, connection), ("NOT (dummy)", [])) @@ -3581,14 +3581,14 @@ class WhereNodeTest(SimpleTestCase): w.negate() with self.assertRaises(EmptyResultSet): w.as_sql(compiler, connection) - w.connector = "OR" + w.connector = OR with self.assertRaises(EmptyResultSet): w.as_sql(compiler, connection) w.negate() self.assertEqual(w.as_sql(compiler, connection), ("", [])) - w = WhereNode(children=[empty_w, NothingNode()], connector="OR") + w = WhereNode(children=[empty_w, NothingNode()], connector=OR) self.assertEqual(w.as_sql(compiler, connection), ("", [])) - w = WhereNode(children=[empty_w, NothingNode()], connector="AND") + w = WhereNode(children=[empty_w, NothingNode()], connector=AND) with self.assertRaises(EmptyResultSet): w.as_sql(compiler, connection) diff --git a/tests/utils_tests/test_tree.py b/tests/utils_tests/test_tree.py index fe59f778cd..fcc4c3147d 100644 --- a/tests/utils_tests/test_tree.py +++ b/tests/utils_tests/test_tree.py @@ -1,6 +1,7 @@ import copy import unittest +from django.db.models.sql import AND, OR from django.utils.tree import Node @@ -56,9 +57,9 @@ class NodeTests(unittest.TestCase): self.assertEqual(str(node3), "(DEFAULT: ('a', 1), ('b', 2), ('c', 3))") def test_add_eq_child_mixed_connector(self): - node = Node(["a", "b"], "OR") - self.assertEqual(node.add("a", "AND"), "a") - self.assertEqual(node, Node([Node(["a", "b"], "OR"), "a"], "AND")) + node = Node(["a", "b"], OR) + self.assertEqual(node.add("a", AND), "a") + self.assertEqual(node, Node([Node(["a", "b"], OR), "a"], AND)) def test_negate(self): # negated is False by default