summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/expression.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-02-29 17:47:59 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2012-02-29 17:47:59 -0500
commit0536c48dafb670d34fc96d26078b41ed6accf01f (patch)
treeb3109ed91ac61e5ddbe8c77c5a1e0bf3e08c0f51 /lib/sqlalchemy/sql/expression.py
parentcd655cf0996de682365201a0184170256da6859b (diff)
downloadsqlalchemy-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.py22
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