]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
MSSQL: only compile ORDER BY if it will be rendered 4588/head
authorMatt Lewellyn <guruofgentoo@gmail.com>
Wed, 3 Apr 2019 16:20:47 +0000 (12:20 -0400)
committerMatt Lewellyn <guruofgentoo@gmail.com>
Wed, 3 Apr 2019 16:23:54 +0000 (12:23 -0400)
- prevents parameters from being included in lists sent to the DBAPI layer if those positions do not exist in the query
fixes #4587

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

index 992b97188a04dde56183aa3a6107156610a4d09b..507fcfdcb5b5679098a068c748648e251de64c44 100644 (file)
@@ -1753,10 +1753,16 @@ class MSSQLCompiler(compiler.SQLCompiler):
         return ""
 
     def order_by_clause(self, select, **kw):
+        # MSSQL only allows ORDER BY in subqueries if there is a LIMIT
+        if self.is_subquery() and not select._limit:
+            # avoid processing the order by clause if we won't end up
+            # using it, because we don't want all the bind params tacked
+            # onto the positional list if that is what the dbapi requires
+            return ""
+
         order_by = self.process(select._order_by_clause, **kw)
 
-        # MSSQL only allows ORDER BY in subqueries if there is a LIMIT
-        if order_by and (not self.is_subquery() or select._limit):
+        if order_by:
             return " ORDER BY " + order_by
         else:
             return ""
index 9823faa814cc1c7ccd70dbb4f6479fa6fa690d27..26e6d152ccb192663557f078dd9c3e641895c556 100644 (file)
@@ -377,6 +377,36 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             "foo.myid = mytable.myid",
         )
 
+    def test_noorderby_parameters_insubquery(self):
+        """test that the ms-sql dialect does not include ORDER BY
+        positional parameters in subqueries"""
+
+        table1 = table(
+            "mytable",
+            column("myid", Integer),
+            column("name", String),
+            column("description", String),
+        )
+
+        q = select(
+            [table1.c.myid, sql.literal('bar').label('c1')],
+            order_by=[table1.c.name + '-']
+        ).alias("foo")
+        crit = q.c.myid == table1.c.myid
+        dialect = mssql.dialect()
+        dialect.paramstyle = "qmark"
+        dialect.positional = True
+        self.assert_compile(
+            select(["*"], crit),
+            "SELECT * FROM (SELECT mytable.myid AS "
+            "myid, ? AS c1 FROM mytable) AS foo, mytable WHERE "
+            "foo.myid = mytable.myid",
+            dialect=dialect,
+            checkparams={'param_1': 'bar'},
+            # if name_1 is included, too many parameters are passed to dbapi
+            checkpositional=('bar', )
+        )
+
     def test_force_schema_quoted_name_w_dot_case_insensitive(self):
         metadata = MetaData()
         tbl = Table(