From: Mike Bayer Date: Mon, 3 Jun 2013 19:38:08 +0000 (-0400) Subject: - add changelog/migration note X-Git-Tag: rel_0_9_0b1~301 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f8325d9dbb52d0da140f3403ce915645ae4a5a9c;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - add changelog/migration note - inline the label check --- diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 124946b111..df87f397cd 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -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 diff --git a/doc/build/changelog/migration_09.rst b/doc/build/changelog/migration_09.rst index 3d7b303241..03c84d8d95 100644 --- a/doc/build/changelog/migration_09.rst +++ b/doc/build/changelog/migration_09.rst @@ -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 =============== diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index d475f54ac0..73b094053c 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -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)