diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-11-14 11:31:22 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-11-14 11:35:45 -0500 |
| commit | 4ee5b2c4a9e7ad9f3df75940b9837d5c65cba6fd (patch) | |
| tree | 2d9897ef7ba5e6e69d33098f2d9dbaa0fb2fad3d /lib/sqlalchemy | |
| parent | 616b226f74e63e72a6e02f2770fac3933e3cc098 (diff) | |
| download | sqlalchemy-4ee5b2c4a9e7ad9f3df75940b9837d5c65cba6fd.tar.gz | |
Deannotate "parententity" in primaryjoin/secondaryjoin
Fixed bug where the ORM annotations could be incorrect for the
primaryjoin/secondaryjoin a relationship if one used the pattern
``ForeignKey(SomeClass.id)`` in the declarative mappings. This pattern
would leak undesired annotations into the join conditions which can break
aliasing operations done within :class:`.Query` that are not supposed to
impact elements in that join condition. These annotations are now removed
up front if present.
Also add a test suite for has/any into test_query which will
form the basis for new tests to be added in :ticket:`4366`.
Fixes: #4367
Change-Id: I929ef983981bb49bf975f346950ebb0e19c986b8
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/orm/relationships.py | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py index e92d10a5b..adcaa5927 100644 --- a/lib/sqlalchemy/orm/relationships.py +++ b/lib/sqlalchemy/orm/relationships.py @@ -2080,6 +2080,7 @@ class JoinCondition(object): self.support_sync = support_sync self.can_be_synced_fn = can_be_synced_fn self._determine_joins() + self._sanitize_joins() self._annotate_fks() self._annotate_remote() self._annotate_local() @@ -2118,6 +2119,22 @@ class JoinCondition(object): log.info('%s relationship direction %s', self.prop, self.direction) + def _sanitize_joins(self): + """remove the parententity annotation from our join conditions which + can leak in here based on some declarative patterns and maybe others. + + We'd want to remove "parentmapper" also, but apparently there's + an exotic use case in _join_fixture_inh_selfref_w_entity + that relies upon it being present, see :ticket:`3364`. + + """ + + self.primaryjoin = _deep_deannotate( + self.primaryjoin, values=("parententity",)) + if self.secondaryjoin is not None: + self.secondaryjoin = _deep_deannotate( + self.secondaryjoin, values=("parententity",)) + def _determine_joins(self): """Determine the 'primaryjoin' and 'secondaryjoin' attributes, if not passed to the constructor already. |
