summaryrefslogtreecommitdiff
path: root/test/sql/test_compiler.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2021-04-05 16:32:14 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2021-04-05 19:30:19 -0400
commit279d185058ecf322b0c7a1fc8263dbf4da56e9b7 (patch)
tree3f2aea8c95ac3f8a825f974a9228a983af823ba4 /test/sql/test_compiler.py
parent165c3a65dcb1ba3f42ecf2b5da7c298bdc259f9b (diff)
downloadsqlalchemy-279d185058ecf322b0c7a1fc8263dbf4da56e9b7.tar.gz
uniquify when popping literal_execute_params from param dict
Fixed further issues in the same area as that of :ticket:`6173` released in 1.4.5, where a "postcompile" parameter, again most typically those used for LIMIT/OFFSET rendering in Oracle and SQL Server, would fail to be processed correctly if the same parameter rendered in multiple places in the statement. Fixes: #6202 Change-Id: I95c355aa52a7546fe579ad67f9a8402a213cb79d
Diffstat (limited to 'test/sql/test_compiler.py')
-rw-r--r--test/sql/test_compiler.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py
index b2d443438..2115c32a7 100644
--- a/test/sql/test_compiler.py
+++ b/test/sql/test_compiler.py
@@ -3964,6 +3964,91 @@ class BindParameterTest(AssertsCompiledSQL, fixtures.TestBase):
"(:param_1_2_1, :param_1_2_2)",
)
+ def test_construct_params_repeated_postcompile_params_one(self):
+ """test for :ticket:`6202` one - name repeated in positiontup
+ (e.g. SQL Server using TOP)
+
+ """
+
+ t = table("t", column("x"))
+ stmt = (
+ select(1)
+ .where(t.c.x == bindparam(None, value="10", literal_execute=True))
+ .scalar_subquery()
+ )
+
+ u = union(select(stmt), select(stmt)).subquery().select()
+
+ compiled = u.compile(
+ dialect=default.DefaultDialect(paramstyle="format"),
+ compile_kwargs={"render_postcompile": True},
+ )
+ eq_ignore_whitespace(
+ compiled.string,
+ "SELECT anon_2.anon_1 FROM (SELECT (SELECT 1 FROM t "
+ "WHERE t.x = '10') AS anon_1 UNION SELECT "
+ "(SELECT 1 FROM t WHERE t.x = '10') AS anon_1) AS anon_2",
+ )
+ eq_(compiled.construct_params(), {"param_1": "10"})
+
+ def test_construct_params_repeated_postcompile_params_two(self):
+ """test for :ticket:`6202` two - same param name used twice
+ (e.g. Oracle LIMIT)
+
+ """
+ t = table("t", column("x"))
+
+ bp = bindparam(None, value="10")
+ stmt = (
+ select(1)
+ .where(t.c.x == bp.render_literal_execute())
+ .scalar_subquery()
+ )
+ stmt2 = (
+ select(1)
+ .where(t.c.x == bp.render_literal_execute())
+ .scalar_subquery()
+ )
+
+ u = union(select(stmt), select(stmt2)).subquery().select()
+
+ compiled = u.compile(
+ dialect=default.DefaultDialect(paramstyle="named"),
+ compile_kwargs={"render_postcompile": True},
+ )
+ eq_ignore_whitespace(
+ compiled.string,
+ "SELECT anon_2.anon_1 FROM (SELECT (SELECT 1 "
+ "FROM t WHERE t.x = '10') AS anon_1 UNION SELECT "
+ "(SELECT 1 FROM t WHERE t.x = '10') AS anon_3) AS anon_2",
+ )
+ eq_(compiled.construct_params(), {"param_1": "10"})
+
+ def test_construct_params_positional_plain_repeated(self):
+ t = table("t", column("x"))
+ stmt = (
+ select(1)
+ .where(t.c.x == bindparam(None, value="10"))
+ .where(t.c.x == bindparam(None, value="12", literal_execute=True))
+ .scalar_subquery()
+ )
+
+ u = union(select(stmt), select(stmt)).subquery().select()
+
+ compiled = u.compile(
+ dialect=default.DefaultDialect(paramstyle="format"),
+ compile_kwargs={"render_postcompile": True},
+ )
+ eq_ignore_whitespace(
+ compiled.string,
+ "SELECT anon_2.anon_1 FROM (SELECT (SELECT 1 FROM t "
+ "WHERE t.x = %s AND t.x = '12') AS anon_1 "
+ "UNION SELECT (SELECT 1 FROM t WHERE t.x = %s AND t.x = '12') "
+ "AS anon_1) AS anon_2",
+ )
+ eq_(compiled.construct_params(), {"param_1": "10", "param_2": "12"})
+ eq_(compiled.positiontup, ["param_1", "param_1"])
+
def test_tuple_clauselist_in(self):
self.assert_compile(
tuple_(table1.c.myid, table1.c.name).in_(