Used AND, OR, XOR constants instead of hard-coded values.

This commit is contained in:
Nick Pope 2022-07-23 13:31:35 +01:00 committed by Mariusz Felisiak
parent e20e5d1557
commit 769d7cce4a
6 changed files with 20 additions and 18 deletions

View File

@ -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

View File

@ -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:

View File

@ -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"))

View File

@ -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)",
)

View File

@ -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)

View File

@ -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