mirror of
https://github.com/django/django.git
synced 2024-12-22 09:05:43 +00:00
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])
|
columns.append(value[0])
|
||||||
return tuple(columns)
|
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):
|
def no_limit_value(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -344,7 +338,9 @@ END;
|
|||||||
def lookup_cast(self, lookup_type, internal_type=None):
|
def lookup_cast(self, lookup_type, internal_type=None):
|
||||||
if lookup_type in ("iexact", "icontains", "istartswith", "iendswith"):
|
if lookup_type in ("iexact", "icontains", "istartswith", "iendswith"):
|
||||||
return "UPPER(%s)"
|
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 "DBMS_LOB.SUBSTR(%s)"
|
||||||
return "%s"
|
return "%s"
|
||||||
|
|
||||||
|
@ -82,6 +82,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
|||||||
"indexes.tests.SchemaIndexesNotPostgreSQLTests."
|
"indexes.tests.SchemaIndexesNotPostgreSQLTests."
|
||||||
"test_create_index_ignores_opclasses",
|
"test_create_index_ignores_opclasses",
|
||||||
},
|
},
|
||||||
|
"PostgreSQL requires casting to text.": {
|
||||||
|
"lookup.tests.LookupTests.test_textfield_exact_null",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
|
@ -9,4 +9,6 @@ Django 4.2.2 fixes several bugs in 4.2.1.
|
|||||||
Bugfixes
|
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):
|
class Author(models.Model):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
alias = models.CharField(max_length=50, null=True, blank=True)
|
alias = models.CharField(max_length=50, null=True, blank=True)
|
||||||
|
bio = models.TextField(null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ("name",)
|
ordering = ("name",)
|
||||||
@ -50,22 +51,11 @@ class NulledTextField(models.TextField):
|
|||||||
return None if value == "" else value
|
return None if value == "" else value
|
||||||
|
|
||||||
|
|
||||||
class NullField(models.Field):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
NullField.register_lookup(IsNull)
|
|
||||||
|
|
||||||
|
|
||||||
@NulledTextField.register_lookup
|
@NulledTextField.register_lookup
|
||||||
class NulledTransform(models.Transform):
|
class NulledTransform(models.Transform):
|
||||||
lookup_name = "nulled"
|
lookup_name = "nulled"
|
||||||
template = "NULL"
|
template = "NULL"
|
||||||
|
|
||||||
@property
|
|
||||||
def output_field(self):
|
|
||||||
return NullField()
|
|
||||||
|
|
||||||
|
|
||||||
@NulledTextField.register_lookup
|
@NulledTextField.register_lookup
|
||||||
class IsNullWithNoneAsRHS(IsNull):
|
class IsNullWithNoneAsRHS(IsNull):
|
||||||
|
@ -49,7 +49,7 @@ class LookupTests(TestCase):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
# Create a few Authors.
|
# 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")
|
cls.au2 = Author.objects.create(name="Author 2", alias="a2")
|
||||||
# Create a few Articles.
|
# Create a few Articles.
|
||||||
cls.a1 = Article.objects.create(
|
cls.a1 = Article.objects.create(
|
||||||
@ -1029,6 +1029,13 @@ class LookupTests(TestCase):
|
|||||||
Season.objects.create(year=2012, gt=None)
|
Season.objects.create(year=2012, gt=None)
|
||||||
self.assertQuerySetEqual(Season.objects.filter(gt__regex=r"^$"), [])
|
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):
|
def test_regex_non_string(self):
|
||||||
"""
|
"""
|
||||||
A regex lookup does not fail on non-string fields
|
A regex lookup does not fail on non-string fields
|
||||||
|
Loading…
Reference in New Issue
Block a user