mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-29 20:14:55 -04:00
- repair MS-SQL handling of LIMIT/OFFSET as binds, add bindparam() to the compile stream
so they function correctly
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user