]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- fixed internal error which would occur if calling has()
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 11 Mar 2010 17:07:08 +0000 (12:07 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 11 Mar 2010 17:07:08 +0000 (12:07 -0500)
or similar complex expression on a single-table inheritance
relation(). [ticket:1731]

CHANGES
lib/sqlalchemy/sql/util.py
test/sql/test_generative.py
test/sql/test_selectable.py

diff --git a/CHANGES b/CHANGES
index a7457e6d3199f7bb1d7b8a77e4381c8f4fbd141b..fe9f32396bf1c543c031656957209aac80e8acd6 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -34,6 +34,10 @@ CHANGES
   - session.merge() works with relations that specifically
     don't include "merge" in their cascade options - the target
     is ignored completely.
+
+  - fixed internal error which would occur if calling has()
+    or similar complex expression on a single-table inheritance
+    relation(). [ticket:1731]
     
   - query.one() no longer applies LIMIT to the query, this to
     ensure that it fully counts all object identities present
index 43673eaec5601aebb182d6da2a37e033be9f98e0..1b90a457fcb41288d6b07b97f952f8d10df9f28d 100644 (file)
@@ -276,7 +276,9 @@ def _deep_annotate(element, annotations, exclude=None):
     def clone(elem):
         # check if element is present in the exclude list.
         # take into account proxying relationships.
-        if exclude and elem.proxy_set.intersection(exclude):
+        if exclude and \
+                    hasattr(elem, 'proxy_set') and \
+                    elem.proxy_set.intersection(exclude):
             elem = elem._clone()
         elif annotations != elem._annotations:
             elem = elem._annotate(annotations.copy())
index c31a24b93cce3ae0fc42cfa9fffe5a171994e0c7..a6f8c5956058a277ff60a23f127b27d18e162790 100644 (file)
@@ -286,6 +286,11 @@ class ClauseTest(TestBase, AssertsCompiledSQL):
         assert u2.compile().params == {'id_param':7}
         assert u3.compile().params == {'id_param':10}
     
+    def test_in(self):
+        expr = t1.c.col1.in_(['foo', 'bar'])
+        expr2 = CloningVisitor().traverse(expr)
+        assert str(expr) == str(expr2)
+        
     def test_adapt_union(self):
         u = union(t1.select().where(t1.c.col1==4), t1.select().where(t1.c.col1==5)).alias()
         
index f5f61aab136c3ae710d891a66cfa40878d156f48..78455e6d6e38e0dbbd3b4045ae3e092925f5f9cf 100644 (file)
@@ -549,6 +549,20 @@ class AnnotationsTest(TestBase):
         b5 = visitors.cloned_traverse(b3, {}, {'binary':visit_binary})
         assert str(b5) == ":bar = table1.col2"
     
+    def test_annotate_expressions(self):
+        table1 = table('table1', column("col1"), column("col2"))
+        
+        for expr, expected in [
+            (table1.c.col1, "table1.col1"),
+            (table1.c.col1 == 5, "table1.col1 = :col1_1"),
+            (table1.c.col1.in_([2,3,4]), "table1.col1 IN (:col1_1, :col1_2, :col1_3)")
+        ]:
+            eq_(str(expr), expected)
+            eq_(str(expr._annotate({})), expected)
+            eq_(str(sql_util._deep_annotate(expr, {})), expected)
+            eq_(str(sql_util._deep_annotate(expr, {}, exclude=[table1.c.col1])), expected)
+        
+        
     def test_deannotate(self):
         table1 = table('table1', column("col1"), column("col2"))