diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-06-27 19:25:35 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-06-27 19:25:35 -0400 |
commit | 668991a7ed3a46e29ab76cd0278b021e5190b103 (patch) | |
tree | b15a912e26af60a5f5134c94baffa560b1915276 /lib/sqlalchemy/sql/util.py | |
parent | 63dbed1fd7421fd4f5cbf0bb2773f7faa8359651 (diff) | |
download | sqlalchemy-668991a7ed3a46e29ab76cd0278b021e5190b103.tar.gz |
- Fixed subtle bug that caused SQL to blow
up if: column_property() against subquery +
joinedload + LIMIT + order by the column
property() occurred. [ticket:2188].
Also in 0.6.9
Diffstat (limited to 'lib/sqlalchemy/sql/util.py')
-rw-r--r-- | lib/sqlalchemy/sql/util.py | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 1a3f7d2f8..f003a9691 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -8,6 +8,7 @@ from sqlalchemy import exc, schema, util, sql, types as sqltypes from sqlalchemy.util import topological from sqlalchemy.sql import expression, operators, visitors from itertools import chain +from collections import deque """Utility functions that build upon SQL and Schema constructs.""" @@ -99,6 +100,25 @@ def find_columns(clause): visitors.traverse(clause, {}, {'column':cols.add}) return cols +def unwrap_order_by(clause): + """Break up an 'order by' expression into individual column-expressions, + without DESC/ASC/NULLS FIRST/NULLS LAST""" + + cols = util.column_set() + stack = deque([clause]) + while stack: + t = stack.popleft() + if isinstance(t, expression.ColumnElement) and \ + ( + not isinstance(t, expression._UnaryExpression) or \ + not operators.is_ordering_modifier(t.modifier) + ): + cols.add(t) + else: + for c in t.get_children(): + stack.append(c) + return cols + def clause_is_present(clause, search): """Given a target clause and a second to search within, return True if the target is plainly present in the search without any @@ -624,11 +644,15 @@ class ClauseAdapter(visitors.ReplacingCloningVisitor): self.equivalents = util.column_dict(equivalents or {}) def _corresponding_column(self, col, require_embedded, _seen=util.EMPTY_SET): - newcol = self.selectable.corresponding_column(col, require_embedded=require_embedded) + newcol = self.selectable.corresponding_column( + col, + require_embedded=require_embedded) if newcol is None and col in self.equivalents and col not in _seen: for equiv in self.equivalents[col]: - newcol = self._corresponding_column(equiv, require_embedded=require_embedded, _seen=_seen.union([col])) + newcol = self._corresponding_column(equiv, + require_embedded=require_embedded, + _seen=_seen.union([col])) if newcol is not None: return newcol return newcol |