summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2019-11-14 23:28:34 -0500
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-11-21 11:56:35 +0100
commit37e6c5b79bd0529a3c85b8c478e4002fd33a2a1d (patch)
tree8381d4425204c73b5078130eb1fbd904942fe130
parent306b6875209cfedce2536a6679e69adee7c9bc6a (diff)
Refs #25367 -- Moved conditional expression wrapping to the Exact lookup.
-rw-r--r--django/db/backends/oracle/operations.py8
-rw-r--r--django/db/models/lookups.py14
-rw-r--r--django/db/models/sql/query.py7
3 files changed, 19 insertions, 10 deletions
diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py
index c44f2a9cee..493854ce04 100644
--- a/django/db/backends/oracle/operations.py
+++ b/django/db/backends/oracle/operations.py
@@ -6,7 +6,7 @@ from django.conf import settings
from django.db.backends.base.operations import BaseDatabaseOperations
from django.db.backends.utils import strip_quotes, truncate_name
from django.db.models.expressions import Exists, ExpressionWrapper, RawSQL
-from django.db.models.query_utils import Q
+from django.db.models.sql.where import WhereNode
from django.db.utils import DatabaseError
from django.utils import timezone
from django.utils.encoding import force_bytes, force_str
@@ -633,10 +633,10 @@ END;
Oracle supports only EXISTS(...) or filters in the WHERE clause, others
must be compared with True.
"""
- if isinstance(expression, Exists):
- return True
- if isinstance(expression, ExpressionWrapper) and isinstance(expression.expression, Q):
+ if isinstance(expression, (Exists, WhereNode)):
return True
+ if isinstance(expression, ExpressionWrapper) and expression.conditional:
+ return self.conditional_expression_supported_in_where_clause(expression.expression)
if isinstance(expression, RawSQL) and expression.conditional:
return True
return False
diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py
index 4b41906966..59e1b7211b 100644
--- a/django/db/models/lookups.py
+++ b/django/db/models/lookups.py
@@ -274,6 +274,20 @@ class Exact(FieldGetDbPrepValueMixin, BuiltinLookup):
)
return super().process_rhs(compiler, connection)
+ def as_sql(self, compiler, connection):
+ # Avoid comparison against direct rhs if lhs is a boolean value. That
+ # turns "boolfield__exact=True" into "WHERE boolean_field" instead of
+ # "WHERE boolean_field = True" when allowed.
+ if (
+ isinstance(self.rhs, bool) and
+ getattr(self.lhs, 'conditional', False) and
+ connection.ops.conditional_expression_supported_in_where_clause(self.lhs)
+ ):
+ lhs_sql, params = self.process_lhs(compiler, connection)
+ template = '%s' if self.rhs else 'NOT %s'
+ return template % lhs_sql, params
+ return super().as_sql(compiler, connection)
+
@Field.register_lookup
class IExact(BuiltinLookup):
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index e6803649e7..f14859fda1 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1222,12 +1222,7 @@ class Query(BaseExpression):
if isinstance(filter_expr, dict):
raise FieldError("Cannot parse keyword query as dict")
if hasattr(filter_expr, 'resolve_expression') and getattr(filter_expr, 'conditional', False):
- if connections[DEFAULT_DB_ALIAS].ops.conditional_expression_supported_in_where_clause(filter_expr):
- condition = filter_expr.resolve_expression(self)
- else:
- # Expression is not supported in the WHERE clause, add
- # comparison with True.
- condition = self.build_lookup(['exact'], filter_expr.resolve_expression(self), True)
+ condition = self.build_lookup(['exact'], filter_expr.resolve_expression(self), True)
clause = self.where_class()
clause.add(condition, AND)
return clause, []