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:
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.base.operations import BaseDatabaseOperations
|
||||||
from django.db.backends.utils import strip_quotes, truncate_name
|
from django.db.backends.utils import strip_quotes, truncate_name
|
||||||
from django.db.models.expressions import Exists, ExpressionWrapper, RawSQL
|
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.db.utils import DatabaseError
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.encoding import force_bytes, force_str
|
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
|
Oracle supports only EXISTS(...) or filters in the WHERE clause, others
|
||||||
must be compared with True.
|
must be compared with True.
|
||||||
"""
|
"""
|
||||||
if isinstance(expression, Exists):
|
if isinstance(expression, (Exists, WhereNode)):
|
||||||
return True
|
|
||||||
if isinstance(expression, ExpressionWrapper) and isinstance(expression.expression, Q):
|
|
||||||
return True
|
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:
|
if isinstance(expression, RawSQL) and expression.conditional:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -274,6 +274,20 @@ class Exact(FieldGetDbPrepValueMixin, BuiltinLookup):
|
|||||||
)
|
)
|
||||||
return super().process_rhs(compiler, connection)
|
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
|
@Field.register_lookup
|
||||||
class IExact(BuiltinLookup):
|
class IExact(BuiltinLookup):
|
||||||
|
@ -1222,12 +1222,7 @@ class Query(BaseExpression):
|
|||||||
if isinstance(filter_expr, dict):
|
if isinstance(filter_expr, dict):
|
||||||
raise FieldError("Cannot parse keyword query as dict")
|
raise FieldError("Cannot parse keyword query as dict")
|
||||||
if hasattr(filter_expr, 'resolve_expression') and getattr(filter_expr, 'conditional', False):
|
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 = self.build_lookup(['exact'], filter_expr.resolve_expression(self), True)
|
||||||
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)
|
|
||||||
clause = self.where_class()
|
clause = self.where_class()
|
||||||
clause.add(condition, AND)
|
clause.add(condition, AND)
|
||||||
return clause, []
|
return clause, []
|
||||||
|
Loading…
Reference in New Issue
Block a user