From e2b9d3c330e86cf3cfff4f59de50b56d2d142bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Edelbo?= Date: Mon, 11 Nov 2024 16:15:06 +0100 Subject: [PATCH] Fix issue when changing type of primary key If you change the type of the primary key and call Realm::update_schema() without a migration function, the new column will not be set as primary key column. --- CHANGELOG.md | 2 +- src/realm/object-store/object_store.cpp | 9 ++++++--- test/object-store/migrations.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e36d4b963f..1f43ae9c2af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ * None. ### Fixed -* ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?) +* Migrating primary key to a new type without migration function would cause an assertion to fail. ([#8045](https://github.com/realm/realm-core/issues/8045), since v10.0.0) * None. ### Breaking changes diff --git a/src/realm/object-store/object_store.cpp b/src/realm/object-store/object_store.cpp index 1190c5865ff..254cb0b2721 100644 --- a/src/realm/object-store/object_store.cpp +++ b/src/realm/object-store/object_store.cpp @@ -124,7 +124,8 @@ ColKey add_column(Group& group, Table& table, Property const& property) REALM_ASSERT(property.type != PropertyType::LinkingObjects); if (property.is_primary) { - // Primary key columns should have been created when the table was created + // Primary key columns should have been created when the table was created. + // Unless this is a migration if (auto col = table.get_column_key(property.name)) { return col; } @@ -139,9 +140,11 @@ ColKey add_column(Group& group, Table& table, Property const& property) else { auto key = table.add_column(to_core_type(property.type), property.name, is_nullable(property.type), collection_type); - if (property.requires_index()) + if (property.is_primary) + table.set_primary_key_column(key); // You can end here if this is a migration + else if (property.requires_index()) table.add_search_index(key); - if (property.requires_fulltext_index()) + else if (property.requires_fulltext_index()) table.add_fulltext_index(key); return key; } diff --git a/test/object-store/migrations.cpp b/test/object-store/migrations.cpp index 2c47a1acce4..dd4968fc214 100644 --- a/test/object-store/migrations.cpp +++ b/test/object-store/migrations.cpp @@ -1137,6 +1137,31 @@ TEST_CASE("migration: Automatic", "[migration]") { }); } + SECTION("change primary key from string to UUID without migration function") { + using namespace std::string_literals; + Schema schema{{"Foo", + { + {"_id", PropertyType::String, Property::IsPrimary{true}}, + }}}; + Schema schema2{{"Foo", + { + {"_id", PropertyType::UUID, Property::IsPrimary{true}}, + }}}; + InMemoryTestFile config; + config.schema_mode = SchemaMode::Automatic; + config.schema = schema; + auto realm = Realm::get_shared_realm(config); + realm->update_schema(schema2, 2); + + CppContext ctx(realm); + std::any values = AnyDict{ + {"_id", UUID("3b241101-0000-0000-0000-4136c566a964"s)}, + }; + realm->begin_transaction(); + Object::create(ctx, realm, *realm->schema().find("Foo"), values); + realm->commit_transaction(); + } + SECTION("object accessors inside migrations") { using namespace std::string_literals;