summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/backends/base/features.py2
-rw-r--r--django/db/backends/oracle/features.py3
-rw-r--r--tests/expressions_case/tests.py22
-rw-r--r--tests/gis_tests/geoapp/test_regress.py6
-rw-r--r--tests/gis_tests/relatedapp/tests.py10
-rw-r--r--tests/model_fields/test_jsonfield.py2
6 files changed, 22 insertions, 23 deletions
diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py
index 0b315aac02..03c97e6691 100644
--- a/django/db/backends/base/features.py
+++ b/django/db/backends/base/features.py
@@ -4,6 +4,8 @@ from django.utils.functional import cached_property
class BaseDatabaseFeatures:
gis_enabled = False
+ # Oracle can't group by LOB (large object) data types.
+ allows_group_by_lob = True
allows_group_by_pk = False
allows_group_by_selected_pks = False
empty_fetchmany_value = []
diff --git a/django/db/backends/oracle/features.py b/django/db/backends/oracle/features.py
index b0eebe5008..63d825f68a 100644
--- a/django/db/backends/oracle/features.py
+++ b/django/db/backends/oracle/features.py
@@ -4,6 +4,9 @@ from django.utils.functional import cached_property
class DatabaseFeatures(BaseDatabaseFeatures):
+ # Oracle crashes with "ORA-00932: inconsistent datatypes: expected - got
+ # BLOB" when grouping by LOBs (#24096).
+ allows_group_by_lob = False
interprets_empty_strings_as_nulls = True
has_select_for_update = True
has_select_for_update_nowait = True
diff --git a/tests/expressions_case/tests.py b/tests/expressions_case/tests.py
index 54c53ef4de..ec811ca511 100644
--- a/tests/expressions_case/tests.py
+++ b/tests/expressions_case/tests.py
@@ -5,6 +5,7 @@ from operator import attrgetter, itemgetter
from uuid import UUID
from django.core.exceptions import FieldError
+from django.db import connection
from django.db.models import (
BinaryField, BooleanField, Case, Count, DecimalField, F,
GenericIPAddressField, IntegerField, Max, Min, Q, Sum, TextField, Value,
@@ -56,10 +57,13 @@ class CaseExpressionTests(TestCase):
O2OCaseTestModel.objects.create(o2o=o, integer=1)
FKCaseTestModel.objects.create(fk=o, integer=5)
- # GROUP BY on Oracle fails with TextField/BinaryField; see #24096.
- cls.non_lob_fields = [
+ cls.group_by_fields = [
f.name for f in CaseTestModel._meta.get_fields()
- if not (f.is_relation and f.auto_created) and not isinstance(f, (BinaryField, TextField))
+ if not (f.is_relation and f.auto_created) and
+ (
+ connection.features.allows_group_by_lob or
+ not isinstance(f, (BinaryField, TextField))
+ )
]
def test_annotate(self):
@@ -197,7 +201,7 @@ class CaseExpressionTests(TestCase):
def test_annotate_with_aggregation_in_value(self):
self.assertQuerysetEqual(
- CaseTestModel.objects.values(*self.non_lob_fields).annotate(
+ CaseTestModel.objects.values(*self.group_by_fields).annotate(
min=Min('fk_rel__integer'),
max=Max('fk_rel__integer'),
).annotate(
@@ -212,7 +216,7 @@ class CaseExpressionTests(TestCase):
def test_annotate_with_aggregation_in_condition(self):
self.assertQuerysetEqual(
- CaseTestModel.objects.values(*self.non_lob_fields).annotate(
+ CaseTestModel.objects.values(*self.group_by_fields).annotate(
min=Min('fk_rel__integer'),
max=Max('fk_rel__integer'),
).annotate(
@@ -227,7 +231,7 @@ class CaseExpressionTests(TestCase):
def test_annotate_with_aggregation_in_predicate(self):
self.assertQuerysetEqual(
- CaseTestModel.objects.values(*self.non_lob_fields).annotate(
+ CaseTestModel.objects.values(*self.group_by_fields).annotate(
max=Max('fk_rel__integer'),
).annotate(
test=Case(
@@ -483,7 +487,7 @@ class CaseExpressionTests(TestCase):
def test_filter_with_aggregation_in_value(self):
self.assertQuerysetEqual(
- CaseTestModel.objects.values(*self.non_lob_fields).annotate(
+ CaseTestModel.objects.values(*self.group_by_fields).annotate(
min=Min('fk_rel__integer'),
max=Max('fk_rel__integer'),
).filter(
@@ -498,7 +502,7 @@ class CaseExpressionTests(TestCase):
def test_filter_with_aggregation_in_condition(self):
self.assertQuerysetEqual(
- CaseTestModel.objects.values(*self.non_lob_fields).annotate(
+ CaseTestModel.objects.values(*self.group_by_fields).annotate(
min=Min('fk_rel__integer'),
max=Max('fk_rel__integer'),
).filter(
@@ -513,7 +517,7 @@ class CaseExpressionTests(TestCase):
def test_filter_with_aggregation_in_predicate(self):
self.assertQuerysetEqual(
- CaseTestModel.objects.values(*self.non_lob_fields).annotate(
+ CaseTestModel.objects.values(*self.group_by_fields).annotate(
max=Max('fk_rel__integer'),
).filter(
integer=Case(
diff --git a/tests/gis_tests/geoapp/test_regress.py b/tests/gis_tests/geoapp/test_regress.py
index 661124dcba..674f19ba54 100644
--- a/tests/gis_tests/geoapp/test_regress.py
+++ b/tests/gis_tests/geoapp/test_regress.py
@@ -5,7 +5,6 @@ from django.contrib.gis.shortcuts import render_to_kmz
from django.db.models import Count, Min
from django.test import TestCase, skipUnlessDBFeature
-from ..utils import no_oracle
from .models import City, PennsylvaniaCity, State, Truth
@@ -65,10 +64,7 @@ class GeoRegressionTests(TestCase):
# .count() should not throw TypeError in __eq__
self.assertEqual(cities_within_state.count(), 1)
- # TODO: fix on Oracle -- get the following error because the SQL is ordered
- # by a geometry object, which Oracle apparently doesn't like:
- # ORA-22901: cannot compare nested table or VARRAY or LOB attributes of an object type
- @no_oracle
+ @skipUnlessDBFeature('allows_group_by_lob')
def test_defer_or_only_with_annotate(self):
"Regression for #16409. Make sure defer() and only() work with annotate()"
self.assertIsInstance(list(City.objects.annotate(Count('point')).defer('name')), list)
diff --git a/tests/gis_tests/relatedapp/tests.py b/tests/gis_tests/relatedapp/tests.py
index 5f003b78f2..2b4a0b0ed0 100644
--- a/tests/gis_tests/relatedapp/tests.py
+++ b/tests/gis_tests/relatedapp/tests.py
@@ -222,10 +222,7 @@ class RelatedGeoModelTest(TestCase):
self.assertIn('Aurora', names)
self.assertIn('Kecksburg', names)
- # TODO: fix on Oracle -- get the following error because the SQL is ordered
- # by a geometry object, which Oracle apparently doesn't like:
- # ORA-22901: cannot compare nested table or VARRAY or LOB attributes of an object type
- @no_oracle
+ @skipUnlessDBFeature('allows_group_by_lob')
def test12a_count(self):
"Testing `Count` aggregate on geo-fields."
# The City, 'Fort Worth' uses the same location as Dallas.
@@ -247,10 +244,7 @@ class RelatedGeoModelTest(TestCase):
self.assertEqual(1, len(vqs))
self.assertEqual(3, vqs[0]['num_books'])
- # TODO: fix on Oracle -- get the following error because the SQL is ordered
- # by a geometry object, which Oracle apparently doesn't like:
- # ORA-22901: cannot compare nested table or VARRAY or LOB attributes of an object type
- @no_oracle
+ @skipUnlessDBFeature('allows_group_by_lob')
def test13c_count(self):
"Testing `Count` aggregate with `.values()`. See #15305."
qs = Location.objects.filter(id=5).annotate(num_cities=Count('city')).values('id', 'point', 'num_cities')
diff --git a/tests/model_fields/test_jsonfield.py b/tests/model_fields/test_jsonfield.py
index f45589e075..1c63d70bf9 100644
--- a/tests/model_fields/test_jsonfield.py
+++ b/tests/model_fields/test_jsonfield.py
@@ -355,7 +355,7 @@ class TestQuerying(TestCase):
operator.itemgetter('key', 'count'),
)
- @skipIf(connection.vendor == 'oracle', "Oracle doesn't support grouping by LOBs, see #24096.")
+ @skipUnlessDBFeature('allows_group_by_lob')
def test_ordering_grouping_by_count(self):
qs = NullableJSONModel.objects.filter(
value__isnull=False,