summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/compiler.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-08-04 13:45:07 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2018-08-04 13:46:19 -0400
commitabeea1d82db34232bbef01e98fa4d1de0f583eb6 (patch)
treefa5fa3576e8248975bbbd47c3fc21e31822529e9 /lib/sqlalchemy/sql/compiler.py
parente9e869f4d557a2a4e9a57f74862b4db7493b657e (diff)
downloadsqlalchemy-abeea1d82db34232bbef01e98fa4d1de0f583eb6.tar.gz
Include UPDATE/DELETE extra_froms in correlation
Fixed bug where the multi-table support for UPDATE and DELETE statements did not consider the additional FROM elements as targets for correlation, when a correlated SELECT were also combined with the statement. This change now includes that a SELECT statement in the WHERE clause for such a statement will try to auto-correlate back to these additional tables in the parent UPDATE/DELETE or unconditionally correlate if :meth:`.Select.correlate` is used. Note that auto-correlation raises an error if the SELECT statement would have no FROM clauses as a result, which can now occur if the parent UPDATE/DELETE specifies the same tables in its additional set of tables ; specify :meth:`.Select.correlate` explicitly to resolve. Change-Id: Ie11eaad7e49af3f59df11691b104d6359341bdae Fixes: #4313
Diffstat (limited to 'lib/sqlalchemy/sql/compiler.py')
-rw-r--r--lib/sqlalchemy/sql/compiler.py27
1 files changed, 15 insertions, 12 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index ae1dd2c7c..529e28ba6 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -2180,11 +2180,6 @@ class SQLCompiler(Compiled):
def visit_update(self, update_stmt, asfrom=False, **kw):
toplevel = not self.stack
- self.stack.append(
- {'correlate_froms': {update_stmt.table},
- "asfrom_froms": {update_stmt.table},
- "selectable": update_stmt})
-
extra_froms = update_stmt._extra_froms
is_multitable = bool(extra_froms)
@@ -2194,8 +2189,15 @@ class SQLCompiler(Compiled):
render_extra_froms = [
f for f in extra_froms if f not in main_froms
]
+ correlate_froms = main_froms.union(extra_froms)
else:
render_extra_froms = []
+ correlate_froms = {update_stmt.table}
+
+ self.stack.append(
+ {'correlate_froms': correlate_froms,
+ "asfrom_froms": correlate_froms,
+ "selectable": update_stmt})
text = "UPDATE "
@@ -2289,14 +2291,15 @@ class SQLCompiler(Compiled):
def visit_delete(self, delete_stmt, asfrom=False, **kw):
toplevel = not self.stack
- self.stack.append({'correlate_froms': {delete_stmt.table},
- "asfrom_froms": {delete_stmt.table},
- "selectable": delete_stmt})
-
crud._setup_crud_params(self, delete_stmt, crud.ISDELETE, **kw)
extra_froms = delete_stmt._extra_froms
+ correlate_froms = {delete_stmt.table}.union(extra_froms)
+ self.stack.append({'correlate_froms': correlate_froms,
+ "asfrom_froms": correlate_froms,
+ "selectable": delete_stmt})
+
text = "DELETE "
if delete_stmt._prefixes:
@@ -2401,9 +2404,9 @@ class StrSQLCompiler(SQLCompiler):
for t in extra_froms)
def delete_extra_from_clause(self, update_stmt,
- from_table, extra_froms,
- from_hints,
- **kw):
+ from_table, extra_froms,
+ from_hints,
+ **kw):
return ', ' + ', '.join(
t._compiler_dispatch(self, asfrom=True,
fromhints=from_hints, **kw)