From: Mike Bayer Date: Thu, 11 Mar 2010 17:07:08 +0000 (-0500) Subject: - fixed internal error which would occur if calling has() X-Git-Tag: rel_0_6beta2~57^2~16^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=86df449c2b724341f3d3f322ad71252b287e1f12;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - fixed internal error which would occur if calling has() or similar complex expression on a single-table inheritance relation(). [ticket:1731] --- diff --git a/CHANGES b/CHANGES index a7457e6d31..fe9f32396b 100644 --- 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 diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 43673eaec5..1b90a457fc 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -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()) diff --git a/test/sql/test_generative.py b/test/sql/test_generative.py index c31a24b93c..a6f8c59560 100644 --- a/test/sql/test_generative.py +++ b/test/sql/test_generative.py @@ -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() diff --git a/test/sql/test_selectable.py b/test/sql/test_selectable.py index f5f61aab13..78455e6d6e 100644 --- a/test/sql/test_selectable.py +++ b/test/sql/test_selectable.py @@ -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"))