From b3817dc8c218b0fd5a60a9cf8b21a04395f59599 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 15 May 2007 16:43:26 +0000 Subject: [PATCH] - fix to polymorphic query which allows the original polymorphic_union to be embedded into a correlated subquery [ticket:577] --- CHANGES | 2 ++ lib/sqlalchemy/orm/query.py | 6 +++--- test/orm/inheritance5.py | 10 +++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 6e44a2e09c..277f57e2f0 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,8 @@ from the association table by a delete operation matches the expected results - session.get() and session.load() propigate **kwargs through to query + - fix to polymorphic query which allows the original polymorphic_union + to be embedded into a correlated subquery [ticket:577] - mysql - support for column-level CHARACTER SET and COLLATE declarations, as well as ASCII, UNICODE, NATIONAL and BINARY shorthand. diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index be299d2005..38279f5f21 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -967,7 +967,7 @@ class Query(object): # adapt the given WHERECLAUSE to adjust instances of this query's mapped # table to be that of our select_table, # which may be the "polymorphic" selectable used by our mapper. - sql_util.ClauseAdapter(self.table).traverse(whereclause) + sql_util.ClauseAdapter(self.table).traverse(whereclause, stop_on=util.Set([self.table])) # if extra entities, adapt the criterion to those as well for m in self._entities: @@ -975,7 +975,7 @@ class Query(object): m = mapper.class_mapper(m) if isinstance(m, mapper.Mapper): table = m.select_table - sql_util.ClauseAdapter(m.select_table).traverse(whereclause) + sql_util.ClauseAdapter(m.select_table).traverse(whereclause, stop_on=util.Set([m.select_table])) # get/create query context. get the ultimate compile arguments # from there @@ -1050,7 +1050,7 @@ class Query(object): # it has no relations() on it. should we compile those too into the query ? (i.e. eagerloads) for value in self.select_mapper.props.values(): value.setup(context) - + # additional entities/columns, add those to selection criterion for m in self._entities: if isinstance(m, type): diff --git a/test/orm/inheritance5.py b/test/orm/inheritance5.py index 6575304056..43f1fa3ca8 100644 --- a/test/orm/inheritance5.py +++ b/test/orm/inheritance5.py @@ -672,6 +672,8 @@ class GenerativeTest(testbase.AssertMixin): session.save(dead) session.flush() + # TODO: we haven't created assertions for all the data combinations created here + # creating 5 managers named from M1 to M5 and 5 engineers named from E1 to E5 # M4, M5, E4 and E5 are dead for i in range(1,5): @@ -694,12 +696,18 @@ class GenerativeTest(testbase.AssertMixin): session.save(car2) session.flush() - # test these twice because theres caching involved + # test these twice because theres caching involved, as well previous issues that modified the polymorphic union for x in range(0, 2): r = session.query(Person).filter_by(people.c.name.like('%2')).join('status').filter_by(name="active") assert str(list(r)) == "[Manager M2, category YYYYYYYYY, status Status active, Engineer E2, field X, status Status active]" r = session.query(Engineer).join('status').filter(people.c.name.in_('E2', 'E3', 'E4', 'M4', 'M2', 'M1') & (status.c.name=="active")) assert str(list(r)) == "[Engineer E2, field X, status Status active, Engineer E3, field X, status Status active]" + # this test embeds the original polymorphic union (employee_join) fully + # into the WHERE criterion, using a correlated select. ticket #577 tracks + # that Query's adaptation of the WHERE clause does not dig into the + # mapped selectable itself, which permanently breaks the mapped selectable. + r = session.query(Person).filter(Car.c.owner == select([Car.c.owner], Car.c.owner==employee_join.c.person_id)) + assert str(list(r)) == "[Engineer E4, field X, status Status dead]" class MultiLevelTest(testbase.ORMTest): def define_tables(self, metadata): -- 2.47.2