diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-07-17 11:32:27 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-07-17 11:32:27 -0400 |
commit | 85a88df13ab8d217331cf98392544a888b4d7df3 (patch) | |
tree | 7dbe7bd9c6b2595a6067fb4ea6b00ae7fa933362 /test/sql/test_operators.py | |
parent | f1dff43a825fe779d52e12d9a823ede0edef9bb0 (diff) | |
download | sqlalchemy-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.py | 82 |
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="\\"), |