]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed bug whereby the source clause
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 20 Jul 2011 22:03:35 +0000 (18:03 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 20 Jul 2011 22:03:35 +0000 (18:03 -0400)
used by query.join() would be inconsistent
if against a column expression that combined
multiple entities together.  [ticket:2197]

CHANGES
lib/sqlalchemy/orm/query.py
test/orm/test_froms.py

diff --git a/CHANGES b/CHANGES
index d4804c1c18e6eddf78d50e26e33f079262045f15..679f2c2594a0bf31b1ca9fab66baa92e55d78ce5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -32,6 +32,12 @@ CHANGES
     _with_invoke_all_eagers()
     which selects old/new behavior [ticket:2213]
 
+  - Fixed bug whereby the source clause
+    used by query.join() would be inconsistent
+    if against a column expression that combined
+    multiple entities together.  [ticket:2197]
+    Also in 0.6.9
+
   - Fixed bug whereby if a mapped class
     redefined __hash__() or __eq__() to something
     non-standard, which is a supported use case
index a3901868a83841f1da44741c7a1971844fdd6e8e..1b6b8986cc26fc6977e1e12002325a8f44ad5798 100644 (file)
@@ -2861,7 +2861,8 @@ class _ColumnEntity(_QueryEntity):
 
     def setup_entity(self, entity, mapper, adapter, from_obj,
                                 is_aliased_class, with_polymorphic):
-        self.selectable = from_obj
+        if 'selectable' not in self.__dict__: 
+            self.selectable = from_obj
         self.froms.add(from_obj)
 
     def corresponds_to(self, entity):
index 0a2617a6b5daa58e755abd83dd6a08e7a2251253..b762721aff9e8323ac30dd6126cc11e1e1d40f43 100644 (file)
@@ -941,6 +941,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
 
 
 class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
+    __dialect__ = 'default'
 
     def test_values(self):
         Address, users, User = (self.classes.Address,
@@ -1014,8 +1015,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
         self.assert_compile(
             q,
             "SELECT foobar.id AS foobar_id, "
-            "foobar.name AS foobar_name FROM users AS foobar",
-            use_default_dialect=True
+            "foobar.name AS foobar_name FROM users AS foobar"
         )
 
     @testing.fails_on('mssql', 'FIXME: unknown')
@@ -1297,7 +1297,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
                             "orders.description AS orders_description, "
                             "'q' AS foo FROM orders WHERE "
                             "orders.description = :description_1) AS "
-                            "anon_1", use_default_dialect=True)
+                            "anon_1")
         eq_(
             q.all(),
             [(3, u'order 3', 'q')]
@@ -1400,8 +1400,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
                     ' AS addresses_email_address FROM users, '
                     'addresses WHERE users.id = :id_1 AND '
                     'addresses.user_id = users.id ORDER BY '
-                    'users.name', 
-                use_default_dialect=True)
+                    'users.name')
 
 
     def test_multi_columns(self):
@@ -1522,6 +1521,62 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
         assert q.all() == expected
         sess.expunge_all()
 
+    def test_expression_selectable_matches_mzero(self):
+        User, Address = self.classes.User, self.classes.Address
+
+        ua = aliased(User)
+        aa = aliased(Address)
+        s = create_session()
+        for crit, j, exp in [
+            (User.id + Address.id, User.addresses,
+                            "SELECT users.id + addresses.id AS anon_1 "
+                            "FROM users JOIN addresses ON users.id = "
+                            "addresses.user_id"
+            ),
+            (User.id + Address.id, Address.user,
+                            "SELECT users.id + addresses.id AS anon_1 "
+                            "FROM addresses JOIN users ON users.id = "
+                            "addresses.user_id"
+            ),
+            (Address.id + User.id, User.addresses,
+                            "SELECT addresses.id + users.id AS anon_1 "
+                            "FROM users JOIN addresses ON users.id = "
+                            "addresses.user_id"
+            ),
+            (User.id + aa.id, (aa, User.addresses),
+                            "SELECT users.id + addresses_1.id AS anon_1 "
+                            "FROM users JOIN addresses AS addresses_1 "
+                            "ON users.id = addresses_1.user_id"
+            ),
+        ]:
+            q = s.query(crit)
+            mzero = q._mapper_zero()
+            assert mzero.mapped_table is q._entity_zero().selectable
+            q = q.join(j)
+            self.assert_compile(q, exp)
+
+        for crit, j, exp in [
+            (ua.id + Address.id, ua.addresses, 
+                            "SELECT users_1.id + addresses.id AS anon_1 "
+                            "FROM users AS users_1 JOIN addresses "
+                            "ON users_1.id = addresses.user_id"),
+            (ua.id + aa.id, (aa, ua.addresses), 
+                            "SELECT users_1.id + addresses_1.id AS anon_1 "
+                            "FROM users AS users_1 JOIN addresses AS "
+                            "addresses_1 ON users_1.id = addresses_1.user_id"),
+            (ua.id + aa.id, (ua, aa.user), 
+                            "SELECT users_1.id + addresses_1.id AS anon_1 "
+                            "FROM addresses AS addresses_1 JOIN "
+                            "users AS users_1 "
+                            "ON users_1.id = addresses_1.user_id")
+        ]:
+            q = s.query(crit)
+            mzero = q._mapper_zero()
+            assert mzero._AliasedClass__alias is q._entity_zero().selectable
+            q = q.join(j)
+            self.assert_compile(q, exp)
+
+
 class SelectFromTest(QueryTest, AssertsCompiledSQL):
     run_setup_mappers = None