diff options
-rw-r--r-- | django/db/backends/mysql/schema.py | 2 | ||||
-rw-r--r-- | django/db/backends/oracle/schema.py | 2 | ||||
-rw-r--r-- | django/db/backends/postgresql/schema.py | 2 | ||||
-rw-r--r-- | tests/migrations/test_operations.py | 8 |
4 files changed, 8 insertions, 6 deletions
diff --git a/django/db/backends/mysql/schema.py b/django/db/backends/mysql/schema.py index 2ac287328b..31829506c1 100644 --- a/django/db/backends/mysql/schema.py +++ b/django/db/backends/mysql/schema.py @@ -56,8 +56,6 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): def quote_value(self, value): self.connection.ensure_connection() - if isinstance(value, str): - value = value.replace("%", "%%") # MySQLdb escapes to string, PyMySQL to bytes. quoted = self.connection.connection.escape( value, self.connection.connection.encoders diff --git a/django/db/backends/oracle/schema.py b/django/db/backends/oracle/schema.py index aca6d83962..0d70522a2a 100644 --- a/django/db/backends/oracle/schema.py +++ b/django/db/backends/oracle/schema.py @@ -32,7 +32,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): elif isinstance(value, datetime.timedelta): return "'%s'" % duration_iso_string(value) elif isinstance(value, str): - return "'%s'" % value.replace("'", "''").replace("%", "%%") + return "'%s'" % value.replace("'", "''") elif isinstance(value, (bytes, bytearray, memoryview)): return "'%s'" % value.hex() elif isinstance(value, bool): diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py index 18899a6a2b..40fef6660e 100644 --- a/django/db/backends/postgresql/schema.py +++ b/django/db/backends/postgresql/schema.py @@ -56,8 +56,6 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): ) def quote_value(self, value): - if isinstance(value, str): - value = value.replace("%", "%%") return sql.quote(value, self.connection.connection) def _field_indexes_sql(self, model, field): diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index 0135dbc538..b67a871bc8 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -3662,7 +3662,7 @@ class OperationTests(OperationTestBase): ), # Literal "%" should be escaped in a way that is not a considered a # wildcard. - (models.Q(rebate__endswith="%"), {"rebate": "10%"}, {"rebate": "10$"}), + (models.Q(rebate__endswith="%"), {"rebate": "10%"}, {"rebate": "10%$"}), # Right-hand-side baked "%" literals should not be used for # parameters interpolation. ( @@ -3670,6 +3670,12 @@ class OperationTests(OperationTestBase): {"name": "Albert"}, {"name": "Albert", "surname": "Alberto"}, ), + # Exact matches against "%" literals should also be supported. + ( + models.Q(name="%"), + {"name": "%"}, + {"name": "Albert"}, + ), ] for check, valid, invalid in checks: with self.subTest(check=check, valid=valid, invalid=invalid): |