-
Type: Bug
-
Resolution: Fixed
-
Priority: Unknown
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
Expected results
For collections in mixed, we detect and bubble up possible errors due to collection type mismatches.
Example:
realm_set_collection(obj1.get(), foo_any_col_key, RLM_COLLECTION_TYPE_LIST); realm_value_t value; realm_get_value(obj1.get(), foo_any_col_key, &value); auto list = cptr_checked(realm_get_list(obj1.get(), foo_any_col_key)); realm_list_insert_collection(list.get(), 0, RLM_COLLECTION_TYPE_LIST); auto n_list = cptr_checked(realm_list_get_list(list.get(), 0)); realm_list_insert(n_list.get(), 0, rlm_str_val("Test1")); realm_list_set_collection(list.get(), 0, RLM_COLLECTION_TYPE_DICTIONARY); //the accessor has become invalid. Trying to use for inserting into the list should fail, with some exception be thrown. realm_list_insert(n_list.get(), 1, rlm_str_val("Test2"));
Code that catches the error:
bool Lst<Mixed>::init_from_parent(bool allow_create) const { if (!m_tree) { m_tree.reset(new BPlusTreeMixed(get_alloc())); const ArrayParent* parent = this; m_tree->set_parent(const_cast<ArrayParent*>(parent), 0); } try { auto ref = Base::get_collection_ref(); if (ref) { m_tree->init_from_ref(ref); } else { if (!allow_create) { m_tree->detach(); return false; } // The ref in the column was NULL, create the tree in place. m_tree->create(); REALM_ASSERT(m_tree->is_attached()); } } catch (...) { m_tree->detach(); return false; } return true; }
After this point, if we don't check the boolean, the mismatch exception will be lost. We do this for List and Dictionaries, but not for Sets. We should instead record the error and propagate the exception further.
In particular, this is the code that deals with the failure for Lst<Mixed>. The same should be done for Sets.
ref_type Lst<Mixed>::get_collection_ref(Index index, CollectionType type) const { auto ndx = m_tree->find_key(mpark::get<int64_t>(index)); if (ndx != realm::not_found) { auto val = get(ndx); if (val.is_null() || !val.is_type(DataType(int(type)))) { throw IllegalOperation("Not proper collection type"); } return val.get_ref(); } return 0; }