mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #26063 -- Crash when passing > 2000 params.
If SQLITE_MAX_VARIABLE_NUMBER (default = 999) is changed at compile time to be greater than SQLITE_MAX_COLUMN (default = 2000), which Debian does by setting the former to 250000, Django raised an exception on queries containing more than 2000 parameters when DEBUG = True.
This commit is contained in:
		| @@ -107,6 +107,19 @@ class DatabaseOperations(BaseDatabaseOperations): | ||||
|         """ | ||||
|         Only for last_executed_query! Don't use this to execute SQL queries! | ||||
|         """ | ||||
|         # This function is limited both by SQLITE_LIMIT_VARIABLE_NUMBER (the | ||||
|         # number of paramters, default = 999) and SQLITE_MAX_COLUMN (the | ||||
|         # number of return values, default = 2000). Since Python's sqlite3 | ||||
|         # module doesn't expose the get_limit() C API, assume the default | ||||
|         # limits are in effect and split the work in batches if needed. | ||||
|         BATCH_SIZE = 999 | ||||
|         if len(params) > BATCH_SIZE: | ||||
|             results = () | ||||
|             for index in range(0, len(params), BATCH_SIZE): | ||||
|                 chunk = params[index:index + BATCH_SIZE] | ||||
|                 results += self._quote_params_for_last_executed_query(chunk) | ||||
|             return results | ||||
|  | ||||
|         sql = 'SELECT ' + ', '.join(['QUOTE(?)'] * len(params)) | ||||
|         # Bypass Django's wrappers and use the underlying sqlite3 connection | ||||
|         # to avoid logging this query - it would trigger infinite recursion. | ||||
|   | ||||
| @@ -44,3 +44,8 @@ Bugfixes | ||||
|  | ||||
| * Fixed a ``QuerySet.order_by()`` crash when ordering by a relational field of | ||||
|   a ``ManyToManyField`` ``through`` model (:ticket:`26092`). | ||||
|  | ||||
| * Fixed a regression that caused an exception when making database queries on | ||||
|   SQLite with more than 2000 parameters when :setting:`DEBUG` is ``True`` on | ||||
|   distributions that increase the ``SQLITE_MAX_VARIABLE_NUMBER`` compile-time | ||||
|   limit to over 2000, such as Debian (:ticket:`26063`). | ||||
|   | ||||
| @@ -426,6 +426,18 @@ class LastExecutedQueryTest(TestCase): | ||||
|         substituted = "SELECT '\"''\\'" | ||||
|         self.assertEqual(connection.queries[-1]['sql'], substituted) | ||||
|  | ||||
|     @unittest.skipUnless(connection.vendor == 'sqlite', | ||||
|                          "This test is specific to SQLite.") | ||||
|     def test_large_number_of_parameters_on_sqlite(self): | ||||
|         # If SQLITE_MAX_VARIABLE_NUMBER (default = 999) has been changed to be | ||||
|         # greater than SQLITE_MAX_COLUMN (default = 2000), last_executed_query | ||||
|         # can hit the SQLITE_MAX_COLUMN limit. See #26063. | ||||
|         cursor = connection.cursor() | ||||
|         sql = "SELECT MAX(%s)" % ", ".join(["%s"] * 2001) | ||||
|         params = list(range(2001)) | ||||
|         # This should not raise an exception. | ||||
|         cursor.db.ops.last_executed_query(cursor.cursor, sql, params) | ||||
|  | ||||
|  | ||||
| class ParameterHandlingTest(TestCase): | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user