Repaired an issue where the "ORDER BY" clause rendering a label name rather
than a complete expression, which is particularly important for SQL Server,
would fail to occur if the expression were enclosed in a parenthesized
- grouping in some cases. This case has been added to test support.
-
+ grouping in some cases. This case has been added to test support. The
+ change additionally adjusts the "automatically add ORDER BY columns when
+ DISTINCT is present" behavior of ORM query, deprecated in 1.4, to more
+ accurately detect column expressions that are already present.
from .elements import BindParameter
from .elements import ColumnClause
from .elements import ColumnElement
+from .elements import Grouping
+from .elements import Label
from .elements import Null
from .elements import UnaryExpression
from .schema import Column
not isinstance(t, UnaryExpression)
or not operators.is_ordering_modifier(t.modifier)
):
+ if isinstance(t, Label) and not isinstance(
+ t.element, ScalarSelect
+ ):
+ t = t.element
+
+ if isinstance(t, Grouping):
+ t = t.element
+
+ stack.append(t)
+ continue
+
if isinstance(t, _label_reference):
t = t.element
if isinstance(t, (_textual_label_reference)):
]
)
- return [
- col
- for col in chain(*[unwrap_order_by(o) for o in order_by])
- if col not in cols_already_present
- ]
+ to_look_for = list(chain(*[unwrap_order_by(o) for o in order_by]))
+
+ return [col for col in to_look_for if col not in cols_already_present]
def clause_is_present(clause, search):
import sqlalchemy as sa
from sqlalchemy import and_
+from sqlalchemy import asc
from sqlalchemy import between
from sqlalchemy import bindparam
from sqlalchemy import Boolean
.all(),
)
+ def test_issue_5470_one(self):
+ User = self.classes.User
+
+ expr = (User.id.op("+")(2)).label("label")
+
+ sess = create_session()
+
+ q = sess.query(expr).select_from(User).order_by(desc(expr)).distinct()
+
+ # no double col in the select list,
+ # orders by the label
+ self.assert_compile(
+ q,
+ "SELECT DISTINCT users.id + :id_1 AS label "
+ "FROM users ORDER BY label DESC",
+ )
+
+ def test_issue_5470_two(self):
+ User = self.classes.User
+
+ expr = User.id + literal(1)
+
+ sess = create_session()
+ q = sess.query(expr).select_from(User).order_by(asc(expr)).distinct()
+
+ # no double col in the select list,
+ # there's no label so this is the requested SQL
+ self.assert_compile(
+ q,
+ "SELECT DISTINCT users.id + :param_1 AS anon_1 "
+ "FROM users ORDER BY users.id + :param_1 ASC",
+ )
+
+ def test_issue_5470_three(self):
+ User = self.classes.User
+
+ expr = (User.id + literal(1)).label("label")
+
+ sess = create_session()
+ q = sess.query(expr).select_from(User).order_by(asc(expr)).distinct()
+
+ # no double col in the select list,
+ # orders by the label
+ self.assert_compile(
+ q,
+ "SELECT DISTINCT users.id + :param_1 AS label "
+ "FROM users ORDER BY label ASC",
+ )
+
+ def test_issue_5470_four(self):
+ User = self.classes.User
+
+ expr = (User.id + literal(1)).label("label")
+
+ sess = create_session()
+ q = (
+ sess.query(expr)
+ .select_from(User)
+ .order_by(asc("label"))
+ .distinct()
+ )
+
+ # no double col in the select list,
+ # orders by the label
+ self.assert_compile(
+ q,
+ "SELECT DISTINCT users.id + :param_1 AS label "
+ "FROM users ORDER BY label ASC",
+ )
+
def test_columns_augmented_roundtrip_one(self):
User, Address = self.classes.User, self.classes.Address