mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Refs #25367 -- Moved conditional expression wrapping to the Exact lookup.
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						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,11 +1222,6 @@ 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) | ||||
|             clause = self.where_class() | ||||
|             clause.add(condition, AND) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user