mirror of https://github.com/django/django.git
Fixed #34544 -- Avoided DBMS_LOB.SUBSTR() wrapping with IS NULL condition on Oracle.
Regression in09ffc5c121
. Thanks Michael Smith for the report. This also reverts commit1e4da43955
.
This commit is contained in:
parent
aaf8c76c56
commit
1586a09b79
|
@ -296,12 +296,6 @@ END;
|
|||
columns.append(value[0])
|
||||
return tuple(columns)
|
||||
|
||||
def field_cast_sql(self, db_type, internal_type):
|
||||
if db_type and db_type.endswith("LOB") and internal_type != "JSONField":
|
||||
return "DBMS_LOB.SUBSTR(%s)"
|
||||
else:
|
||||
return "%s"
|
||||
|
||||
def no_limit_value(self):
|
||||
return None
|
||||
|
||||
|
@ -344,7 +338,9 @@ END;
|
|||
def lookup_cast(self, lookup_type, internal_type=None):
|
||||
if lookup_type in ("iexact", "icontains", "istartswith", "iendswith"):
|
||||
return "UPPER(%s)"
|
||||
if internal_type == "JSONField" and lookup_type == "exact":
|
||||
if (
|
||||
lookup_type != "isnull" and internal_type in ("BinaryField", "TextField")
|
||||
) or (lookup_type == "exact" and internal_type == "JSONField"):
|
||||
return "DBMS_LOB.SUBSTR(%s)"
|
||||
return "%s"
|
||||
|
||||
|
|
|
@ -82,6 +82,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
|||
"indexes.tests.SchemaIndexesNotPostgreSQLTests."
|
||||
"test_create_index_ignores_opclasses",
|
||||
},
|
||||
"PostgreSQL requires casting to text.": {
|
||||
"lookup.tests.LookupTests.test_textfield_exact_null",
|
||||
},
|
||||
}
|
||||
|
||||
@cached_property
|
||||
|
|
|
@ -9,4 +9,6 @@ Django 4.2.2 fixes several bugs in 4.2.1.
|
|||
Bugfixes
|
||||
========
|
||||
|
||||
* ...
|
||||
* Fixed a regression in Django 4.2 that caused an unnecessary
|
||||
``DBMS_LOB.SUBSTR()`` wrapping in the ``__isnull`` and ``__exact=None``
|
||||
lookups for ``TextField()``/``BinaryField()`` on Oracle (:ticket:`34544`).
|
||||
|
|
|
@ -19,6 +19,7 @@ class Alarm(models.Model):
|
|||
class Author(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
alias = models.CharField(max_length=50, null=True, blank=True)
|
||||
bio = models.TextField(null=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ("name",)
|
||||
|
@ -50,22 +51,11 @@ class NulledTextField(models.TextField):
|
|||
return None if value == "" else value
|
||||
|
||||
|
||||
class NullField(models.Field):
|
||||
pass
|
||||
|
||||
|
||||
NullField.register_lookup(IsNull)
|
||||
|
||||
|
||||
@NulledTextField.register_lookup
|
||||
class NulledTransform(models.Transform):
|
||||
lookup_name = "nulled"
|
||||
template = "NULL"
|
||||
|
||||
@property
|
||||
def output_field(self):
|
||||
return NullField()
|
||||
|
||||
|
||||
@NulledTextField.register_lookup
|
||||
class IsNullWithNoneAsRHS(IsNull):
|
||||
|
|
|
@ -49,7 +49,7 @@ class LookupTests(TestCase):
|
|||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
# Create a few Authors.
|
||||
cls.au1 = Author.objects.create(name="Author 1", alias="a1")
|
||||
cls.au1 = Author.objects.create(name="Author 1", alias="a1", bio="x" * 4001)
|
||||
cls.au2 = Author.objects.create(name="Author 2", alias="a2")
|
||||
# Create a few Articles.
|
||||
cls.a1 = Article.objects.create(
|
||||
|
@ -1029,6 +1029,13 @@ class LookupTests(TestCase):
|
|||
Season.objects.create(year=2012, gt=None)
|
||||
self.assertQuerySetEqual(Season.objects.filter(gt__regex=r"^$"), [])
|
||||
|
||||
def test_textfield_exact_null(self):
|
||||
with self.assertNumQueries(1) as ctx:
|
||||
self.assertSequenceEqual(Author.objects.filter(bio=None), [self.au2])
|
||||
# Columns with IS NULL condition are not wrapped (except PostgreSQL).
|
||||
bio_column = connection.ops.quote_name(Author._meta.get_field("bio").column)
|
||||
self.assertIn(f"{bio_column} IS NULL", ctx.captured_queries[0]["sql"])
|
||||
|
||||
def test_regex_non_string(self):
|
||||
"""
|
||||
A regex lookup does not fail on non-string fields
|
||||
|
|
Loading…
Reference in New Issue