Skip to content

Commit 7e4c4f4

Browse files
authored
Fixed #36718 -- Added JSONField support for negative array indexing on Oracle 21c+.
1 parent 8ce3e1f commit 7e4c4f4

4 files changed

Lines changed: 18 additions & 2 deletions

File tree

django/db/backends/oracle/features.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
7676
requires_compound_order_by_subquery = True
7777
allows_multiple_constraints_on_same_fields = False
7878
supports_json_field_contains = False
79-
supports_json_negative_indexing = False
8079
supports_collation_on_textfield = False
8180
supports_on_delete_db_default = False
8281
supports_no_precision_decimalfield = True
@@ -91,6 +90,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
9190
"INSERT INTO {} VALUES (DEFAULT, DEFAULT, DEFAULT)"
9291
)
9392

93+
@cached_property
94+
def supports_json_negative_indexing(self):
95+
return self.connection.oracle_version >= (21,)
96+
9497
@cached_property
9598
def django_test_skips(self):
9699
skips = {

django/db/backends/oracle/operations.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,3 +729,8 @@ def conditional_expression_supported_in_where_clause(self, expression):
729729
if isinstance(expression, RawSQL) and expression.conditional:
730730
return True
731731
return False
732+
733+
def format_json_path_numeric_index(self, num):
734+
if num < 0:
735+
return "[last-%s]" % abs(num + 1) # Indexing is zero-based.
736+
return super().format_json_path_numeric_index(num)

docs/releases/6.1.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ Models
254254
<django.db.models.DecimalField.decimal_places>` are no longer required to be
255255
set on Oracle, PostgreSQL, and SQLite.
256256

257+
* :class:`~django.db.models.JSONField` now supports
258+
:ref:`negative array indexing <key-index-and-path-transforms>` on Oracle
259+
21c+.
260+
257261
Pagination
258262
~~~~~~~~~~
259263

docs/topics/db/queries.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1184,14 +1184,18 @@ directly, but you can still use dictionary unpacking to use it in a query:
11841184
>>> Dog.objects.filter(**{"data__owner__other_pets__-1__name": "Fishy"})
11851185
<QuerySet [<Dog: Rufus>]>
11861186

1187-
.. admonition:: MySQL, MariaDB, and Oracle
1187+
.. admonition:: MySQL, MariaDB, and Oracle < 21c
11881188

11891189
Negative JSON array indices are not supported.
11901190

11911191
.. versionchanged:: 6.0
11921192

11931193
SQLite support for negative JSON array indices was added.
11941194

1195+
.. versionchanged:: 6.1
1196+
1197+
Oracle 21c+ support for negative JSON array indices was added.
1198+
11951199
If the key you wish to query by clashes with the name of another lookup, use
11961200
the :lookup:`contains <jsonfield.contains>` lookup instead.
11971201

0 commit comments

Comments
 (0)