diff options
| author | Lucidiot <lucidiot@brainshit.fr> | 2021-06-17 21:54:08 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-06-22 06:09:16 +0200 |
| commit | b69b0c3fe871167a0ca01bb439508e335143801f (patch) | |
| tree | b20fedc0b3f7c0974fc7360395c44f529f3aa48a | |
| parent | 501a3714114b9c72e7dc4d8add76663bb8c83e3a (diff) | |
Fixed #32858 -- Fixed ExclusionConstraint crash with index transforms in expressions.
| -rw-r--r-- | AUTHORS | 1 | ||||
| -rw-r--r-- | django/contrib/postgres/constraints.py | 3 | ||||
| -rw-r--r-- | tests/postgres_tests/test_constraints.py | 17 |
3 files changed, 20 insertions, 1 deletions
@@ -561,6 +561,7 @@ answer newbie questions, and generally made Django that much better: Luan Pablo <luanpab@gmail.com> Lucas Connors <https://www.revolutiontech.ca/> Luciano Ramalho + Lucidiot <lucidiot@brainshit.fr> Ludvig Ericson <ludvig.ericson@gmail.com> Luis C. Berrocal <luis.berrocal.1942@gmail.com> Ćukasz Langa <lukasz@langa.pl> diff --git a/django/contrib/postgres/constraints.py b/django/contrib/postgres/constraints.py index 48dfd2bbc0..ddc9d23df9 100644 --- a/django/contrib/postgres/constraints.py +++ b/django/contrib/postgres/constraints.py @@ -2,6 +2,7 @@ from django.db import NotSupportedError from django.db.backends.ddl_references import Statement, Table from django.db.models import Deferrable, F, Q from django.db.models.constraints import BaseConstraint +from django.db.models.expressions import Col from django.db.models.sql import Query __all__ = ['ExclusionConstraint'] @@ -73,6 +74,8 @@ class ExclusionConstraint(BaseConstraint): expression = F(expression) expression = expression.resolve_expression(query=query) sql, params = compiler.compile(expression) + if not isinstance(expression, Col): + sql = f'({sql})' try: opclass = self.opclasses[idx] if opclass: diff --git a/tests/postgres_tests/test_constraints.py b/tests/postgres_tests/test_constraints.py index 7915bb226e..65402bd429 100644 --- a/tests/postgres_tests/test_constraints.py +++ b/tests/postgres_tests/test_constraints.py @@ -14,7 +14,9 @@ from django.test import modify_settings, skipUnlessDBFeature from django.utils import timezone from . import PostgreSQLTestCase -from .models import HotelReservation, RangesModel, Room, Scene +from .models import ( + HotelReservation, IntegerArrayModel, RangesModel, Room, Scene, +) try: from psycopg2.extras import DateRange, NumericRange @@ -670,6 +672,19 @@ class ExclusionConstraintTests(PostgreSQLTestCase): self.get_constraints(HotelReservation._meta.db_table), ) + def test_index_transform(self): + constraint_name = 'first_index_equal' + constraint = ExclusionConstraint( + name=constraint_name, + expressions=[('field__0', RangeOperators.EQUAL)], + ) + with connection.schema_editor() as editor: + editor.add_constraint(IntegerArrayModel, constraint) + self.assertIn( + constraint_name, + self.get_constraints(IntegerArrayModel._meta.db_table), + ) + def test_range_adjacent_initially_deferred(self): constraint_name = 'ints_adjacent_deferred' self.assertNotIn(constraint_name, self.get_constraints(RangesModel._meta.db_table)) |
