]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Changed MySQL dialect to use the older LIMIT <offset>, <limit> syntax instead
authorJason Kirtland <jek@discorporate.us>
Wed, 26 Sep 2007 23:37:11 +0000 (23:37 +0000)
committerJason Kirtland <jek@discorporate.us>
Wed, 26 Sep 2007 23:37:11 +0000 (23:37 +0000)
of LIMIT <l> OFFSET <o> for folks using 3.23. ([ticket:794], thanks for the
patch!)

CHANGES
lib/sqlalchemy/databases/mysql.py
test/dialect/mysql.py

diff --git a/CHANGES b/CHANGES
index bdb2cd995204ce185c3acc4827e275430d43b89c..cfba8ff227d6761c35b37757b8439d032b6f9337 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -58,6 +58,9 @@ CHANGES
 
 - Fixed reflection of the empty string for mysql enums.
 
+- Changed MySQL dialect to use the older LIMIT <offset>, <limit> syntax
+  instead of LIMIT <l> OFFSET <o> for folks using 3.23. [ticket:794]
+
 - Added 'passive_deletes="all"' flag to relation(), disables all nulling-out
   of foreign key attributes during a flush where the parent object is
   deleted.
index 9eba2abdb440945c9661e3d214c7f8e8ea764163..c0b1179a3738af7027b159edceb5f122589ed033 100644 (file)
@@ -1812,16 +1812,28 @@ class MySQLCompiler(compiler.DefaultCompiler):
             return super(MySQLCompiler, self).for_update_clause(select)
 
     def limit_clause(self, select):
-        text = ""
-        if select._limit is not None:
-            text +=  " \n LIMIT " + str(select._limit)
-        if select._offset is not None:
-            if select._limit is None:
-                # straight from the MySQL docs, I kid you not
-                text += " \n LIMIT 18446744073709551615"
-            text += " OFFSET " + str(select._offset)
-        return text
-        
+        # MySQL supports:
+        #   LIMIT <limit>
+        #   LIMIT <offset>, <limit>
+        # and in server versions > 3.3:
+        #   LIMIT <limit> OFFSET <offset>
+        # The latter is more readable for offsets but we're stuck with the
+        # former until we can refine dialects by server revision.
+
+        limit, offset = select._limit, select._offset
+
+        if (limit, offset) == (None, None):
+            return ''
+        elif offset is not None:
+            # As suggested by the MySQL docs, need to apply an
+            # artificial limit if one wasn't provided
+            if limit is None:
+                limit = 18446744073709551615
+            return ' \n LIMIT %s, %s' % (offset, limit)
+        else:
+            # No offset provided, so just use the limit
+            return ' \n LIMIT %s' % (limit,)
+
 
 # ug.  "InnoDB needs indexes on foreign keys and referenced keys [...].
 #       Starting with MySQL 4.1.2, these indexes are created automatically.
index 1482056ab817e88748d5029c87ac6a8b4b7c5248..92d93b8d538d1bece7b2f018087871360e9d0aa2 100644 (file)
@@ -569,9 +569,12 @@ class TypesTest(AssertMixin):
         enum_table.drop()
 
     @testing.supported('mysql')
+    @testing.exclude('mysql', '>', (3))
     def test_enum_parse(self):
         """More exercises for the ENUM type."""
-        
+
+        # MySQL 3.23 can't handle an ENUM of ''....
+
         db = testbase.db
         enum_table = Table('mysql_enum', MetaData(testbase.db),
             Column('e1', mysql.MSEnum("'a'")),
@@ -727,8 +730,9 @@ class TypesTest(AssertMixin):
         self.assertEqual(got, wanted)
 
 
-class SQLTest(AssertMixin):
+class SQLTest(SQLCompileTest):
     """Tests MySQL-dialect specific compilation."""
+    __dialect__ = testbase.db.dialect
 
     @testing.supported('mysql')
     def test_precolumns(self):
@@ -763,6 +767,22 @@ class SQLTest(AssertMixin):
             gen(True, ['high_priority', sql.text('sql_cache')]),
             'SELECT high_priority sql_cache DISTINCT q')
 
+    @testing.supported('mysql')
+    def test_limit(self):
+        t = sql.table('t', sql.column('col1'), sql.column('col2'))
+        
+        self.assert_compile(
+            select([t]).limit(10).offset(20),
+            "SELECT t.col1, t.col2 FROM t  LIMIT 20, 10"
+            )
+        self.assert_compile(
+            select([t]).limit(10),
+            "SELECT t.col1, t.col2 FROM t  LIMIT 10")
+        self.assert_compile(
+            select([t]).offset(10),
+            "SELECT t.col1, t.col2 FROM t  LIMIT 10, 18446744073709551615"
+            )
+
 
 def colspec(c):
     return testbase.db.dialect.schemagenerator(testbase.db.dialect,