From 23ac35af19face4ad0b466f5aaffafd5db98db0e Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Tue, 21 Jun 2016 00:01:03 -0400 Subject: [PATCH] [1.10.x] Fixed #26781 -- Made table name case change a noop on SQLite. SQLite disgresses from the SQL standard by ignoring case of quoted identifiers. Thanks to laozzzi for the report and Tim for the review. Backport of c2e62fd1aed093c4d9ff84e3d86e6a85c8aa1917 from master --- django/db/backends/base/features.py | 4 ++++ django/db/backends/base/schema.py | 4 +++- django/db/backends/oracle/features.py | 3 +++ django/db/backends/sqlite3/features.py | 1 + tests/schema/tests.py | 9 +++++++++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py index 91065ecc99..484b272294 100644 --- a/django/db/backends/base/features.py +++ b/django/db/backends/base/features.py @@ -221,6 +221,10 @@ class BaseDatabaseFeatures(object): # Defaults to False to allow third-party backends to opt-in. can_clone_databases = False + # Does the backend consider quoted identifiers with different casing to + # be equal? + ignores_quoted_identifier_case = False + def __init__(self, connection): self.connection = connection diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py index 2fd0d2738c..156f119c0d 100644 --- a/django/db/backends/base/schema.py +++ b/django/db/backends/base/schema.py @@ -363,7 +363,9 @@ class BaseDatabaseSchemaEditor(object): """ Renames the table a model points to. """ - if old_db_table == new_db_table: + if (old_db_table == new_db_table or + (self.connection.features.ignores_quoted_identifier_case and + old_db_table.lower() == new_db_table.lower())): return self.execute(self.sql_rename_table % { "old_table": self.quote_name(old_db_table), diff --git a/django/db/backends/oracle/features.py b/django/db/backends/oracle/features.py index ee300f3530..84e18cf9ba 100644 --- a/django/db/backends/oracle/features.py +++ b/django/db/backends/oracle/features.py @@ -40,6 +40,9 @@ class DatabaseFeatures(BaseDatabaseFeatures): # select for update with limit can be achieved on Oracle, but not with the current backend. supports_select_for_update_with_limit = False supports_temporal_subtraction = True + # Oracle doesn't ignore quoted identifiers case but the current backend + # does by uppercasing all identifiers. + ignores_quoted_identifier_case = True def introspected_boolean_field_type(self, field=None, created_separately=False): """ diff --git a/django/db/backends/sqlite3/features.py b/django/db/backends/sqlite3/features.py index acf20d569f..e834ec61a3 100644 --- a/django/db/backends/sqlite3/features.py +++ b/django/db/backends/sqlite3/features.py @@ -39,6 +39,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): supports_sequence_reset = False can_clone_databases = True supports_temporal_subtraction = True + ignores_quoted_identifier_case = True @cached_property def uses_savepoints(self): diff --git a/tests/schema/tests.py b/tests/schema/tests.py index b0d5b407ac..8b35b77c7b 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -825,6 +825,15 @@ class SchemaTests(TransactionTestCase): author_is_fk = True self.assertTrue(author_is_fk, "No FK constraint for author_id found") + def test_alter_db_table_case(self): + # Create the table + with connection.schema_editor() as editor: + editor.create_model(Author) + # Alter the case of the table + old_table_name = Author._meta.db_table + with connection.schema_editor() as editor: + editor.alter_db_table(Author, old_table_name, old_table_name.upper()) + def test_alter_implicit_id_to_explicit(self): """ Should be able to convert an implicit "id" field to an explicit "id"