From 6636cd9d256ccbad651eba6553ec46391380cc93 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 1 Jul 2019 22:33:26 -0400 Subject: Clear proxy_set cache when creating an annotated column Fixed an unlikely issue where the "corresponding column" routine for unions and other :class:`.CompoundSelect` objects could return the wrong column in some overlapping column situtations, thus potentially impacting some ORM operations when set operations are in use, if the underlying :func:`.select` constructs were used previously in other similar kinds of routines, due to a cached value not being cleared. Fixes: #4747 Change-Id: I7fb134cac3604f8fe62e220fb24a0945d0a1c56f --- test/sql/test_selectable.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'test/sql/test_selectable.py') diff --git a/test/sql/test_selectable.py b/test/sql/test_selectable.py index bfa96d766..1a53cd1d6 100644 --- a/test/sql/test_selectable.py +++ b/test/sql/test_selectable.py @@ -433,6 +433,18 @@ class SelectableTest( assert u1.corresponding_column(table1.c.colx) is u1.c.col2 assert u1.corresponding_column(table1.c.col3) is u1.c.col1 + def test_proxy_set_pollution(self): + s1 = select([table1.c.col1, table1.c.col2]) + s2 = select([table1.c.col2, table1.c.col1]) + + for c in s1.c: + c.proxy_set + for c in s2.c: + c.proxy_set + + u1 = union(s1, s2) + assert u1.corresponding_column(table1.c.col2) is u1.c.col2 + def test_singular_union(self): u = union( select([table1.c.col1, table1.c.col2, table1.c.col3]), @@ -1936,6 +1948,27 @@ class AnnotationsTest(fixtures.TestBase): assert x_p.compare(x_p_a) assert not x_p_a.compare(x_a) + def test_proxy_set_iteration_includes_annotated(self): + from sqlalchemy.schema import Column + + c1 = Column("foo", Integer) + + stmt = select([c1]).alias() + proxy = stmt.c.foo + + proxy.proxy_set + + # create an annotated of the column + p2 = proxy._annotate({"weight": 10}) + + # now see if our annotated version is in that column's + # proxy_set, as corresponding_column iterates through proxy_set + # in this way + d = {} + for col in p2.proxy_set: + d.update(col._annotations) + eq_(d, {"weight": 10}) + def test_late_name_add(self): from sqlalchemy.schema import Column -- cgit v1.2.1