summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sqlalchemy/orm/query.py16
-rw-r--r--lib/sqlalchemy/sql/compiler.py11
-rw-r--r--lib/sqlalchemy/sql/expression.py8
-rw-r--r--lib/sqlalchemy/sql/util.py1
-rw-r--r--test/orm/inheritance/test_polymorphic_rel.py25
-rw-r--r--test/orm/test_of_type.py12
6 files changed, 52 insertions, 21 deletions
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index beae7aba0..25ffb0127 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -1862,19 +1862,20 @@ class Query(object):
(right_selectable.description,
right_mapper.mapped_table.description))
- if not isinstance(right_selectable, expression.Alias):
- right_selectable = right_selectable.alias()
+ if not isinstance(right_selectable, expression.Join):
+ if not isinstance(right_selectable, expression.Alias):
+ right_selectable = right_selectable.alias()
+ need_adapter = True
right = aliased(right_mapper, right_selectable)
- need_adapter = True
aliased_entity = right_mapper and \
not right_is_aliased and \
(
- right_mapper.with_polymorphic or
- isinstance(
- right_mapper.mapped_table,
- expression.Join)
+ right_mapper.with_polymorphic
+ #isinstance(
+ # right_mapper.mapped_table,
+ # expression.Join)
)
if not need_adapter and (create_aliases or aliased_entity):
@@ -1946,7 +1947,6 @@ class Query(object):
clause = left_selectable
assert clause is not None
-
try:
clause = orm_join(clause, right, onclause, isouter=outerjoin)
except sa_exc.ArgumentError as ae:
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 030d6dce9..27e883c86 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -1095,14 +1095,19 @@ class SQLCompiler(engine.Compiled):
c._label = c._key_label = c.name
elem.right = selectable
- adapters.append(
- sql_util.ClauseAdapter(selectable,
+ import pdb
+ pdb.set_trace()
+ adapter = sql_util.ClauseAdapter(selectable,
traverse_options=traverse_options)
- )
+ adapter.__traverse_options__.pop('stop_on')
+ adapters.append(adapter)
select = visitors.cloned_traverse(select,
traverse_options, {"join": visit_join})
+ if adapters:
+ import pdb
+ pdb.set_trace()
for adap in reversed(adapters):
select = adap.traverse(select)
return select
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index 5820cb106..edab9e290 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -4212,10 +4212,10 @@ class FromGrouping(FromClause):
@property
def foreign_keys(self):
- # this could be
- # self.element.foreign_keys
- # see SelectableTest.test_join_condition
- return set()
+ return self.element.foreign_keys
+
+ def is_derived_from(self, element):
+ return self.element.is_derived_from(element)
@property
def _hide_froms(self):
diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py
index ffa07d3df..6a267752e 100644
--- a/lib/sqlalchemy/sql/util.py
+++ b/lib/sqlalchemy/sql/util.py
@@ -833,6 +833,7 @@ class ClauseAdapter(visitors.ReplacingCloningVisitor):
return newcol
def replace(self, col):
+ print "COL!", col
if isinstance(col, expression.FromClause) and \
self.selectable.is_derived_from(col):
return self.selectable
diff --git a/test/orm/inheritance/test_polymorphic_rel.py b/test/orm/inheritance/test_polymorphic_rel.py
index 8c1f22114..eecfb036b 100644
--- a/test/orm/inheritance/test_polymorphic_rel.py
+++ b/test/orm/inheritance/test_polymorphic_rel.py
@@ -37,6 +37,7 @@ class _PolymorphicTestBase(object):
e1, e2, e3, b1, m1 = \
cls.e1, cls.e2, cls.e3, cls.b1, cls.m1
+
def test_loads_at_once(self):
"""
Test that all objects load from the full query, when
@@ -672,7 +673,17 @@ class _PolymorphicTestBase(object):
expected)
self.assert_sql_count(testing.db, go, 1)
+ def test_subqueryload_on_subclass(self):
sess = create_session()
+ expected = [
+ Engineer(
+ name="dilbert",
+ engineer_name="dilbert",
+ primary_language="java",
+ status="regular engineer",
+ machines=[
+ Machine(name="IBM ThinkPad"),
+ Machine(name="IPhone")])]
def go():
# test load People with subqueryload to engineers + machines
eq_(sess.query(Person)
@@ -726,6 +737,14 @@ class _PolymorphicTestBase(object):
.join(Engineer.machines).all(),
[c1, c2])
+ def test_join_to_subclass_six_point_five(self):
+ sess = create_session()
+ eq_(sess.query(Company)
+ .join(people.join(engineers), 'employees')
+ .join(Engineer.machines)
+ .filter(Engineer.name == 'dilbert').all(),
+ [c1])
+
def test_join_to_subclass_seven(self):
sess = create_session()
eq_(sess.query(Company)
@@ -898,7 +917,8 @@ class _PolymorphicTestBase(object):
.filter(Paperwork.description.like('%#%')).all(),
[c1, c2])
- def test_explicit_polymorphic_join(self):
+
+ def test_explicit_polymorphic_join_one(self):
sess = create_session()
# join from Company to Engineer; join condition formulated by
@@ -910,6 +930,9 @@ class _PolymorphicTestBase(object):
.filter(Engineer.engineer_name == 'vlad').one(),
c2)
+ def test_explicit_polymorphic_join_two(self):
+ sess = create_session()
+
# same, using explicit join condition. Query.join() must
# adapt the on clause here to match the subquery wrapped around
# "people join engineers".
diff --git a/test/orm/test_of_type.py b/test/orm/test_of_type.py
index 17ffebc3d..150673560 100644
--- a/test/orm/test_of_type.py
+++ b/test/orm/test_of_type.py
@@ -69,12 +69,16 @@ class _PolymorphicTestBase(object):
.filter(Engineer.primary_language == 'java').count(),
1)
+ def test_join_to_subclass_four(self):
+ sess = Session()
# test [ticket:2093]
eq_(sess.query(Company.company_id, Engineer)
.join(Company.employees.of_type(Engineer))
.filter(Engineer.primary_language == 'java').count(),
1)
+ def test_join_to_subclass_five(self):
+ sess = Session()
eq_(sess.query(Company)
.join(Company.employees.of_type(Engineer))
.filter(Engineer.primary_language == 'java').count(),
@@ -185,6 +189,7 @@ class _PolymorphicTestBase(object):
)
self.assert_sql_count(testing.db, go, 3)
+
class PolymorphicPolymorphicTest(_PolymorphicTestBase, _PolymorphicPolymorphic):
def _polymorphic_join_target(self, cls):
from sqlalchemy.orm import class_mapper
@@ -524,11 +529,8 @@ class SubclassRelationshipTest(testing.AssertsCompiledSQL, fixtures.DeclarativeM
self.assert_compile(q,
"SELECT data_container.id AS data_container_id, "
"data_container.name AS data_container_name "
- "FROM data_container JOIN (SELECT job.id AS job_id, "
- "job.type AS job_type, job.container_id AS job_container_id, "
- "subjob.id AS subjob_id, subjob.attr AS subjob_attr "
- "FROM job JOIN subjob ON job.id = subjob.id) AS anon_1 "
- "ON data_container.id = anon_1.job_container_id"
+ "FROM data_container JOIN (job JOIN subjob ON job.id = subjob.id) "
+ "ON data_container.id = job.container_id"
)
def test_join_wpoly_innerjoin(self):