]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- repair MS-SQL handling of LIMIT/OFFSET as binds, add bindparam() to the compile...
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 29 Nov 2010 22:28:36 +0000 (17:28 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 29 Nov 2010 22:28:36 +0000 (17:28 -0500)
so they function correctly

lib/sqlalchemy/dialects/mssql/base.py
test/dialect/test_mssql.py

index fc374c5953a714660485279daeb583a30d2d0fbd..7dd7400ea60408b6e72ed0cb8e58e2b32c9da936 100644 (file)
@@ -740,13 +740,13 @@ class MSSQLCompiler(compiler.SQLCompiler):
                 sql.literal_column("ROW_NUMBER() OVER (ORDER BY %s)" \
                 % orderby).label("mssql_rn")
                                    ).order_by(None).alias()
-
+            
+            mssql_rn = sql.column('mssql_rn')
             limitselect = sql.select([c for c in select.c if
                                         c.key!='mssql_rn'])
-            limitselect.append_whereclause("mssql_rn>%s" % self.process(sql.literal(_offset)))
+            limitselect.append_whereclause(mssql_rn> _offset)
             if _limit is not None:
-                limitselect.append_whereclause("mssql_rn<=%s" % 
-                                            (self.process(sql.literal(_limit + _offset))))
+                limitselect.append_whereclause(mssql_rn<=(_limit + _offset))
             return self.process(limitselect, iswrapper=True, **kwargs)
         else:
             return compiler.SQLCompiler.visit_select(self, select, **kwargs)
index 26c53298c694c5f5c0f023c27d00849354d1b618..63aa874fd0ce26d754c287c61131b8f1ddabb780 100644 (file)
@@ -334,7 +334,49 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'LEN(inserted.name) AS length_1 VALUES '
                             '(:name)')
 
+    def test_limit_using_top(self):
+        t = table('t', column('x', Integer), column('y', Integer))
+        
+        s = select([t]).where(t.c.x==5).order_by(t.c.y).limit(10)
+        
+        self.assert_compile(
+            s,
+            "SELECT TOP 10 t.x, t.y FROM t WHERE t.x = :x_1 ORDER BY t.y",
+            {u'x_1': 5}
+        )
+
+    def test_offset_using_window(self):
+        t = table('t', column('x', Integer), column('y', Integer))
+        
+        s = select([t]).where(t.c.x==5).order_by(t.c.y).offset(20)
+        
+        self.assert_compile(
+            s,
+            "SELECT anon_1.x, anon_1.y FROM (SELECT t.x AS x, t.y "
+            "AS y, ROW_NUMBER() OVER (ORDER BY t.y) AS "
+            "mssql_rn FROM t WHERE t.x = :x_1) AS "
+            "anon_1 WHERE mssql_rn > :mssql_rn_1",
+            {u'mssql_rn_1': 20, u'x_1': 5}
+        )
 
+    def test_limit_offset_using_window(self):
+        t = table('t', column('x', Integer), column('y', Integer))
+        
+        s = select([t]).where(t.c.x==5).order_by(t.c.y).limit(10).offset(20)
+        
+        self.assert_compile(
+            s,
+            "SELECT anon_1.x, anon_1.y "
+            "FROM (SELECT t.x AS x, t.y AS y, "
+            "ROW_NUMBER() OVER (ORDER BY t.y) AS mssql_rn "
+            "FROM t "
+            "WHERE t.x = :x_1) AS anon_1 "
+            "WHERE mssql_rn > :mssql_rn_1 AND mssql_rn <= :mssql_rn_2",
+            {u'mssql_rn_1': 20, u'mssql_rn_2': 30, u'x_1': 5}
+        )
+        
+        
+        
 class IdentityInsertTest(TestBase, AssertsCompiledSQL):
     __only_on__ = 'mssql'
     __dialect__ = mssql.MSDialect()