summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-05-02 11:33:54 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2015-05-02 11:33:54 -0400
commit8ac2bec0292daaefdfd4062a209ae4c44ba6d690 (patch)
treec10d7051b47464f0ba97d78d7e5ec6b0e5465fa9 /test
parent77db0ef6ac03d0f6f5622be373f7f85536924d3e (diff)
downloadsqlalchemy-8ac2bec0292daaefdfd4062a209ae4c44ba6d690.tar.gz
- Liberalized an assertion that was added as part of :ticket:`3347`
to protect against unknown conditions when splicing inner joins together within joined eager loads with ``innerjoin=True``; if some of the joins use a "secondary" table, the assertion needs to unwrap further joins in order to pass. fixes #3412
Diffstat (limited to 'test')
-rw-r--r--test/orm/test_eager_relations.py134
1 files changed, 134 insertions, 0 deletions
diff --git a/test/orm/test_eager_relations.py b/test/orm/test_eager_relations.py
index f532901f2..1156fc1bf 100644
--- a/test/orm/test_eager_relations.py
+++ b/test/orm/test_eager_relations.py
@@ -2301,6 +2301,140 @@ class InnerJoinSplicingTest(fixtures.MappedTest, testing.AssertsCompiledSQL):
)
+class InnerJoinSplicingWSecondaryTest(
+ fixtures.MappedTest, testing.AssertsCompiledSQL):
+ __dialect__ = 'default'
+ __backend__ = True # exercise hardcore join nesting on backends
+
+ @classmethod
+ def define_tables(cls, metadata):
+ Table(
+ 'a', metadata,
+ Column('id', Integer, primary_key=True),
+ Column('bid', ForeignKey('b.id'))
+ )
+
+ Table(
+ 'b', metadata,
+ Column('id', Integer, primary_key=True),
+ Column('cid', ForeignKey('c.id'))
+ )
+
+ Table(
+ 'c', metadata,
+ Column('id', Integer, primary_key=True),
+ )
+
+ Table('ctod', metadata,
+ Column('cid', ForeignKey('c.id'), primary_key=True),
+ Column('did', ForeignKey('d.id'), primary_key=True),
+ )
+ Table('d', metadata,
+ Column('id', Integer, primary_key=True),
+ )
+
+ @classmethod
+ def setup_classes(cls):
+
+ class A(cls.Comparable):
+ pass
+
+ class B(cls.Comparable):
+ pass
+
+ class C(cls.Comparable):
+ pass
+
+ class D(cls.Comparable):
+ pass
+
+ @classmethod
+ def setup_mappers(cls):
+ A, B, C, D = (
+ cls.classes.A, cls.classes.B, cls.classes.C,
+ cls.classes.D)
+ mapper(A, cls.tables.a, properties={
+ 'b': relationship(B)
+ })
+ mapper(B, cls.tables.b, properties=odict([
+ ('c', relationship(C)),
+ ]))
+ mapper(C, cls.tables.c, properties=odict([
+ ('ds', relationship(D, secondary=cls.tables.ctod,
+ order_by=cls.tables.d.c.id)),
+ ]))
+ mapper(D, cls.tables.d)
+
+ @classmethod
+ def _fixture_data(cls):
+ A, B, C, D = (
+ cls.classes.A, cls.classes.B, cls.classes.C,
+ cls.classes.D)
+
+ d1, d2, d3 = D(id=1), D(id=2), D(id=3)
+ return [
+ A(
+ id=1,
+ b=B(
+ c=C(
+ id=1,
+ ds=[d1, d2]
+ )
+ )
+ ),
+ A(
+ id=2,
+ b=B(
+ c=C(
+ id=2,
+ ds=[d2, d3]
+ )
+ )
+ )
+ ]
+
+ @classmethod
+ def insert_data(cls):
+ s = Session(testing.db)
+ s.add_all(cls._fixture_data())
+ s.commit()
+
+ def _assert_result(self, query):
+ def go():
+ eq_(
+ query.all(),
+ self._fixture_data()
+ )
+
+ self.assert_sql_count(
+ testing.db,
+ go,
+ 1
+ )
+
+ def test_joined_across(self):
+ A = self.classes.A
+
+ s = Session()
+ q = s.query(A) \
+ .options(
+ joinedload('b').
+ joinedload('c', innerjoin=True).
+ joinedload('ds', innerjoin=True))
+ self.assert_compile(
+ q,
+ "SELECT a.id AS a_id, a.bid AS a_bid, d_1.id AS d_1_id, "
+ "c_1.id AS c_1_id, b_1.id AS b_1_id, b_1.cid AS b_1_cid "
+ "FROM a LEFT OUTER JOIN "
+ "(b AS b_1 JOIN "
+ "(c AS c_1 JOIN ctod AS ctod_1 ON c_1.id = ctod_1.cid) "
+ "ON c_1.id = b_1.cid "
+ "JOIN d AS d_1 ON d_1.id = ctod_1.did) ON b_1.id = a.bid "
+ "ORDER BY d_1.id"
+ )
+ self._assert_result(q)
+
+
class SubqueryAliasingTest(fixtures.MappedTest, testing.AssertsCompiledSQL):
"""test #2188"""