Index: lib/sqlalchemy/sql_util.py
===================================================================
--- lib/sqlalchemy/sql_util.py	(revision 2369)
+++ lib/sqlalchemy/sql_util.py	(working copy)
@@ -178,7 +178,7 @@
 
 class ClauseAdapter(AbstractClauseProcessor):
     """Given a clause (like as in a WHERE criterion), locate columns
-    which *correspond* to a given selectable, and changes those
+    which are embedded within a given selectable, and changes those
     columns to be that of the selectable.
 
     E.g.::
@@ -219,10 +219,10 @@
         if self.exclude is not None:
             if col in self.exclude:
                 return None
-        newcol = self.selectable.corresponding_column(col, raiseerr=False, keys_ok=False)
+        newcol = self.selectable.corresponding_column(col, raiseerr=False, require_embedded=True, keys_ok=False)
         if newcol is None and self.equivalents is not None and col in self.equivalents:
             for equiv in self.equivalents[col]:
-                newcol = self.selectable.corresponding_column(equiv, raiseerr=False, keys_ok=False)
+                newcol = self.selectable.corresponding_column(equiv, raiseerr=False, require_embedded=True, keys_ok=False)
                 if newcol:
                     return newcol
         return newcol
Index: lib/sqlalchemy/sql.py
===================================================================
--- lib/sqlalchemy/sql.py	(revision 2373)
+++ lib/sqlalchemy/sql.py	(working copy)
@@ -506,6 +506,21 @@
     def visit_label(self, label):pass
     def visit_typeclause(self, typeclause):pass
 
+class VisitColumnMixin(object):
+    """a mixin that adds Column traversal to a ClauseVisitor"""
+    def visit_table(self, table):
+        for c in table.c:
+            c.accept_visitor(self)
+    def visit_select(self, select):
+        for c in select.c:
+            c.accept_visitor(self)
+    def visit_compound_select(self, select):
+        for c in select.c:
+            c.accept_visitor(self)
+    def visit_alias(self, alias):
+        for c in alias.c:
+            c.accept_visitor(self)
+        
 class Executor(object):
     """Represent a *thing that can produce Compiled objects and execute them*."""
 
@@ -1041,20 +1056,25 @@
             self._oid_column = self._locate_oid_column()
         return self._oid_column
 
-    def corresponding_column(self, column, raiseerr=True, keys_ok=False, require_exact=False):
+    def _get_all_embedded_columns(self):
+        ret = []
+        class FindCols(VisitColumnMixin, ClauseVisitor):
+            def visit_column(self, col):
+                ret.append(col)
+        self.accept_visitor(FindCols())
+        return ret
+
+    def corresponding_column(self, column, raiseerr=True, keys_ok=False, require_embedded=False):
         """Given a ``ColumnElement``, return the ``ColumnElement``
         object from this ``Selectable`` which corresponds to that
         original ``Column`` via a proxy relationship.
         """
 
-        if require_exact:
-            if self.columns.get(column.name) is column:
-                return column
+        if require_embedded and column not in util.Set(self._get_all_embedded_columns()):
+            if not raiseerr:
+                return None
             else:
-                if not raiseerr:
-                    return None
-                else:
-                    raise exceptions.InvalidRequestError("Column instance '%s' is not directly present in table '%s'" % (str(column), str(column.table)))
+                raise exceptions.InvalidRequestError("Column instance '%s' is not directly present within selectable '%s'" % (str(column), column.table))
         for c in column.orig_set:
             try:
                 return self.original_columns[c]
Index: lib/sqlalchemy/ansisql.py
===================================================================
--- lib/sqlalchemy/ansisql.py	(revision 2373)
+++ lib/sqlalchemy/ansisql.py	(working copy)
@@ -391,9 +391,9 @@
                 c.accept_visitor(self)
                 inner_columns[self.get_str(c)] = c
                 continue
-            try:
+            if hasattr(c, '_selectable'):
                 s = c._selectable()
-            except AttributeError:
+            else:
                 c.accept_visitor(self)
                 inner_columns[self.get_str(c)] = c
                 continue
Index: CHANGES
===================================================================
--- CHANGES	(revision 2382)
+++ CHANGES	(working copy)
@@ -39,6 +39,7 @@
       (since its not polymorphic) which breaks in bi-directional relationships
       (i.e. C has its A, but A's backref will lazyload it as a different 
       instance of type "B") [ticket:500]
+
 0.3.5
 - sql:
     - the value of "case_sensitive" defaults to True now, regardless of the
