Author: mtredinnick
Date: 2008-02-22 19:34:49 -0600 (Fri, 22 Feb 2008)
New Revision: 7147

Modified:
   django/branches/queryset-refactor/django/db/backends/__init__.py
   django/branches/queryset-refactor/django/db/backends/mysql/base.py
   django/branches/queryset-refactor/django/db/backends/mysql_old/base.py
   django/branches/queryset-refactor/django/db/backends/postgresql/operations.py
   django/branches/queryset-refactor/django/db/backends/sqlite3/base.py
   django/branches/queryset-refactor/django/db/models/sql/query.py
   django/branches/queryset-refactor/docs/db-api.txt
   django/branches/queryset-refactor/tests/modeltests/basic/models.py
Log:
queryset-refactor: Implemented slicing to end of querysets.

Refs #2150, #5012.


Modified: django/branches/queryset-refactor/django/db/backends/__init__.py
===================================================================
--- django/branches/queryset-refactor/django/db/backends/__init__.py    
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/django/db/backends/__init__.py    
2008-02-23 01:34:49 UTC (rev 7147)
@@ -183,6 +183,14 @@
         """
         return None
 
+    def no_limit_value(self):
+        """
+        Returns the value to use for the LIMIT when we are wanting "LIMIT
+        infinity". Returns None if the limit clause can be omitted in this 
case.
+        """
+        # FIXME: API may need to change once Oracle backend is repaired.
+        raise NotImplementedError()
+
     def pk_default_value(self):
         """
         Returns the value to use during an INSERT statement to specify that

Modified: django/branches/queryset-refactor/django/db/backends/mysql/base.py
===================================================================
--- django/branches/queryset-refactor/django/db/backends/mysql/base.py  
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/django/db/backends/mysql/base.py  
2008-02-23 01:34:49 UTC (rev 7147)
@@ -93,6 +93,10 @@
             sql += "%s," % offset
         return sql + str(limit)
 
+    def no_limit_value(self):
+        # 2**64 - 1, as recommended by the MySQL documentation
+        return 18446744073709551615L
+
     def quote_name(self, name):
         if name.startswith("`") and name.endswith("`"):
             return name # Quoting once is enough.

Modified: django/branches/queryset-refactor/django/db/backends/mysql_old/base.py
===================================================================
--- django/branches/queryset-refactor/django/db/backends/mysql_old/base.py      
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/django/db/backends/mysql_old/base.py      
2008-02-23 01:34:49 UTC (rev 7147)
@@ -98,6 +98,10 @@
             sql += "%s," % offset
         return sql + str(limit)
 
+    def no_limit_value(self):
+        # 2**64 - 1, as recommended by the MySQL documentation
+        return 18446744073709551615L
+
     def quote_name(self, name):
         if name.startswith("`") and name.endswith("`"):
             return name # Quoting once is enough.

Modified: 
django/branches/queryset-refactor/django/db/backends/postgresql/operations.py
===================================================================
--- 
django/branches/queryset-refactor/django/db/backends/postgresql/operations.py   
    2008-02-23 00:23:57 UTC (rev 7146)
+++ 
django/branches/queryset-refactor/django/db/backends/postgresql/operations.py   
    2008-02-23 01:34:49 UTC (rev 7147)
@@ -31,6 +31,9 @@
         cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, 
pk_name))
         return cursor.fetchone()[0]
 
+    def no_limit_value(self):
+        return None
+
     def quote_name(self, name):
         if name.startswith('"') and name.endswith('"'):
             return name # Quoting once is enough.

Modified: django/branches/queryset-refactor/django/db/backends/sqlite3/base.py
===================================================================
--- django/branches/queryset-refactor/django/db/backends/sqlite3/base.py        
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/django/db/backends/sqlite3/base.py        
2008-02-23 01:34:49 UTC (rev 7147)
@@ -63,6 +63,9 @@
             return name # Quoting once is enough.
         return '"%s"' % name
 
+    def no_limit_value(self):
+        return -1
+
     def sql_flush(self, style, tables, sequences):
         # NB: The generated SQL below is specific to SQLite
         # Note: The DELETE FROM... SQL generated below works for SQLite 
databases

Modified: django/branches/queryset-refactor/django/db/models/sql/query.py
===================================================================
--- django/branches/queryset-refactor/django/db/models/sql/query.py     
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/django/db/models/sql/query.py     
2008-02-23 01:34:49 UTC (rev 7147)
@@ -262,11 +262,15 @@
         if ordering:
             result.append('ORDER BY %s' % ', '.join(ordering))
 
+        # FIXME: Pull this out to make life easier for Oracle et al.
         if with_limits:
             if self.high_mark:
                 result.append('LIMIT %d' % (self.high_mark - self.low_mark))
             if self.low_mark:
-                assert self.high_mark, "'offset' is not allowed without 
'limit'"
+                if not self.high_mark:
+                    val = self.connection.ops.no_limit_value()
+                    if val:
+                        result.append('LIMIT %d' % val)
                 result.append('OFFSET %d' % self.low_mark)
 
         params.extend(self.extra_params)

Modified: django/branches/queryset-refactor/docs/db-api.txt
===================================================================
--- django/branches/queryset-refactor/docs/db-api.txt   2008-02-23 00:23:57 UTC 
(rev 7146)
+++ django/branches/queryset-refactor/docs/db-api.txt   2008-02-23 01:34:49 UTC 
(rev 7147)
@@ -422,6 +422,14 @@
 
     Entry.objects.all()[5:10]
 
+You can also slice from the item ''N'' to the end of the queryset. For
+example, to return everything from the fixth item onwards::
+
+    Entry.objects.all()[5:]
+
+How this last example is implemented in SQL varies depending upon the database
+used, but it is supported in all cases.
+
 Generally, slicing a ``QuerySet`` returns a new ``QuerySet`` -- it doesn't
 evaluate the query. An exception is if you use the "step" parameter of Python
 slice syntax. For example, this would actually execute the query in order to

Modified: django/branches/queryset-refactor/tests/modeltests/basic/models.py
===================================================================
--- django/branches/queryset-refactor/tests/modeltests/basic/models.py  
2008-02-23 00:23:57 UTC (rev 7146)
+++ django/branches/queryset-refactor/tests/modeltests/basic/models.py  
2008-02-23 01:34:49 UTC (rev 7147)
@@ -292,11 +292,9 @@
 >>> Article.objects.all()[2:][2:3]
 [<Article: Default headline>]
 
-# Note that you can't use 'offset' without 'limit' (on some dbs), so this 
doesn't work:
->>> Article.objects.all()[2:]
-Traceback (most recent call last):
-    ...
-AssertionError: 'offset' is not allowed without 'limit'
+# Using an offset without a limit is also possible.
+>>> Article.objects.all()[5:]
+[<Article: Fourth article>, <Article: Article 7>, <Article: Updated article 8>]
 
 # Also, once you have sliced you can't filter, re-order or combine
 >>> Article.objects.all()[0:5].filter(id=1)


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to