summaryrefslogtreecommitdiff
path: root/test/sql/test_operators.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-07-17 11:32:27 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-07-17 11:32:27 -0400
commit85a88df13ab8d217331cf98392544a888b4d7df3 (patch)
tree7dbe7bd9c6b2595a6067fb4ea6b00ae7fa933362 /test/sql/test_operators.py
parentf1dff43a825fe779d52e12d9a823ede0edef9bb0 (diff)
downloadsqlalchemy-85a88df13ab8d217331cf98392544a888b4d7df3.tar.gz
use concat() directly for contains, startswith, endswith
Adjusted the SQL compilation for string containment functions ``.contains()``, ``.startswith()``, ``.endswith()`` to force the use of the string concatenation operator, rather than relying upon the overload of the addition operator, so that non-standard use of these operators with for example bytestrings still produces string concatenation operators. To accommodate this, needed to add a new _rconcat operator function, which is private, as well as a fallback in concat_op() that works similarly to Python builtin ops. Fixes: #8253 Change-Id: I2b7f56492f765742d88cb2a7834ded6a2892bd7e
Diffstat (limited to 'test/sql/test_operators.py')
-rw-r--r--test/sql/test_operators.py82
1 files changed, 82 insertions, 0 deletions
diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py
index 2411fb0a3..830a5eb0f 100644
--- a/test/sql/test_operators.py
+++ b/test/sql/test_operators.py
@@ -3087,6 +3087,36 @@ class ComposedLikeOperatorsTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"x_1": "y"},
)
+ def test_contains_encoded(self):
+ self.assert_compile(
+ column("x").contains(b"y"),
+ "x LIKE '%' || :x_1 || '%'",
+ checkparams={"x_1": b"y"},
+ )
+
+ def test_not_contains_encoded(self):
+ self.assert_compile(
+ ~column("x").contains(b"y"),
+ "x NOT LIKE '%' || :x_1 || '%'",
+ checkparams={"x_1": b"y"},
+ )
+
+ def test_contains_encoded_mysql(self):
+ self.assert_compile(
+ column("x").contains(b"y"),
+ "x LIKE concat('%%', %s, '%%')",
+ checkparams={"x_1": b"y"},
+ dialect="mysql",
+ )
+
+ def test_not_contains_encoded_mysql(self):
+ self.assert_compile(
+ ~column("x").contains(b"y"),
+ "x NOT LIKE concat('%%', %s, '%%')",
+ checkparams={"x_1": b"y"},
+ dialect="mysql",
+ )
+
def test_contains_escape(self):
self.assert_compile(
column("x").contains("a%b_c", escape="\\"),
@@ -3250,6 +3280,36 @@ class ComposedLikeOperatorsTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"x_1": "a^%b^_c/d^^e"},
)
+ def test_startswith_encoded(self):
+ self.assert_compile(
+ column("x").startswith(b"y"),
+ "x LIKE :x_1 || '%'",
+ checkparams={"x_1": b"y"},
+ )
+
+ def test_startswith_encoded_mysql(self):
+ self.assert_compile(
+ column("x").startswith(b"y"),
+ "x LIKE concat(%s, '%%')",
+ checkparams={"x_1": b"y"},
+ dialect="mysql",
+ )
+
+ def test_not_startswith_encoded(self):
+ self.assert_compile(
+ ~column("x").startswith(b"y"),
+ "x NOT LIKE :x_1 || '%'",
+ checkparams={"x_1": b"y"},
+ )
+
+ def test_not_startswith_encoded_mysql(self):
+ self.assert_compile(
+ ~column("x").startswith(b"y"),
+ "x NOT LIKE concat(%s, '%%')",
+ checkparams={"x_1": b"y"},
+ dialect="mysql",
+ )
+
def test_not_startswith(self):
self.assert_compile(
~column("x").startswith("y"),
@@ -3324,6 +3384,28 @@ class ComposedLikeOperatorsTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"x_1": "y"},
)
+ def test_endswith_encoded(self):
+ self.assert_compile(
+ column("x").endswith(b"y"),
+ "x LIKE '%' || :x_1",
+ checkparams={"x_1": b"y"},
+ )
+
+ def test_endswith_encoded_mysql(self):
+ self.assert_compile(
+ column("x").endswith(b"y"),
+ "x LIKE concat('%%', %s)",
+ checkparams={"x_1": b"y"},
+ dialect="mysql",
+ )
+
+ def test_not_endswith_encoded(self):
+ self.assert_compile(
+ ~column("x").endswith(b"y"),
+ "x NOT LIKE '%' || :x_1",
+ checkparams={"x_1": b"y"},
+ )
+
def test_endswith_escape(self):
self.assert_compile(
column("x").endswith("a%b_c", escape="\\"),