diff options
| author | Shai Berger <shai@platonix.com> | 2014-08-01 01:36:06 +0300 |
|---|---|---|
| committer | Shai Berger <shai@platonix.com> | 2014-08-05 03:21:25 +0300 |
| commit | f3c0cb0120aa5805daa880f18b24f40bacde651f (patch) | |
| tree | a8b60b3640f69ee61a8c9317aef4779df0064d7b | |
| parent | a582431b414295ad4cabf0dc8d76229512a459df (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__.py | 3 | ||||
| -rw-r--r-- | django/db/backends/oracle/base.py | 2 | ||||
| -rw-r--r-- | django/db/models/query.py | 4 | ||||
| -rw-r--r-- | tests/select_for_update/tests.py | 6 |
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') |
