From f91bb39b199c17ba56a8835c1ce2f6cf3e7b67ef Mon Sep 17 00:00:00 2001 From: Br1an67 <932039080@qq.com> Date: Sun, 1 Mar 2026 14:47:22 +0800 Subject: [PATCH] test: verify LIKE filter in update queries uses parameterized values Add a regression test for issue #1225. The LIKE pattern from contains() filter is passed as a parameterized query value (not rendered inline), so the % wildcards never conflict with MySQL driver's %s parameter substitution. Fixes #1225 --- tests/test_sql.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/test_sql.py b/tests/test_sql.py index d0a17a1c3..590646bb3 100644 --- a/tests/test_sql.py +++ b/tests/test_sql.py @@ -2,7 +2,7 @@ import pytest -from tests.testmodels import CharPkModel, Drink, Event, IntFields +from tests.testmodels import CharPkModel, Drink, Event, IntFields, Tournament from tortoise import connections from tortoise.backends.psycopg.client import PsycopgClient from tortoise.expressions import F @@ -287,3 +287,32 @@ def test_m2m_filter_two_relations_same_target_produces_aliased_joins(sql_context assert '"drink_topping"' in sql assert '"drink__flavors"' in sql assert '"drink__toppings"' in sql + + +def test_update_with_like_filter(sql_context): + """LIKE wildcards (%) in update queries must not conflict with %s parameter placeholders. + + The LIKE pattern is passed as a parameterized value, so it never appears + inline in the SQL template and cannot conflict with driver-level %s + substitution (see https://github.com/tortoise/tortoise-orm/issues/1225). + """ + db, dialect, is_psycopg = sql_context + sql = Tournament.filter(name__contains="test").update(desc="updated").sql() + if dialect == "mysql": + expected = "UPDATE `tournament` SET `desc`=%s WHERE CAST(`name` AS CHAR) LIKE %s" + elif dialect == "postgres": + if is_psycopg: + expected = ( + 'UPDATE "tournament" SET "desc"=%s' + " WHERE CAST(\"name\" AS VARCHAR) LIKE %s ESCAPE '\\'" + ) + else: + expected = ( + 'UPDATE "tournament" SET "desc"=$1' + " WHERE CAST(\"name\" AS VARCHAR) LIKE $2 ESCAPE '\\'" + ) + else: + expected = ( + 'UPDATE "tournament" SET "desc"=? WHERE CAST("name" AS VARCHAR) LIKE ? ESCAPE \'\\\'' + ) + assert sql == expected