Resolving issue of improper handling of indexes in auto migrations.
Fixed two issues in this CL:
1) When a brand new table is added in the new database version, only the CREATE TABLE statement was used in constructing the new table. This was an invalid approach as the CREATE TABLE SQL statements do not include the statements required to create the indexes associated with this table. Therefore, even if there were indexes in the new table, the statements for adding them to the table would not be added in AutoMigrationWriter. This issue was only valid for the case of indexes, as foreign keys are included in the CREATE TABLE statements, and views are destroyed and recreated by our implementation independent of CREATE TABLE (regardless of any changes).
2) When we check for new added columns, we have logic in place that avoids processing any new columns detected in a table that has already been discovered as a "complex changed table", as this table will be destroyed and recreated from scratch already, and the new added columns will be handled automatically in this process. In the previous logic, we were conducting this check by looking up the name of the "toTable" in the map of complex changed tables. This was incorrect as the map is keyed by the table names in the "from" version of the database, therefore if a table was renamed and included complex changes and had a new column added to it, this check would fail (as the table would not be found in the map).
A new Entity has been added to AutoMigrationDb to check for these cases.
Bug: 189726437
Test: AutoMigrationTest.java
Change-Id: I2554abe0e5ea2d5c5031ab6112862c25b7d5879c
diff --git a/room/integration-tests/testapp/schemas/androidx.room.integration.testapp.migration.AutoMigrationDb/2.json b/room/integration-tests/testapp/schemas/androidx.room.integration.testapp.migration.AutoMigrationDb/2.json
index aa7dd78..f8edc20 100644
--- a/room/integration-tests/testapp/schemas/androidx.room.integration.testapp.migration.AutoMigrationDb/2.json
+++ b/room/integration-tests/testapp/schemas/androidx.room.integration.testapp.migration.AutoMigrationDb/2.json
@@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 2,
- "identityHash": "24a4a9a632f303b32cc8cfcc1534a1b1",
+ "identityHash": "2dee70d4b5bbc3df9701e56eedb6377c",
"entities": [
{
"tableName": "Entity1",
@@ -874,6 +874,48 @@
},
"indices": [],
"foreignKeys": []
+ },
+ {
+ "tableName": "Entity26",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, `addedInV2` INTEGER NOT NULL DEFAULT 1, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": false
+ },
+ {
+ "fieldPath": "addedInV2",
+ "columnName": "addedInV2",
+ "affinity": "INTEGER",
+ "notNull": true,
+ "defaultValue": "1"
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [
+ {
+ "name": "index_Entity26_addedInV2",
+ "unique": true,
+ "columnNames": [
+ "addedInV2"
+ ],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Entity26_addedInV2` ON `${TABLE_NAME}` (`addedInV2`)"
+ }
+ ],
+ "foreignKeys": []
}
],
"views": [
@@ -884,7 +926,7 @@
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
- "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '24a4a9a632f303b32cc8cfcc1534a1b1')"
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2dee70d4b5bbc3df9701e56eedb6377c')"
]
}
}
\ No newline at end of file
diff --git a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/migration/AutoMigrationDb.java b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/migration/AutoMigrationDb.java
index 186befee..e4e47974 100644
--- a/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/migration/AutoMigrationDb.java
+++ b/room/integration-tests/testapp/src/androidTest/java/androidx/room/integration/testapp/migration/AutoMigrationDb.java
@@ -66,7 +66,8 @@
AutoMigrationDb.Entity22.class,
AutoMigrationDb.Entity23.class,
AutoMigrationDb.Entity24.class,
- AutoMigrationDb.Entity25.class
+ AutoMigrationDb.Entity25.class,
+ AutoMigrationDb.Entity26.class
},
autoMigrations = {
@AutoMigration(
@@ -420,6 +421,19 @@
public int entity1Id;
}
+ /**
+ * Added a new table that has an index.
+ */
+ @Entity(indices = {@Index(value = {"addedInV2"}, unique = true)})
+ static class Entity26 {
+ public static final String TABLE_NAME = "Entity26";
+ @PrimaryKey
+ public int id;
+ public String name;
+ @ColumnInfo(defaultValue = "1")
+ public int addedInV2;
+ }
+
@Dao
interface AutoMigrationDao {
@Query("SELECT * from Entity1 ORDER BY id ASC")
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/util/SchemaDiffer.kt b/room/room-compiler/src/main/kotlin/androidx/room/util/SchemaDiffer.kt
index d041082..e499404 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/util/SchemaDiffer.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/util/SchemaDiffer.kt
@@ -556,7 +556,7 @@
// Check if the new column is on a table with complex changes. If so, no
// need to account for it as the table will be recreated already with the new
// table.
- if (!complexChangedTables.containsKey(toTable.tableName)) {
+ if (!complexChangedTables.containsKey(fromTable.tableName)) {
addedColumns[toColumn.columnName] =
AutoMigration.AddedColumn(
toTable.tableName,
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/writer/AutoMigrationWriter.kt b/room/room-compiler/src/main/kotlin/androidx/room/writer/AutoMigrationWriter.kt
index b19107f..8f4b05c 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/writer/AutoMigrationWriter.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/writer/AutoMigrationWriter.kt
@@ -453,6 +453,7 @@
migrateBuilder,
addedTable.entityBundle.createTable()
)
+ addStatementsToRecreateIndexes(addedTable.entityBundle, migrateBuilder)
}
}