From f3e0ee079abfcb4bf6b75d48982b824e759d859f Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 19 Oct 2023 11:21:26 -0400 Subject: [PATCH] dont mis-render value from previous loop iteration Fixed issue where using the same bound parameter more than once with ``literal_execute=True`` in some combinations with other literal rendering parameters would cause the wrong values to render due to an iteration issue. Fixes: #10142 Change-Id: Idde314006568e3445558f0104aed9d2f4af72b56 (cherry picked from commit 9fe7c291921540df9173820d3a06b949d7a3d949) --- doc/build/changelog/unreleased_14/10142.rst | 9 +++++++++ lib/sqlalchemy/sql/compiler.py | 14 ++++++-------- test/sql/test_compiler.py | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 doc/build/changelog/unreleased_14/10142.rst diff --git a/doc/build/changelog/unreleased_14/10142.rst b/doc/build/changelog/unreleased_14/10142.rst new file mode 100644 index 0000000000..91643c69ec --- /dev/null +++ b/doc/build/changelog/unreleased_14/10142.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, sql + :tickets: 10142 + :versions: 2.0.23 + + Fixed issue where using the same bound parameter more than once with + ``literal_execute=True`` in some combinations with other literal rendering + parameters would cause the wrong values to render due to an iteration + issue. diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index e72e2f8c04..1a71c4a4f9 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -1218,14 +1218,12 @@ class SQLCompiler(Compiled): parameter = self.binds[name] if parameter in self.literal_execute_params: if escaped_name not in replacement_expressions: - value = parameters.pop(name) - - replacement_expressions[ - escaped_name - ] = self.render_literal_bindparam( - parameter, - render_literal_value=value, - ) + replacement_expressions[ + escaped_name + ] = self.render_literal_bindparam( + parameter, + render_literal_value=parameters.pop(escaped_name), + ) continue if parameter in self.post_compile_params: diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py index 79826d2fb8..1194651375 100644 --- a/test/sql/test_compiler.py +++ b/test/sql/test_compiler.py @@ -4285,6 +4285,21 @@ class BindParameterTest(AssertsCompiledSQL, fixtures.TestBase): {"myid_1": 20, "myid_2": 18}, ) + @testing.combinations("default", "default_qmark", argnames="dialect") + def test_literal_execute_combinations(self, dialect): + """test #10142""" + + a = bindparam("a", value="abc", literal_execute=True) + b = bindparam("b", value="def", literal_execute=True) + c = bindparam("c", value="ghi", literal_execute=True) + self.assert_compile( + select(a, b, a, c), + "SELECT 'abc' AS anon_1, 'def' AS anon_2, 'abc' AS anon__1, " + "'ghi' AS anon_3", + render_postcompile=True, + dialect=dialect, + ) + def test_tuple_expanding_in_no_values(self): expr = tuple_(table1.c.myid, table1.c.name).in_( [(1, "foo"), (5, "bar")] -- 2.47.2