diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py index 62ea5c420ba..1ac6ef5d9bf 100644 --- a/django/core/cache/backends/db.py +++ b/django/core/cache/backends/db.py @@ -167,17 +167,9 @@ class DatabaseCache(BaseDatabaseCache): num = cursor.fetchone()[0] if num > self._max_entries: cull_num = num / self._cull_frequency - if connections[db].vendor == 'oracle': - # Oracle doesn't support LIMIT + OFFSET - cursor.execute("""SELECT cache_key FROM -(SELECT ROW_NUMBER() OVER (ORDER BY cache_key) AS counter, cache_key FROM %s) -WHERE counter > %%s AND COUNTER <= %%s""" % table, [cull_num, cull_num + 1]) - else: - # This isn't standard SQL, it's likely to break - # with some non officially supported databases - cursor.execute("SELECT cache_key FROM %s " - "ORDER BY cache_key " - "LIMIT 1 OFFSET %%s" % table, [cull_num]) + cursor.execute( + connections[db].ops.cache_key_culling_sql() % table, + [cull_num]) cursor.execute("DELETE FROM %s " "WHERE cache_key < %%s" % table, [cursor.fetchone()[0]]) diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py index 05ef7bf62a3..2da1f2be0f4 100644 --- a/django/db/backends/__init__.py +++ b/django/db/backends/__init__.py @@ -475,6 +475,16 @@ class BaseDatabaseOperations(object): """ return None + def cache_key_culling_sql(self): + """ + Returns a SQL query that retrieves the first cache key greater than the + n smallest. + + This is used by the 'db' cache backend to determine where to start + culling. + """ + return "SELECT cache_key FROM %s ORDER BY cache_key LIMIT 1 OFFSET %%s" + def date_extract_sql(self, lookup_type, field_name): """ Given a lookup_type of 'year', 'month' or 'day', returns the SQL that diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index b90f6ea1550..49b628075b8 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -118,6 +118,13 @@ WHEN (new.%(col_name)s IS NULL) /""" % locals() return sequence_sql, trigger_sql + def cache_key_culling_sql(self): + return """ + SELECT cache_key + FROM (SELECT cache_key, rank() OVER (ORDER BY cache_key) AS rank FROM %s) + WHERE rank = %%s + 1 + """ + def date_extract_sql(self, lookup_type, field_name): # http://download-east.oracle.com/docs/cd/B10501_01/server.920/a96540/functions42a.htm#1017163 if lookup_type == 'week_day':