diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2021-04-12 19:32:03 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@ci3.zzzcomputing.com> | 2021-04-12 19:32:03 +0000 |
| commit | 8ad68e72c6d88abbddc77546e12ff6170d3dc221 (patch) | |
| tree | 77d8e07fd7023afb0474af67f77da51d05996ae3 /test/sql | |
| parent | bed6c21ac7cf264cbcca7bde99c07b973636ff12 (diff) | |
| parent | f0a334903316aa1f320053e368842458f667cbf3 (diff) | |
| download | sqlalchemy-8ad68e72c6d88abbddc77546e12ff6170d3dc221.tar.gz | |
Merge "Ensure bindparam key escaping applied in all cases"
Diffstat (limited to 'test/sql')
| -rw-r--r-- | test/sql/test_external_traversal.py | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/test/sql/test_external_traversal.py b/test/sql/test_external_traversal.py index 21b5b2d27..e7c6cccca 100644 --- a/test/sql/test_external_traversal.py +++ b/test/sql/test_external_traversal.py @@ -1,3 +1,5 @@ +import re + from sqlalchemy import and_ from sqlalchemy import bindparam from sqlalchemy import case @@ -38,11 +40,14 @@ from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ from sqlalchemy.testing import is_not +from sqlalchemy.util import pickle A = B = t1 = t2 = t3 = table1 = table2 = table3 = table4 = None -class TraversalTest(fixtures.TestBase, AssertsExecutionResults): +class TraversalTest( + fixtures.TestBase, AssertsExecutionResults, AssertsCompiledSQL +): """test ClauseVisitor's traversal, particularly its ability to copy and modify a ClauseElement in place.""" @@ -175,6 +180,49 @@ class TraversalTest(fixtures.TestBase, AssertsExecutionResults): s2 = vis.traverse(s1) eq_(list(s2.selected_columns)[0].anon_label, c1.anon_label) + @testing.combinations( + ("clone",), ("pickle",), ("conv_to_unique"), ("none"), argnames="meth" + ) + @testing.combinations( + ("name with space",), ("name with [brackets]",), argnames="name" + ) + def test_bindparam_key_proc_for_copies(self, meth, name): + r"""test :ticket:`6249`. + + The key of the bindparam needs spaces and other characters + escaped out for the POSTCOMPILE regex to work correctly. + + + Currently, the bind key reg is:: + + re.sub(r"[%\(\) \$]+", "_", body).strip("_") + + and the compiler postcompile reg is:: + + re.sub(r"\[POSTCOMPILE_(\S+)\]", process_expanding, self.string) + + Interestingly, brackets in the name seems to work out. + + """ + expr = column(name).in_([1, 2, 3]) + + if meth == "clone": + expr = visitors.cloned_traverse(expr, {}, {}) + elif meth == "pickle": + expr = pickle.loads(pickle.dumps(expr)) + elif meth == "conv_to_unique": + expr.right.unique = False + expr.right._convert_to_unique() + + token = re.sub(r"[%\(\) \$]+", "_", name).strip("_") + self.assert_compile( + expr, + '"%(name)s" IN (:%(token)s_1_1, ' + ":%(token)s_1_2, :%(token)s_1_3)" % {"name": name, "token": token}, + render_postcompile=True, + dialect="default", + ) + def test_change_in_place(self): struct = B( A("expr1"), A("expr2"), B(A("expr1b"), A("expr2b")), A("expr3") |
