diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2021-05-28 16:38:50 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@ci3.zzzcomputing.com> | 2021-05-28 16:38:50 +0000 |
| commit | 0bf2124e579c41c04ac5faedaa2be632e58eefe7 (patch) | |
| tree | 7114e916168850a24724e7aa5fc87cae6a4fa35c /lib/sqlalchemy/sql | |
| parent | 5ea4111c765b022a0345f021aa1e3b3575f899cb (diff) | |
| parent | 460bed7cfd8a6dd035caff5f5b1b33edf96fa3bb (diff) | |
| download | sqlalchemy-0bf2124e579c41c04ac5faedaa2be632e58eefe7.tar.gz | |
Merge "Fix adaption in AnnotatedLabel; repair needless expense in coercion"
Diffstat (limited to 'lib/sqlalchemy/sql')
| -rw-r--r-- | lib/sqlalchemy/sql/coercions.py | 26 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/elements.py | 1 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/traversals.py | 1 |
3 files changed, 22 insertions, 6 deletions
diff --git a/lib/sqlalchemy/sql/coercions.py b/lib/sqlalchemy/sql/coercions.py index 36ac507ad..82068d768 100644 --- a/lib/sqlalchemy/sql/coercions.py +++ b/lib/sqlalchemy/sql/coercions.py @@ -151,12 +151,25 @@ def expect( is_clause_element = False - while hasattr(element, "__clause_element__"): + # this is a special performance optimization for ORM + # joins used by JoinTargetImpl that we don't go through the + # work of creating __clause_element__() when we only need the + # original QueryableAttribute, as the former will do clause + # adaption and all that which is just thrown away here. + if ( + impl._skip_clauseelement_for_target_match + and isinstance(element, role) + and hasattr(element, "__clause_element__") + ): is_clause_element = True - if not getattr(element, "is_clause_element", False): - element = element.__clause_element__() - else: - break + else: + while hasattr(element, "__clause_element__"): + is_clause_element = True + + if not getattr(element, "is_clause_element", False): + element = element.__clause_element__() + else: + break if not is_clause_element: if impl._use_inspection: @@ -230,6 +243,7 @@ class RoleImpl(object): _post_coercion = None _resolve_literal_only = False + _skip_clauseelement_for_target_match = False def __init__(self, role_class): self._role_class = role_class @@ -860,6 +874,8 @@ class HasCTEImpl(ReturnsRowsImpl): class JoinTargetImpl(RoleImpl): __slots__ = () + _skip_clauseelement_for_target_match = True + def _literal_coercion(self, element, legacy=False, **kw): if isinstance(element, str): return element diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index f212cb079..213f47c40 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -4395,6 +4395,7 @@ class Label(roles.LabeledColumnExprRole, ColumnElement): return self.element.foreign_keys def _copy_internals(self, clone=_clone, anonymize_labels=False, **kw): + self._reset_memoizations() self._element = clone(self._element, **kw) if anonymize_labels: self.name = self._resolve_label = _anonymous_label.safe_construct( diff --git a/lib/sqlalchemy/sql/traversals.py b/lib/sqlalchemy/sql/traversals.py index e64eff6a4..35f2bd62f 100644 --- a/lib/sqlalchemy/sql/traversals.py +++ b/lib/sqlalchemy/sql/traversals.py @@ -737,7 +737,6 @@ class HasCopyInternals(object): continue if obj is not None: - result = meth(attrname, self, obj, **kw) if result is not None: setattr(self, attrname, result) |
