summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/unreleased_14/8162.rst9
-rw-r--r--lib/sqlalchemy/orm/util.py3
-rw-r--r--test/orm/inheritance/_poly_fixtures.py3
-rw-r--r--test/orm/test_deprecations.py33
4 files changed, 46 insertions, 2 deletions
diff --git a/doc/build/changelog/unreleased_14/8162.rst b/doc/build/changelog/unreleased_14/8162.rst
new file mode 100644
index 000000000..4b59155e2
--- /dev/null
+++ b/doc/build/changelog/unreleased_14/8162.rst
@@ -0,0 +1,9 @@
+.. change::
+ :tags: bug, orm, regression
+ :tickets: 8162
+
+ Fixed regression caused by :ticket:`8064` where a particular check for
+ column correspondence was made too liberal, resulting in incorrect
+ rendering for some ORM subqueries such as those using
+ :meth:`.PropComparator.has` or :meth:`.PropComparator.any` in conjunction
+ with joined-inheritance queries that also use legacy aliasing features.
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py
index 0d4d4a837..317abe2b4 100644
--- a/lib/sqlalchemy/orm/util.py
+++ b/lib/sqlalchemy/orm/util.py
@@ -475,7 +475,8 @@ class ORMAdapter(sql_util.ColumnAdapter):
def _include_fn(self, elem):
entity = elem._annotations.get("parentmapper", None)
- return not entity or entity.common_parent(self.mapper)
+
+ return not entity or entity.isa(self.mapper) or self.mapper.isa(entity)
class AliasedClass(
diff --git a/test/orm/inheritance/_poly_fixtures.py b/test/orm/inheritance/_poly_fixtures.py
index 7efc99913..7ba611f95 100644
--- a/test/orm/inheritance/_poly_fixtures.py
+++ b/test/orm/inheritance/_poly_fixtures.py
@@ -350,9 +350,10 @@ class _PolymorphicFixtureBase(fixtures.MappedTest, AssertsCompiledSQL):
inherits=Person,
polymorphic_identity="engineer",
properties={
+ "company": relationship(Company, viewonly=True),
"machines": relationship(
Machine, order_by=machines.c.machine_id
- )
+ ),
},
)
diff --git a/test/orm/test_deprecations.py b/test/orm/test_deprecations.py
index a5bbe2e05..e419236f6 100644
--- a/test/orm/test_deprecations.py
+++ b/test/orm/test_deprecations.py
@@ -1908,6 +1908,39 @@ class InheritedJoinTest(
run_setup_mappers = "once"
__dialect__ = "default"
+ def test_join_w_subq_adapt(self):
+ """test #8162"""
+
+ Company, Manager, Engineer = self.classes(
+ "Company", "Manager", "Engineer"
+ )
+
+ sess = fixture_session()
+
+ with _aliased_join_warning():
+ self.assert_compile(
+ sess.query(Engineer)
+ .join(Company, Company.company_id == Engineer.company_id)
+ .outerjoin(Manager, Company.company_id == Manager.company_id)
+ .filter(~Engineer.company.has()),
+ "SELECT engineers.person_id AS engineers_person_id, "
+ "people.person_id AS people_person_id, "
+ "people.company_id AS people_company_id, "
+ "people.name AS people_name, people.type AS people_type, "
+ "engineers.status AS engineers_status, "
+ "engineers.engineer_name AS engineers_engineer_name, "
+ "engineers.primary_language AS engineers_primary_language "
+ "FROM people JOIN engineers "
+ "ON people.person_id = engineers.person_id "
+ "JOIN companies ON companies.company_id = people.company_id "
+ "LEFT OUTER JOIN (people AS people_1 JOIN managers AS "
+ "managers_1 ON people_1.person_id = managers_1.person_id) "
+ "ON companies.company_id = people_1.company_id "
+ "WHERE NOT (EXISTS (SELECT 1 FROM companies "
+ "WHERE companies.company_id = people.company_id))",
+ use_default_dialect=True,
+ )
+
def test_join_to_selectable(self):
people, Company, engineers, Engineer = (
self.tables.people,