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:21:25 +0300
commitf3c0cb0120aa5805daa880f18b24f40bacde651f (patch)
treea8b60b3640f69ee61a8c9317aef4779df0064d7b
parenta582431b414295ad4cabf0dc8d76229512a459df (diff)
[1.7.x] Fixed #23061: Avoided setting a limit on a query for get with select_for_update on Oracle
Thanks Michael Miller for reporting the issue. Backport of 746f2a4bed from master
-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 b149a94f19..e8e9720d85 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -755,6 +755,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 3260eee0bd..4e055133a0 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -120,6 +120,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 a0967f0fd9..942ee7efa3 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -345,7 +345,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 5d126844d2..3fae8c9ffe 100644
--- a/tests/select_for_update/tests.py
+++ b/tests/select_for_update/tests.py
@@ -292,3 +292,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')