summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES10
-rw-r--r--lib/sqlalchemy/sql/expression.py3
-rw-r--r--test/orm/test_query.py15
-rw-r--r--test/sql/test_selectable.py13
4 files changed, 39 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index 140bd058c..db6a7e673 100644
--- a/CHANGES
+++ b/CHANGES
@@ -799,7 +799,15 @@ CHANGES
unnamed Column objects. This allows easy creation of
declarative helpers which place common columns on multiple
subclasses.
-
+
+ - Fixed a column arithmetic bug that affected column
+ correspondence for cloned selectables which contain
+ free-standing column expressions. This bug is
+ generally only noticeable when exercising newer
+ ORM behavior only availble in 0.6 via [ticket:1568],
+ but is more correct at the SQL expression level
+ as well. [ticket:1617]
+
- postgresql
- The extract() function, which was slightly improved in
0.5.7, needed a lot more work to generate the correct
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index 842e76d15..43b22fc8e 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -1967,7 +1967,8 @@ class FromClause(Selectable):
target_set = column.proxy_set
cols = self.c
for c in cols:
- i = c.proxy_set.intersection(target_set)
+ i = target_set.intersection(itertools.chain(*[p._cloned_set for p in c.proxy_set]))
+
if i and \
(not require_embedded or c.proxy_set.issuperset(target_set)):
diff --git a/test/orm/test_query.py b/test/orm/test_query.py
index 0d98417f6..967d1ac6c 100644
--- a/test/orm/test_query.py
+++ b/test/orm/test_query.py
@@ -921,6 +921,21 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL):
# order_by(User.id, Address.id).first(),
(User(id=8, addresses=[Address(), Address(), Address()]), Address(id=2)),
)
+
+ def test_multiple_with_column_entities(self):
+ sess = create_session()
+
+ eq_(
+ sess.query(User.id).from_self().\
+ add_column(func.count().label('foo')).\
+ group_by(User.id).\
+ from_self().all(),
+ [
+ (7,1), (8, 1), (9, 1), (10, 1)
+ ]
+
+ )
+
class SetOpsTest(QueryTest, AssertsCompiledSQL):
diff --git a/test/sql/test_selectable.py b/test/sql/test_selectable.py
index 147e47cd9..f5f61aab1 100644
--- a/test/sql/test_selectable.py
+++ b/test/sql/test_selectable.py
@@ -57,7 +57,20 @@ class SelectableTest(TestBase, AssertsExecutionResults):
# test alias of the join
j2 = jjj.alias('foo')
assert j2.corresponding_column(table1.c.col1) is j2.c.table1_col1
+
+ def test_against_cloned_non_table(self):
+ # test that corresponding column digs across
+ # clone boundaries with anonymous labeled elements
+ col = func.count().label('foo')
+ sel = select([col])
+
+ sel2 = visitors.ReplacingCloningVisitor().traverse(sel)
+ assert sel2.corresponding_column(col) is sel2.c.foo
+ sel3 = visitors.ReplacingCloningVisitor().traverse(sel2)
+ assert sel3.corresponding_column(col) is sel3.c.foo
+
+
def test_select_on_table(self):
sel = select([table1, table2], use_labels=True)
assert sel.corresponding_column(table1.c.col1) is sel.c.table1_col1