Mike Bayer avatar Mike Bayer committed 6294262

- [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]

Comments (0)

Files changed (4)

     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

lib/sqlalchemy/dialects/mssql/base.py

         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:
 
             _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)" \
 
             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)

lib/sqlalchemy/dialects/oracle/base.py

                     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:

test/dialect/test_mssql.py

 
         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))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.