diff options
| author | Roman <roman1972@gmail.com> | 2021-10-11 23:53:53 +0300 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-11-02 21:30:21 +0100 |
| commit | 407fe95cb116599adeb4b9ed01df5673aa5cb1db (patch) | |
| tree | ced14903df06d08c69586229e6f989ffb955e500 /tests | |
| parent | aaf9b558583d9bb75a0c9d53b135dc8c1b75b6a2 (diff) | |
Fixed #32691 -- Made Exact lookup on BooleanFields compare directly to a boolean value on MySQL.
Performance regression in 37e6c5b79bd0529a3c85b8c478e4002fd33a2a1d.
Thanks Todor Velichkov for the report.
Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/lookup/tests.py | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/tests/lookup/tests.py b/tests/lookup/tests.py index 168a621a7e..8e9d2e70f0 100644 --- a/tests/lookup/tests.py +++ b/tests/lookup/tests.py @@ -2,6 +2,7 @@ import collections.abc from datetime import datetime from math import ceil from operator import attrgetter +from unittest import skipUnless from django.core.exceptions import FieldError from django.db import connection, models @@ -927,6 +928,44 @@ class LookupTests(TestCase): with self.assertRaisesMessage(ValueError, msg): list(Article.objects.filter(author=Author.objects.all()[1:])) + @skipUnless(connection.vendor == 'mysql', 'MySQL-specific workaround.') + def test_exact_booleanfield(self): + # MySQL ignores indexes with boolean fields unless they're compared + # directly to a boolean value. + product = Product.objects.create(name='Paper', qty_target=5000) + Stock.objects.create(product=product, short=False, qty_available=5100) + stock_1 = Stock.objects.create(product=product, short=True, qty_available=180) + qs = Stock.objects.filter(short=True) + self.assertSequenceEqual(qs, [stock_1]) + self.assertIn( + '%s = True' % connection.ops.quote_name('short'), + str(qs.query), + ) + + @skipUnless(connection.vendor == 'mysql', 'MySQL-specific workaround.') + def test_exact_booleanfield_annotation(self): + # MySQL ignores indexes with boolean fields unless they're compared + # directly to a boolean value. + qs = Author.objects.annotate(case=Case( + When(alias='a1', then=True), + default=False, + output_field=BooleanField(), + )).filter(case=True) + self.assertSequenceEqual(qs, [self.au1]) + self.assertIn(' = True', str(qs.query)) + + qs = Author.objects.annotate( + wrapped=ExpressionWrapper(Q(alias='a1'), output_field=BooleanField()), + ).filter(wrapped=True) + self.assertSequenceEqual(qs, [self.au1]) + self.assertIn(' = True', str(qs.query)) + # EXISTS(...) shouldn't be compared to a boolean value. + qs = Author.objects.annotate( + exists=Exists(Author.objects.filter(alias='a1', pk=OuterRef('pk'))), + ).filter(exists=True) + self.assertSequenceEqual(qs, [self.au1]) + self.assertNotIn(' = True', str(qs.query)) + def test_custom_field_none_rhs(self): """ __exact=value is transformed to __isnull=True if Field.get_prep_value() |
