]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- [bug] Fixed compiler bug whereby a given
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 13 Aug 2012 01:07:24 +0000 (21:07 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 13 Aug 2012 01:07:24 +0000 (21:07 -0400)
select() would be modified if it had an "offset"
attribute, causing the construct to not compile
correctly a second time.  [ticket:2545]

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

diff --git a/CHANGES b/CHANGES
index f725df5f2cd20f55ed1f2b6e20fec0e9155812ce..9fceb394207dd4af5f68bccd161093ee64ee61ae 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -91,6 +91,12 @@ CHANGES
     the "name" and "native_enum" flags.  Helps
     Alembic autogenerate.
 
+- mssql
+  - [bug] Fixed compiler bug whereby a given
+    select() would be modified if it had an "offset"
+    attribute, causing the construct to not compile
+    correctly a second time.  [ticket:2545]
+
 0.7.8
 =====
 - orm
index 063fc2c36d3381dd0728978f1d013ddbe41108b9..816be76b19501f8508311b9aca277894d0853fa3 100644 (file)
@@ -809,7 +809,7 @@ class MSSQLCompiler(compiler.SQLCompiler):
         so tries to wrap it in a subquery with ``row_number()`` criterion.
 
         """
-        if not getattr(select, '_mssql_visit', None) and select._offset:
+        if select._offset and not getattr(select, '_mssql_visit', None):
             # to use ROW_NUMBER(), an ORDER BY is required.
             orderby = self.process(select._order_by_clause)
             if not orderby:
@@ -818,6 +818,7 @@ class MSSQLCompiler(compiler.SQLCompiler):
 
             _offset = select._offset
             _limit = select._limit
+            select = select._generate()
             select._mssql_visit = True
             select = select.column(
                 sql.literal_column("ROW_NUMBER() OVER (ORDER BY %s)" \
@@ -826,10 +827,10 @@ class MSSQLCompiler(compiler.SQLCompiler):
 
             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> _offset)
+                                        c.key != 'mssql_rn'])
+            limitselect.append_whereclause(mssql_rn > _offset)
             if _limit is not None:
-                limitselect.append_whereclause(mssql_rn<=(_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 87d433cfba069a5fa30a032d1c16272c357da30d..68d1862f6f924ea4f50c797b00ec082a311843f7 100644 (file)
@@ -566,7 +566,7 @@ class OracleCompiler(compiler.SQLCompiler):
                     if not self.dialect.use_binds_for_limits:
                         max_row = sql.literal_column("%d" % max_row)
                     limitselect.append_whereclause(
-                            sql.literal_column("ROWNUM")<=max_row)
+                            sql.literal_column("ROWNUM") <= max_row)
 
                 # If needed, add the ora_rn, and wrap again with offset.
                 if select._offset is None:
index 7bfe480c3b5487c94fe5623f1b09fef153f1749d..7285e9636471fc6700d3f102f76ed66a9c631856 100644 (file)
@@ -427,14 +427,17 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
 
         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",
-            checkparams={u'mssql_rn_1': 20, u'x_1': 5}
-        )
+        # test that the select is not altered with subsequent compile
+        # calls
+        for i in xrange(2):
+            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",
+                checkparams={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))