summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2020-05-18 02:12:20 -0400
committerGitHub <noreply@github.com>2020-05-18 08:12:20 +0200
commitf59a2b730685fc62c5cb44101f54faf8921d9bc7 (patch)
tree3e9bc28ef38bcdda752c00a6165e62f3a6c8b874
parentd00e034a286771830e58356de3511c99ca023d26 (diff)
Refs #12990 -- Added DatabaseFeatures.has_json_operators.
CockroachDB also has them.
-rw-r--r--django/db/backends/base/features.py2
-rw-r--r--django/db/backends/postgresql/features.py1
-rw-r--r--tests/model_fields/test_jsonfield.py8
3 files changed, 8 insertions, 3 deletions
diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py
index 67bfe77e7c..35ce3ba299 100644
--- a/django/db/backends/base/features.py
+++ b/django/db/backends/base/features.py
@@ -309,6 +309,8 @@ class BaseDatabaseFeatures:
supports_primitives_in_json_field = True
# Is there a true datatype for JSON?
has_native_json_field = False
+ # Does the backend use PostgreSQL-style JSON operators like '->'?
+ has_json_operators = False
def __init__(self, connection):
self.connection = connection
diff --git a/django/db/backends/postgresql/features.py b/django/db/backends/postgresql/features.py
index 80cee8e8da..a4ba0b99fc 100644
--- a/django/db/backends/postgresql/features.py
+++ b/django/db/backends/postgresql/features.py
@@ -58,6 +58,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supported_explain_formats = {'JSON', 'TEXT', 'XML', 'YAML'}
validates_explain_options = False # A query will error on invalid options.
supports_deferrable_unique_constraints = True
+ has_json_operators = True
@cached_property
def is_postgresql_10(self):
diff --git a/tests/model_fields/test_jsonfield.py b/tests/model_fields/test_jsonfield.py
index 464cf163d4..1e92b34791 100644
--- a/tests/model_fields/test_jsonfield.py
+++ b/tests/model_fields/test_jsonfield.py
@@ -17,7 +17,9 @@ from django.db.models.fields.json import (
KeyTransformTextLookupMixin,
)
from django.db.models.functions import Cast
-from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
+from django.test import (
+ SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBFeature,
+)
from django.test.utils import CaptureQueriesContext
from .models import CustomJSONDecoder, JSONModel, NullableJSONModel
@@ -607,7 +609,7 @@ class TestQuerying(TestCase):
def test_key_iregex(self):
self.assertIs(NullableJSONModel.objects.filter(value__foo__iregex=r'^bAr$').exists(), True)
- @skipUnless(connection.vendor == 'postgresql', 'kwargs are crafted for PostgreSQL.')
+ @skipUnlessDBFeature('has_json_operators')
def test_key_sql_injection(self):
with CaptureQueriesContext(connection) as queries:
self.assertIs(
@@ -621,7 +623,7 @@ class TestQuerying(TestCase):
queries[0]['sql'],
)
- @skipIf(connection.vendor == 'postgresql', 'PostgreSQL uses operators not functions.')
+ @skipIfDBFeature('has_json_operators')
def test_key_sql_injection_escape(self):
query = str(JSONModel.objects.filter(**{
"""value__test") = '"a"' OR 1 = 1 OR ("d""": 'x',