summaryrefslogtreecommitdiff
path: root/tests/postgres_tests
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2019-07-10 10:33:36 +0200
committerGitHub <noreply@github.com>2019-07-10 10:33:36 +0200
commit7991111af12056ec9a856f35935d273526338c1f (patch)
tree4067b5171a44f6d559c6d44cda34338c75b73ecc /tests/postgres_tests
parentee6e93ec8727d0f5ed33190a3c354867669ed72f (diff)
Fixed #30621 -- Fixed crash of __contains lookup for Date/DateTimeRangeField when the right hand side is the same type.
Thanks Tilman Koschnick for the report and initial patch. Thanks Carlton Gibson the review. Regression in 6b048b364ca1e0e56a0d3815bf2be33ac9998355.
Diffstat (limited to 'tests/postgres_tests')
-rw-r--r--tests/postgres_tests/migrations/0002_create_test_models.py2
-rw-r--r--tests/postgres_tests/models.py2
-rw-r--r--tests/postgres_tests/test_constraints.py52
-rw-r--r--tests/postgres_tests/test_ranges.py10
4 files changed, 64 insertions, 2 deletions
diff --git a/tests/postgres_tests/migrations/0002_create_test_models.py b/tests/postgres_tests/migrations/0002_create_test_models.py
index dc941de139..b9f9cee6bf 100644
--- a/tests/postgres_tests/migrations/0002_create_test_models.py
+++ b/tests/postgres_tests/migrations/0002_create_test_models.py
@@ -211,7 +211,9 @@ class Migration(migrations.Migration):
('bigints', BigIntegerRangeField(null=True, blank=True)),
('decimals', DecimalRangeField(null=True, blank=True)),
('timestamps', DateTimeRangeField(null=True, blank=True)),
+ ('timestamps_inner', DateTimeRangeField(null=True, blank=True)),
('dates', DateRangeField(null=True, blank=True)),
+ ('dates_inner', DateRangeField(null=True, blank=True)),
],
options={
'required_db_vendor': 'postgresql'
diff --git a/tests/postgres_tests/models.py b/tests/postgres_tests/models.py
index 2bb6e6fcdf..3d170a9a1a 100644
--- a/tests/postgres_tests/models.py
+++ b/tests/postgres_tests/models.py
@@ -135,7 +135,9 @@ class RangesModel(PostgreSQLModel):
bigints = BigIntegerRangeField(blank=True, null=True)
decimals = DecimalRangeField(blank=True, null=True)
timestamps = DateTimeRangeField(blank=True, null=True)
+ timestamps_inner = DateTimeRangeField(blank=True, null=True)
dates = DateRangeField(blank=True, null=True)
+ dates_inner = DateRangeField(blank=True, null=True)
class RangeLookupsModel(PostgreSQLModel):
diff --git a/tests/postgres_tests/test_constraints.py b/tests/postgres_tests/test_constraints.py
index 0e09a1c546..2fc6ee5322 100644
--- a/tests/postgres_tests/test_constraints.py
+++ b/tests/postgres_tests/test_constraints.py
@@ -1,5 +1,7 @@
+import datetime
+
from django.db import connection, transaction
-from django.db.models import Q
+from django.db.models import F, Q
from django.db.models.constraints import CheckConstraint
from django.db.utils import IntegrityError
@@ -33,3 +35,51 @@ class SchemaTests(PostgreSQLTestCase):
with self.assertRaises(IntegrityError), transaction.atomic():
RangesModel.objects.create(ints=(20, 50))
RangesModel.objects.create(ints=(10, 30))
+
+ def test_check_constraint_daterange_contains(self):
+ constraint_name = 'dates_contains'
+ self.assertNotIn(constraint_name, self.get_constraints(RangesModel._meta.db_table))
+ constraint = CheckConstraint(
+ check=Q(dates__contains=F('dates_inner')),
+ name=constraint_name,
+ )
+ with connection.schema_editor() as editor:
+ editor.add_constraint(RangesModel, constraint)
+ with connection.cursor() as cursor:
+ constraints = connection.introspection.get_constraints(cursor, RangesModel._meta.db_table)
+ self.assertIn(constraint_name, constraints)
+ date_1 = datetime.date(2016, 1, 1)
+ date_2 = datetime.date(2016, 1, 4)
+ with self.assertRaises(IntegrityError), transaction.atomic():
+ RangesModel.objects.create(
+ dates=(date_1, date_2),
+ dates_inner=(date_1, date_2.replace(day=5)),
+ )
+ RangesModel.objects.create(
+ dates=(date_1, date_2),
+ dates_inner=(date_1, date_2),
+ )
+
+ def test_check_constraint_datetimerange_contains(self):
+ constraint_name = 'timestamps_contains'
+ self.assertNotIn(constraint_name, self.get_constraints(RangesModel._meta.db_table))
+ constraint = CheckConstraint(
+ check=Q(timestamps__contains=F('timestamps_inner')),
+ name=constraint_name,
+ )
+ with connection.schema_editor() as editor:
+ editor.add_constraint(RangesModel, constraint)
+ with connection.cursor() as cursor:
+ constraints = connection.introspection.get_constraints(cursor, RangesModel._meta.db_table)
+ self.assertIn(constraint_name, constraints)
+ datetime_1 = datetime.datetime(2016, 1, 1)
+ datetime_2 = datetime.datetime(2016, 1, 2, 12)
+ with self.assertRaises(IntegrityError), transaction.atomic():
+ RangesModel.objects.create(
+ timestamps=(datetime_1, datetime_2),
+ timestamps_inner=(datetime_1, datetime_2.replace(hour=13)),
+ )
+ RangesModel.objects.create(
+ timestamps=(datetime_1, datetime_2),
+ timestamps_inner=(datetime_1, datetime_2),
+ )
diff --git a/tests/postgres_tests/test_ranges.py b/tests/postgres_tests/test_ranges.py
index ae834b6ff0..89f32ee77c 100644
--- a/tests/postgres_tests/test_ranges.py
+++ b/tests/postgres_tests/test_ranges.py
@@ -115,11 +115,15 @@ class TestRangeContainsLookup(PostgreSQLTestCase):
]
cls.obj = RangesModel.objects.create(
dates=(cls.dates[0], cls.dates[3]),
+ dates_inner=(cls.dates[1], cls.dates[2]),
timestamps=(cls.timestamps[0], cls.timestamps[3]),
+ timestamps_inner=(cls.timestamps[1], cls.timestamps[2]),
)
cls.aware_obj = RangesModel.objects.create(
dates=(cls.dates[0], cls.dates[3]),
+ dates_inner=(cls.dates[1], cls.dates[2]),
timestamps=(cls.aware_timestamps[0], cls.aware_timestamps[3]),
+ timestamps_inner=(cls.timestamps[1], cls.timestamps[2]),
)
# Objects that don't match any queries.
for i in range(3, 4):
@@ -140,6 +144,7 @@ class TestRangeContainsLookup(PostgreSQLTestCase):
(self.aware_timestamps[1], self.aware_timestamps[2]),
Value(self.dates[0], output_field=DateTimeField()),
Func(F('dates'), function='lower', output_field=DateTimeField()),
+ F('timestamps_inner'),
)
for filter_arg in filter_args:
with self.subTest(filter_arg=filter_arg):
@@ -154,6 +159,7 @@ class TestRangeContainsLookup(PostgreSQLTestCase):
(self.dates[1], self.dates[2]),
Value(self.dates[0], output_field=DateField()),
Func(F('timestamps'), function='lower', output_field=DateField()),
+ F('dates_inner'),
)
for filter_arg in filter_args:
with self.subTest(filter_arg=filter_arg):
@@ -361,7 +367,9 @@ class TestSerialization(PostgreSQLSimpleTestCase):
'\\"bounds\\": \\"[)\\"}", "decimals": "{\\"empty\\": true}", '
'"bigints": null, "timestamps": "{\\"upper\\": \\"2014-02-02T12:12:12+00:00\\", '
'\\"lower\\": \\"2014-01-01T00:00:00+00:00\\", \\"bounds\\": \\"[)\\"}", '
- '"dates": "{\\"upper\\": \\"2014-02-02\\", \\"lower\\": \\"2014-01-01\\", \\"bounds\\": \\"[)\\"}" }, '
+ '"timestamps_inner": null, '
+ '"dates": "{\\"upper\\": \\"2014-02-02\\", \\"lower\\": \\"2014-01-01\\", \\"bounds\\": \\"[)\\"}", '
+ '"dates_inner": null }, '
'"model": "postgres_tests.rangesmodel", "pk": null}]'
)