Fix joinedload + of_type() + and_() invalid SQL for subclass columns#13206
Fix joinedload + of_type() + and_() invalid SQL for subclass columns#13206joaquinhuigomez wants to merge 3 commits intosqlalchemy:mainfrom
Conversation
…ss columns When joinedload uses of_type() targeting a joined-table subclass combined with and_() referencing a column on that subclass, the column was not adapted to the subquery alias. This happened because mark_exclude_cols in _JoinCondition.join_targets used identity checks against prop.mapper, which is the base class mapper. Subclass mappers failed this check and got annotated with should_not_adapt, preventing the ClauseAdapter from rewriting the column reference. Fixed by adding a mapper.isa() check so that subclass mapper columns are recognized as belonging to the relationship target and are properly adapted. Fixes: sqlalchemy#13203 Change-Id: I13203a
|
wow, the robots are truly taking over :) well, looks mostly good, will haev to see if that test suite goes through in python 3.7/3.8 for 2.0.x but thanks |
sqla-tester
left a comment
There was a problem hiding this comment.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision 3026c21 of this pull request into gerrit so we can run tests and reviews and stuff
|
New Gerrit review created for change 3026c21: https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/6638 |
| s.add(Animal(id=2, name="Generic", type="animal", owner=o)) | ||
| s.commit() | ||
|
|
||
| def test_joinedload_of_type_and_subclass_col(self): |
There was a problem hiding this comment.
these are good tests but it would be even better if they were done in this style:
sqlalchemy/test/orm/test_of_type.py
Lines 1299 to 1373 in d3a8d49
that is, using self.sql_execution_asserter to actually assert all the SQL emitted for the entire operation
|
Thanks for running it through Gerrit — happy to address anything that comes up in the test run. |
I've requested changes in the review are you able to make these? |
|
Moved the changelog to unreleased_20 and reworked the tests to use sql_execution_asserter with result checks. Let me know if the SQL assertions need adjusting. |
sqla-tester
left a comment
There was a problem hiding this comment.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision 76d61d0 of this pull request into gerrit so we can run tests and reviews and stuff
|
Patchset 76d61d0 added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/6638 |
|
looks like the test is actually failing. need that to be passing to move forward |
|
Fixed the SQL assertions — was using the wrong alias pattern. Should pass now. |
sqla-tester
left a comment
There was a problem hiding this comment.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision ba55b0c of this pull request into gerrit so we can run tests and reviews and stuff
|
Patchset ba55b0c added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/6638 |
When using
joinedload(Parent.children.of_type(SubClass).and_(SubClass.attr == value)), theSubClass.attrcolumn reference in theand_()clause was not adapted to the subquery alias. The generated SQL referencedsubclass_table.colinstead ofanon_1.subclass_col, causingOperationalError: no such column.The issue is in
mark_exclude_colsin_JoinCondition.join_targets— it used identity checks (is not self.prop.mapper) to decide whether a column belongs to the relationship target. Sinceself.prop.mapperis the base class mapper (e.g.Animal), columns from subclass mappers (e.g.Dog) failed this check and were annotated withshould_not_adapt, preventing theClauseAdapterfrom rewriting them.Added a
mapper.isa()check so subclass mapper columns are recognized as belonging to the relationship target.selectinloadandsubqueryloadwere not affected because they emit separate queries where the column is directly available.Fixes #13203