summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShai Berger <shai@platonix.com>2014-08-01 01:36:06 +0300
committerShai Berger <shai@platonix.com>2014-08-05 03:12:08 +0300
commit746f2a4bed52254e1034c4462033226ff565146c (patch)
treeb85dfcc4be58245803c68c44a29d38a26bd29782
parent6d256ae248cfa1f111d03d29402a669a95cdff3c (diff)
Fixed #23061: Avoided setting a limit on a query for get with select_for_update on Oracle
Thanks Michael Miller for reporting the issue.
-rw-r--r--django/db/backends/__init__.py3
-rw-r--r--django/db/backends/oracle/base.py2
-rw-r--r--django/db/models/query.py4
-rw-r--r--tests/select_for_update/tests.py6
4 files changed, 14 insertions, 1 deletions
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 5577d3b46e..aa0191b068 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -666,6 +666,9 @@ class BaseDatabaseFeatures(object):
uppercases_column_names = False
+ # Does the backend support "select for update" queries with limit (and offset)?
+ supports_select_for_update_with_limit = True
+
def __init__(self, connection):
self.connection = connection
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index 47726e76af..6711626dcb 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -121,6 +121,8 @@ class DatabaseFeatures(BaseDatabaseFeatures):
closed_cursor_error_class = InterfaceError
bare_select_suffix = " FROM DUAL"
uppercases_column_names = True
+ # select for update with limit can be achieved on Oracle, but not with the current backend.
+ supports_select_for_update_with_limit = False
class DatabaseOperations(BaseDatabaseOperations):
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 57d9f6144a..ba99307aa3 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -357,7 +357,9 @@ class QuerySet(object):
clone = self.filter(*args, **kwargs)
if self.query.can_filter():
clone = clone.order_by()
- clone = clone[:MAX_GET_RESULTS + 1]
+ if (not clone.query.select_for_update or
+ connections[self.db].features.supports_select_for_update_with_limit):
+ clone = clone[:MAX_GET_RESULTS + 1]
num = len(clone)
if num == 1:
return clone._result_cache[0]
diff --git a/tests/select_for_update/tests.py b/tests/select_for_update/tests.py
index 54ba0d1d27..a0bd206923 100644
--- a/tests/select_for_update/tests.py
+++ b/tests/select_for_update/tests.py
@@ -265,3 +265,9 @@ class SelectForUpdateTests(TransactionTestCase):
self.assertEqual(router.db_for_write(Person), query.db)
finally:
router.routers = old_routers
+
+ @skipUnlessDBFeature('has_select_for_update')
+ def test_select_for_update_with_get(self):
+ with transaction.atomic():
+ person = Person.objects.select_for_update().get(name='Reinhardt')
+ self.assertEqual(person.name, 'Reinhardt')