diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-02-29 17:47:59 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-02-29 17:47:59 -0500 |
commit | 0536c48dafb670d34fc96d26078b41ed6accf01f (patch) | |
tree | b3109ed91ac61e5ddbe8c77c5a1e0bf3e08c0f51 /lib/sqlalchemy/sql/expression.py | |
parent | cd655cf0996de682365201a0184170256da6859b (diff) | |
download | sqlalchemy-0536c48dafb670d34fc96d26078b41ed6accf01f.tar.gz |
- expand the check to determine if a selectable column is embedded
in the corresponding selectable to take into account clones
of the target column. fixes [ticket:2419]
- have _make_proxy() copy out the _is_clone_of attribute on the
new column so that even more corresponding_column() checks
work as expected for cloned elements.
- add a new test fixture so that mapped tests can be specified
using declarative.
Diffstat (limited to 'lib/sqlalchemy/sql/expression.py')
-rw-r--r-- | lib/sqlalchemy/sql/expression.py | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index b11e5ad42..4b61e6dc3 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -1508,6 +1508,7 @@ class ClauseElement(Visitable): supports_execution = False _from_objects = [] bind = None + _is_clone_of = None def _clone(self): """Create a shallow copy of this ClauseElement. @@ -1556,7 +1557,7 @@ class ClauseElement(Visitable): f = self while f is not None: s.add(f) - f = getattr(f, '_is_clone_of', None) + f = f._is_clone_of return s def __getstate__(self): @@ -2158,6 +2159,9 @@ class ColumnElement(ClauseElement, _CompareMixin): type_=getattr(self, 'type', None)) co.proxies = [self] + if selectable._is_clone_of is not None: + co._is_clone_of = \ + selectable._is_clone_of.columns[key] selectable._columns[key] = co return co @@ -2466,6 +2470,13 @@ class FromClause(Selectable): """ + def embedded(expanded_proxy_set, target_set): + for t in target_set.difference(expanded_proxy_set): + if not set(_expand_cloned([t]) + ).intersection(expanded_proxy_set): + return False + return True + # dont dig around if the column is locally present if self.c.contains_column(column): return column @@ -2473,10 +2484,10 @@ class FromClause(Selectable): target_set = column.proxy_set cols = self.c for c in cols: - i = target_set.intersection(itertools.chain(*[p._cloned_set - for p in c.proxy_set])) + expanded_proxy_set = set(_expand_cloned(c.proxy_set)) + i = target_set.intersection(expanded_proxy_set) if i and (not require_embedded - or c.proxy_set.issuperset(target_set)): + or embedded(expanded_proxy_set, target_set)): if col is None: # no corresponding column yet, pick this one. @@ -4073,6 +4084,9 @@ class ColumnClause(_Immutable, ColumnElement): is_literal=is_literal ) c.proxies = [self] + if selectable._is_clone_of is not None: + c._is_clone_of = \ + selectable._is_clone_of.columns[c.name] if attach: selectable._columns[c.name] = c |