Fixed #23061: Avoided setting a limit on a query for get with select_for_update on Oracle
Thanks Michael Miller for reporting the issue.
This commit is contained in:
parent
6d256ae248
commit
746f2a4bed
|
@ -666,6 +666,9 @@ class BaseDatabaseFeatures(object):
|
||||||
|
|
||||||
uppercases_column_names = False
|
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):
|
def __init__(self, connection):
|
||||||
self.connection = connection
|
self.connection = connection
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,8 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
closed_cursor_error_class = InterfaceError
|
closed_cursor_error_class = InterfaceError
|
||||||
bare_select_suffix = " FROM DUAL"
|
bare_select_suffix = " FROM DUAL"
|
||||||
uppercases_column_names = True
|
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):
|
class DatabaseOperations(BaseDatabaseOperations):
|
||||||
|
|
|
@ -357,7 +357,9 @@ class QuerySet(object):
|
||||||
clone = self.filter(*args, **kwargs)
|
clone = self.filter(*args, **kwargs)
|
||||||
if self.query.can_filter():
|
if self.query.can_filter():
|
||||||
clone = clone.order_by()
|
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)
|
num = len(clone)
|
||||||
if num == 1:
|
if num == 1:
|
||||||
return clone._result_cache[0]
|
return clone._result_cache[0]
|
||||||
|
|
|
@ -265,3 +265,9 @@ class SelectForUpdateTests(TransactionTestCase):
|
||||||
self.assertEqual(router.db_for_write(Person), query.db)
|
self.assertEqual(router.db_for_write(Person), query.db)
|
||||||
finally:
|
finally:
|
||||||
router.routers = old_routers
|
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')
|
||||||
|
|
Loading…
Reference in New Issue