Commit 746f2a4b authored by Shai Berger's avatar Shai Berger
Browse files

Fixed #23061: Avoided setting a limit on a query for get with select_for_update on Oracle

Thanks Michael Miller for reporting the issue.
parent 6d256ae2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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

+2 −0
Original line number Diff line number Diff line
@@ -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):
+3 −1
Original line number Diff line number Diff line
@@ -357,6 +357,8 @@ class QuerySet(object):
        clone = self.filter(*args, **kwargs)
        if self.query.can_filter():
            clone = clone.order_by()
        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:
+6 −0
Original line number Diff line number Diff line
@@ -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')