summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-06-24 22:50:06 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2018-06-26 15:41:00 -0400
commitf243c00dda1484da97e706b7237670cdce6f10b9 (patch)
tree217a8209e012abd07d72dfdf3559a5832c0cd902 /lib/sqlalchemy
parent677818707471db670d5c3a83b10ebbc65f871881 (diff)
downloadsqlalchemy-f243c00dda1484da97e706b7237670cdce6f10b9.tar.gz
Ensure BakedQuery is cloned before we add options to it
Fixed bug in new polymorphic selectin loading where the BakedQuery used internally would be mutated by the given loader options, which would both inappropriately mutate the subclass query as well as carry over the effect to subsequent queries. Change-Id: Iaceecb50557f78484d09e55b3029a0483dfe873f Fixes: #4286
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/ext/baked.py7
-rw-r--r--lib/sqlalchemy/orm/loading.py6
2 files changed, 10 insertions, 3 deletions
diff --git a/lib/sqlalchemy/ext/baked.py b/lib/sqlalchemy/ext/baked.py
index 79457e86e..addec90da 100644
--- a/lib/sqlalchemy/ext/baked.py
+++ b/lib/sqlalchemy/ext/baked.py
@@ -154,6 +154,13 @@ class BakedQuery(object):
self._spoiled = True
return self
+ def _with_lazyload_options(self, options, effective_path, cache_path=None):
+ """Cloning version of _add_lazyload_options.
+ """
+ q = self._clone()
+ q._add_lazyload_options(options, effective_path, cache_path=cache_path)
+ return q
+
def _add_lazyload_options(self, options, effective_path, cache_path=None):
"""Used by per-state lazy loaders to add options to the
"lazy load" query from a parent query.
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py
index a169845d4..0a6f8023a 100644
--- a/lib/sqlalchemy/orm/loading.py
+++ b/lib/sqlalchemy/orm/loading.py
@@ -580,17 +580,17 @@ def _load_subclass_via_in(context, path, entity):
def do_load(context, path, states, load_only, effective_entity):
orig_query = context.query
- q._add_lazyload_options(
+ q2 = q._with_lazyload_options(
(enable_opt, ) + orig_query._with_options + (disable_opt, ),
path.parent, cache_path=path
)
if orig_query._populate_existing:
- q.add_criteria(
+ q2.add_criteria(
lambda q: q.populate_existing()
)
- q(context.session).params(
+ q2(context.session).params(
primary_keys=[
state.key[1][0] if zero_idx else state.key[1]
for state, load_attrs in states