]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed a column arithmetic bug that affected column
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 3 Jan 2010 20:57:37 +0000 (20:57 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 3 Jan 2010 20:57:37 +0000 (20:57 +0000)
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]

CHANGES
lib/sqlalchemy/sql/expression.py
test/orm/test_query.py
test/sql/test_selectable.py

diff --git a/CHANGES b/CHANGES
index 140bd058c930d86f05f4d1318b1b4af18d25f6e2..db6a7e6735bc4eea67034da0a664360012efdc28 100644 (file)
--- 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
index 842e76d15943b38a23dda4cdaef4743a0e4ed5fc..43b22fc8e1d3f52a29292e54e59fd551b23b5925 100644 (file)
@@ -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)):
                 
index 0d98417f6d9e6cfdde5b0466ac3448e8e28d5033..967d1ac6cbb51c93be036e1d34a132141f17d5bc 100644 (file)
@@ -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):
     
index 147e47cd963bd28fb401b19b6ae150fb5ccac831..f5f61aab136c3ae710d891a66cfa40878d156f48 100644 (file)
@@ -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