]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
magic accessors to the rescue
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 28 May 2013 01:43:29 +0000 (21:43 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 28 May 2013 01:43:29 +0000 (21:43 -0400)
lib/sqlalchemy/sql/compiler.py
lib/sqlalchemy/sql/expression.py
test/sql/test_compiler.py

index 5fbfa34f3d35c4b82337cf939c94f6f928e2d2a7..5dd7ec564c0e0f9fefaefb199b1b94cea7b76ff2 100644 (file)
@@ -536,14 +536,14 @@ class SQLCompiler(engine.Compiled):
         # note that its OK we aren't expanding tables and other selectables
         # here; we can only add a label in the ORDER BY for an individual
         # label expression in the columns clause.
-        raw_col = set(order_by_select._raw_columns)
+
+        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 in raw_col:
-                return c
-            elif getattr(c, 'modifier', None) in \
-                    (operators.desc_op, operators.asc_op) and \
-                    c.element.proxy_set.intersection(raw_col):
-                return c.element
+            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
 
index 3f9aef2b7835052e8cbc63d9713cdbdd13457a27..402e522725456d3db55f7b20ced7d68f8a159540 100644 (file)
@@ -1659,6 +1659,8 @@ class ClauseElement(Visitable):
     is_selectable = False
     is_clause_element = True
 
+    _order_by_label_element = None
+
     def _clone(self):
         """Create a shallow copy of this ClauseElement.
 
@@ -3690,6 +3692,13 @@ class UnaryExpression(ColumnElement):
         self.type = sqltypes.to_instance(type_)
         self.negate = negate
 
+    @util.memoized_property
+    def _order_by_label_element(self):
+        if self.modifier in (operators.desc_op, operators.asc_op):
+            return self.element._order_by_label_element
+        else:
+            return None
+
     @property
     def _from_objects(self):
         return self.element._from_objects
@@ -4326,6 +4335,10 @@ class Label(ColumnElement):
         self.quote = element.quote
         self._proxies = [element]
 
+    @util.memoized_property
+    def _order_by_label_element(self):
+        return self
+
     @util.memoized_property
     def type(self):
         return sqltypes.to_instance(
index d5f52bdf3557755b90f16150ba68ed9ea29c9323..83a02a49e571e4d78ca8b92199b5f30ae38996fd 100644 (file)
@@ -746,19 +746,6 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL):
                 'foo || :param_1')
 
 
-    def test_foo(self):
-        lx = (table1.c.myid + table1.c.myid).label('lx')
-        ly = (func.lower(table1.c.name) + table1.c.description).label('ly')
-        dialect = default.DefaultDialect()
-
-        self.assert_compile(
-            select([lx, ly]).order_by(lx, ly.desc()),
-            "SELECT mytable.myid + mytable.myid AS lx, "
-            "lower(mytable.name) || mytable.description AS ly "
-            "FROM mytable ORDER BY lx, ly DESC",
-            dialect=dialect
-            )
-
     def test_labels_in_expressions(self):
         lab1 = (table1.c.myid + 12).label('foo')
         lab2 = func.somefunc(table1.c.name).label('bar')