1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Refs #25367 -- Moved conditional expression wrapping to the Exact lookup.

This commit is contained in:
Simon Charette 2019-11-14 23:28:34 -05:00 committed by Mariusz Felisiak
parent 306b687520
commit 37e6c5b79b
3 changed files with 19 additions and 10 deletions

View File

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

View File

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

View File

@ -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, []