- Column-entities (i.e. query(Foo.id)) copy their

state more fully when queries are derived from
themselves + a selectable (i.e. from_self(),
union(), etc.), so that join() and such have the
correct state to work from.  [ticket:1853]

- Fixed bug where Query.join() would fail if
querying a non-ORM column then joining without
an on clause when a FROM clause is already
present, now raises a checked exception the
same way it does when the clause is not
present.  [ticket:1853]
This commit is contained in:
Mike Bayer
2010-07-15 09:59:17 -04:00
parent 10db67be5b
commit 2bd3c795cf
3 changed files with 73 additions and 2 deletions
+13
View File
@@ -14,6 +14,19 @@ CHANGES
and a delete of the parent has occurred.
[ticket:1845]
- Column-entities (i.e. query(Foo.id)) copy their
state more fully when queries are derived from
themselves + a selectable (i.e. from_self(),
union(), etc.), so that join() and such have the
correct state to work from. [ticket:1853]
- Fixed bug where Query.join() would fail if
querying a non-ORM column then joining without
an on clause when a FROM clause is already
present, now raises a checked exception the
same way it does when the clause is not
present. [ticket:1853]
- Improved the check for an "unmapped class",
including the case where the superclass is mapped
but the subclass is not. Any attempts to access
+4 -2
View File
@@ -1301,7 +1301,7 @@ class Query(object):
join_to_left = not is_aliased_class and not left_is_aliased
if self._from_obj:
if self._from_obj and left_selectable is not None:
replace_clause_index, clause = sql_util.find_join_source(
self._from_obj,
left_selectable)
@@ -2622,7 +2622,9 @@ class _ColumnEntity(_QueryEntity):
return self.column.type
def adapt_to_selectable(self, query, sel):
_ColumnEntity(query, sel.corresponding_column(self.column))
c = _ColumnEntity(query, sel.corresponding_column(self.column))
c.entity_zero = self.entity_zero
c.entities = self.entities
def setup_entity(self, entity, mapper, adapter, from_obj,
is_aliased_class, with_polymorphic):
+56
View File
@@ -2343,6 +2343,44 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
(order3, item3),
]
)
def test_joins_from_adapted_entities(self):
# test for #1853
session = create_session()
first = session.query(User)
second = session.query(User)
unioned = first.union(second)
subquery = session.query(User.id).subquery()
join = subquery, subquery.c.id == User.id
joined = unioned.outerjoin(join)
self.assert_compile(joined,
'SELECT anon_1.users_id AS '
'anon_1_users_id, anon_1.users_name AS '
'anon_1_users_name FROM (SELECT users.id '
'AS users_id, users.name AS users_name '
'FROM users UNION SELECT users.id AS '
'users_id, users.name AS users_name FROM '
'users) AS anon_1 LEFT OUTER JOIN (SELECT '
'users.id AS id FROM users) AS anon_2 ON '
'anon_2.id = anon_1.users_id',
use_default_dialect=True)
first = session.query(User.id)
second = session.query(User.id)
unioned = first.union(second)
subquery = session.query(User.id).subquery()
join = subquery, subquery.c.id == User.id
joined = unioned.outerjoin(join)
self.assert_compile(joined,
'SELECT anon_1.users_id AS anon_1_users_id '
'FROM (SELECT users.id AS users_id FROM '
'users UNION SELECT users.id AS users_id '
'FROM users) AS anon_1 LEFT OUTER JOIN '
'(SELECT users.id AS id FROM users) AS '
'anon_2 ON anon_2.id = anon_1.users_id',
use_default_dialect=True)
def test_reset_joinpoint(self):
for aliased in (True, False):
@@ -2422,6 +2460,24 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
sess.query(User.name).join((addresses, User.id==addresses.c.user_id)).order_by(User.id).all(),
[(u'jack',), (u'ed',), (u'ed',), (u'ed',), (u'fred',)]
)
def test_no_joinpoint_expr(self):
sess = create_session()
# these are consistent regardless of
# select_from() being present.
assert_raises_message(
sa_exc.InvalidRequestError,
"Could not find a FROM",
sess.query(users.c.id).join, User
)
assert_raises_message(
sa_exc.InvalidRequestError,
"Could not find a FROM",
sess.query(users.c.id).select_from(users).join, User
)
def test_from_self_resets_joinpaths(self):
"""test a join from from_self() doesn't confuse joins inside the subquery