summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucidiot <lucidiot@brainshit.fr>2021-06-17 21:54:08 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-06-22 06:09:16 +0200
commitb69b0c3fe871167a0ca01bb439508e335143801f (patch)
treeb20fedc0b3f7c0974fc7360395c44f529f3aa48a
parent501a3714114b9c72e7dc4d8add76663bb8c83e3a (diff)
Fixed #32858 -- Fixed ExclusionConstraint crash with index transforms in expressions.
-rw-r--r--AUTHORS1
-rw-r--r--django/contrib/postgres/constraints.py3
-rw-r--r--tests/postgres_tests/test_constraints.py17
3 files changed, 20 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index ef1e4ea095..84cbf17c27 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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))