diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-08-08 13:03:17 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-08-08 13:34:27 -0400 |
commit | c0685e5f419e203acd5e46f25c90e851e30e6f03 (patch) | |
tree | 42b73a6205a8b03e2ba232c21e43d5affb8657d2 /lib/sqlalchemy/sql/compiler.py | |
parent | 302e8dee82718df6c3a46de4c5283bdae51a650a (diff) | |
download | sqlalchemy-c0685e5f419e203acd5e46f25c90e851e30e6f03.tar.gz |
render INSERT/UPDATE column expressions up front; pass state
Fixes related to rendering of complex UPDATE DML
which was not correctly preserving positional parameter
order in conjunction with DML features that are only known
to work on the PostgreSQL database. Both pg8000
and asyncpg use positional parameters which is why these
issues are suddenly apparent.
crud.py now takes on the task of rendering the column
expressions for SET or VALUES so that for the very unusual
case that the column expression is a compound expression
that includes a bound parameter (namely an array index),
the bound parameter order is preserved.
Additionally, crud.py passes through the positional_names
keyword argument into bindparam_string() which is necessary
when CTEs are being rendered, as PG supports complex
CTE / INSERT / UPDATE scenarios.
Change-Id: I7f03920500e19b721636b84594de78a5bfdcbc82
Diffstat (limited to 'lib/sqlalchemy/sql/compiler.py')
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 8e273f67c..542bf58ac 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -3286,7 +3286,7 @@ class SQLCompiler(Compiled): if crud_params_single or not supports_default_values: text += " (%s)" % ", ".join( - [preparer.format_column(c[0]) for c in crud_params_single] + [expr for c, expr, value in crud_params_single] ) if self.returning or insert_stmt._returning: @@ -3311,12 +3311,15 @@ class SQLCompiler(Compiled): elif compile_state._has_multi_parameters: text += " VALUES %s" % ( ", ".join( - "(%s)" % (", ".join(c[1] for c in crud_param_set)) + "(%s)" + % (", ".join(value for c, expr, value in crud_param_set)) for crud_param_set in crud_params ) ) else: - insert_single_values_expr = ", ".join([c[1] for c in crud_params]) + insert_single_values_expr = ", ".join( + [value for c, expr, value in crud_params] + ) text += " VALUES (%s)" % insert_single_values_expr if toplevel: self.insert_single_values_expr = insert_single_values_expr @@ -3424,15 +3427,7 @@ class SQLCompiler(Compiled): text += table_text text += " SET " - include_table = ( - is_multitable and self.render_table_with_column_in_update_from - ) - text += ", ".join( - c[0]._compiler_dispatch(self, include_table=include_table) - + "=" - + c[1] - for c in crud_params - ) + text += ", ".join(expr + "=" + value for c, expr, value in crud_params) if self.returning or update_stmt._returning: if self.returning_precedes_values: |