]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- add changelog/migration note
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 3 Jun 2013 19:38:08 +0000 (15:38 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 3 Jun 2013 19:38:08 +0000 (15:38 -0400)
- inline the label check

doc/build/changelog/changelog_09.rst
doc/build/changelog/migration_09.rst
lib/sqlalchemy/sql/compiler.py

index 124946b1116ba32f9a4ce61fade393ad7b42ce01..df87f397cda81fe4284ff1121d307172660b127b 100644 (file)
@@ -6,6 +6,17 @@
 .. changelog::
     :version: 0.9.0
 
+    .. change::
+        :tags: feature, sql
+        :tickets: 1068
+
+        A :class:`.Label` construct will now render as its name alone
+        in an ``ORDER BY`` clause, if that label is also referred to
+        in the columns clause of the select, instead of rewriting the
+        full expression.  This gives the database a better chance to
+        optimize the evaulation of the same expression in two different
+        contexts.
+
     .. change::
         :tags: feature, firebird
         :tickets: 2504
index 3d7b303241501eb38b93b28949a26379f019d59d..03c84d8d954ec3512856bd91ef4266323f259cc0 100644 (file)
@@ -124,6 +124,48 @@ to 0.9 without issue.
 :ticket:`2736`
 
 
+Behavioral Improvements
+=======================
+
+Improvements that should produce no compatibility issues, but are good
+to be aware of in case there are unexpected issues.
+
+Label constructs can now render as their name alone in an ORDER BY
+------------------------------------------------------------------
+
+For the case where a :class:`.Label` is used in both the columns clause
+as well as the ORDER BY clause of a SELECT, the label will render as
+just it's name in the ORDER BY clause, assuming the underlying dialect
+reports support of this feature.
+
+E.g. an example like::
+
+       from sqlalchemy.sql import table, column, select, func
+
+       t = table('t', column('c1'), column('c2'))
+       expr = (func.foo(t.c.c1) + t.c.c2).label("expr")
+
+       stmt = select([expr]).order_by(expr)
+
+       print stmt
+
+Prior to 0.9 would render as::
+
+       SELECT foo(t.c1) + t.c2 AS expr
+       FROM t ORDER BY foo(t.c1) + t.c2
+
+And now        renders as::
+
+       SELECT foo(t.c1) + t.c2 AS expr
+       FROM t ORDER BY expr
+
+The ORDER BY only renders the label if the label isn't further embedded into an expression within the ORDER BY, other than a simple ``ASC`` or ``DESC``.
+
+The above format works on all databases tested, but might have compatibility issues with older database versions (MySQL 4?  Oracle 8? etc.).   Based on user reports we can add rules
+that will disable the feature based on database version detection.
+
+:ticket:`1068`
+
 Dialect Changes
 ===============
 
index d475f54ac0e94869cf0587f1efed519f2e6bd2a3..73b094053c878a3a724f3bffbab938fcda32ccad 100644 (file)
@@ -516,7 +516,9 @@ class SQLCompiler(engine.Compiled):
 
     def visit_clauselist(self, clauselist, order_by_select=None, **kw):
         if order_by_select is not None:
-            return self._order_by_clauselist(clauselist, order_by_select, **kw)
+            return self._order_by_clauselist(
+                                    clauselist, order_by_select, **kw)
+
         sep = clauselist.operator
         if sep is None:
             sep = " "
@@ -538,19 +540,17 @@ class SQLCompiler(engine.Compiled):
         raw_col = set(l._order_by_label_element.name
                         for l in order_by_select._raw_columns
                         if l._order_by_label_element is not None)
-        def label_ok(c):
-            if c._order_by_label_element is not None and \
-                c._order_by_label_element.name in raw_col:
-                return c._order_by_label_element
-            else:
-                return None
 
         return ", ".join(
                     s for s in
                     (
                         c._compiler_dispatch(self,
-                                render_label_as_label=label_ok(c),
-                                **kw)
+                            render_label_as_label=
+                                c._order_by_label_element if
+                                    c._order_by_label_element is not None and
+                                    c._order_by_label_element.name in raw_col
+                                else None,
+                            **kw)
                         for c in clauselist.clauses)
                     if s)