]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
join() will check existing objects in the FROM clause and not re-join to one which...
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 4 Jun 2007 15:20:42 +0000 (15:20 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 4 Jun 2007 15:20:42 +0000 (15:20 +0000)
lib/sqlalchemy/orm/query.py
lib/sqlalchemy/sql_util.py

index a26bf8dcb68f2d8dc9322c43917e0f98340a9805..f2e87b7deaa7ffc125f283372bcfb6d5ad8bdb60 100644 (file)
@@ -535,23 +535,28 @@ class Query(object):
         else:
             [keys,p] = self._locate_prop(prop, start=start)
         clause = self._from_obj[-1]
+
+        currenttables = sql_util.TableFinder(self._from_obj, include_aliases=True)
+            
         mapper = start
         for key in keys:
             prop = mapper.props[key]
             if prop._is_self_referential():
                 raise exceptions.InvalidRequestError("Self-referential query on '%s' property must be constructed manually using an Alias object for the related table." % str(prop))
-            if outerjoin:
-                if prop.secondary:
-                    clause = clause.outerjoin(prop.secondary, prop.get_join(mapper, primary=True, secondary=False))
-                    clause = clause.outerjoin(prop.select_table, prop.get_join(mapper, primary=False))
-                else:
-                    clause = clause.outerjoin(prop.select_table, prop.get_join(mapper))
-            else:
-                if prop.secondary:
-                    clause = clause.join(prop.secondary, prop.get_join(mapper, primary=True, secondary=False))
-                    clause = clause.join(prop.select_table, prop.get_join(mapper, primary=False))
+            # dont re-join to a table already in our from objects
+            if prop.select_table not in currenttables:
+                if outerjoin:
+                    if prop.secondary:
+                        clause = clause.outerjoin(prop.secondary, prop.get_join(mapper, primary=True, secondary=False))
+                        clause = clause.outerjoin(prop.select_table, prop.get_join(mapper, primary=False))
+                    else:
+                        clause = clause.outerjoin(prop.select_table, prop.get_join(mapper))
                 else:
-                    clause = clause.join(prop.select_table, prop.get_join(mapper))
+                    if prop.secondary:
+                        clause = clause.join(prop.secondary, prop.get_join(mapper, primary=True, secondary=False))
+                        clause = clause.join(prop.select_table, prop.get_join(mapper, primary=False))
+                    else:
+                        clause = clause.join(prop.select_table, prop.get_join(mapper))
             mapper = prop.mapper
         return (clause, mapper)
 
index 9f8bf276ecef839b13db2093d93389086af93496..7a67402318d395fef9c81eaa0ab60c134b3be891 100644 (file)
@@ -71,7 +71,7 @@ class TableFinder(TableCollection, sql.NoColumnVisitor):
         TableCollection.__init__(self)
         self.check_columns = check_columns
         self.include_aliases = include_aliases
-        if clause is not None:
+        for clause in util.to_list(clause):
             self.traverse(clause)
 
     def visit_alias(self, alias):