Refs #25367 -- Moved conditional expression wrapping to the Exact lookup.
This commit is contained in:
parent
306b687520
commit
37e6c5b79b
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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, []
|
||||
|
|
Loading…
Reference in New Issue