mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	[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
			
			
This commit is contained in:
		| @@ -755,6 +755,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 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -120,6 +120,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): | ||||||
|   | |||||||
| @@ -345,7 +345,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] | ||||||
|   | |||||||
| @@ -292,3 +292,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') | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user