Opened 11 hours ago
Last modified 11 hours ago
#36821 new Bug
Asymmetry between exact and iexact when filtering for empty strings on Oracle
| Reported by: | Clifford Gama | Owned by: | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 6.0 |
| Severity: | Normal | Keywords: | iexact, interprets_empty_strings_as_null |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
As pointed out by Jacob, the special-handling that the ORM does for empty strings on backends that interpret_empty_strings_as_null=True is not performed on iexact lookups. The docs on iexact and exact state that:
If the value provided for comparison is None, it will be interpreted as an SQL NULL (see isnull for more details).
Which I would also expect to apply to empty strings on backends where they mean Null.
Failing test:
diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 51d1915c97..24e9c51593 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -2280,6 +2280,17 @@ class ComparisonTests(TestCase): [item_ab], ) + @skipUnlessDBFeature("interprets_empty_strings_as_nulls") + def test_empty_string_is_null(self): + obj = NullableName.objects.create(name=None) + obj1 = NullableName.objects.create(name="") + cases = [{"name__exact": ""}, {"name__iexact": ""}] + for lookup in cases: + with self.subTest(lookup): + self.assertSequenceEqual( + NullableName.objects.filter(**lookup), [obj, obj1] + ) + class ExistsSql(TestCase): def test_exists(self):
The query generated for the iexact case is as follows (note that it will never match anything):
SELECT "queries_nullablename"."id", "queries_nullablename"."name" FROM "queries_nullablename" WHERE Upper("queries_nullablename"."name") = Upper() ORDER BY "queries_nullablename"."id" ASC;
Thanks, Clifford!