summaryrefslogtreecommitdiff
path: root/test/sql
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2021-04-12 19:32:03 +0000
committerGerrit Code Review <gerrit@ci3.zzzcomputing.com>2021-04-12 19:32:03 +0000
commit8ad68e72c6d88abbddc77546e12ff6170d3dc221 (patch)
tree77d8e07fd7023afb0474af67f77da51d05996ae3 /test/sql
parentbed6c21ac7cf264cbcca7bde99c07b973636ff12 (diff)
parentf0a334903316aa1f320053e368842458f667cbf3 (diff)
downloadsqlalchemy-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.py50
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")