Fixed #36718 -- Added JSONField array negative indexing for Oracle 21c+.

This commit is contained in:
Clifford Gama 2025-11-08 17:08:40 +02:00
parent 8af79e2c0c
commit a29a0059a6
4 changed files with 18 additions and 2 deletions

View file

@ -76,7 +76,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
requires_compound_order_by_subquery = True requires_compound_order_by_subquery = True
allows_multiple_constraints_on_same_fields = False allows_multiple_constraints_on_same_fields = False
supports_json_field_contains = False supports_json_field_contains = False
supports_json_negative_indexing = False
supports_collation_on_textfield = False supports_collation_on_textfield = False
supports_on_delete_db_default = False supports_on_delete_db_default = False
test_now_utc_template = "CURRENT_TIMESTAMP AT TIME ZONE 'UTC'" test_now_utc_template = "CURRENT_TIMESTAMP AT TIME ZONE 'UTC'"
@ -90,6 +89,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
"INSERT INTO {} VALUES (DEFAULT, DEFAULT, DEFAULT)" "INSERT INTO {} VALUES (DEFAULT, DEFAULT, DEFAULT)"
) )
@cached_property
def supports_json_negative_indexing(self):
return self.connection.oracle_version >= (21,)
@cached_property @cached_property
def django_test_skips(self): def django_test_skips(self):
skips = { skips = {

View file

@ -729,3 +729,8 @@ END;
if isinstance(expression, RawSQL) and expression.conditional: if isinstance(expression, RawSQL) and expression.conditional:
return True return True
return False return False
def format_json_path_numeric_index(self, num):
if num < 0:
return "[last-%s]" % abs(num + 1) # Indexing is zero-based.
return super().format_json_path_numeric_index(num)

View file

@ -372,6 +372,9 @@ Miscellaneous
used as the top-level value. :lookup:`Key and index lookups <jsonfield.key>` used as the top-level value. :lookup:`Key and index lookups <jsonfield.key>`
are unaffected by this deprecation. are unaffected by this deprecation.
* Support for negative JSON array indices was added for Oracle versions 21c
and higher.
Features removed in 6.1 Features removed in 6.1
======================= =======================

View file

@ -1182,7 +1182,7 @@ directly, but you can still use dictionary unpacking to use it in a query:
>>> Dog.objects.filter(**{"data__owner__other_pets__-1__name": "Fishy"}) >>> Dog.objects.filter(**{"data__owner__other_pets__-1__name": "Fishy"})
<QuerySet [<Dog: Rufus>]> <QuerySet [<Dog: Rufus>]>
.. admonition:: MySQL, MariaDB, and Oracle .. admonition:: MySQL, MariaDB, and Oracle < 21c
Negative JSON array indices are not supported. Negative JSON array indices are not supported.
@ -1190,6 +1190,11 @@ directly, but you can still use dictionary unpacking to use it in a query:
SQLite support for negative JSON array indices was added. SQLite support for negative JSON array indices was added.
.. versionchanged:: 6.1
Support for negative JSON array indices was added for Oracle versions 21c
and higher.
If the key you wish to query by clashes with the name of another lookup, use If the key you wish to query by clashes with the name of another lookup, use
the :lookup:`contains <jsonfield.contains>` lookup instead. the :lookup:`contains <jsonfield.contains>` lookup instead.