Uploaded image for project: 'Realm Core'
  1. Realm Core
  2. RCORE-1681

Handle collection type mismatch for `Set` in `Mixed`.

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Unknown 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;
      }
      

            Assignee:
            nicola.cabiddu@mongodb.com Nicola Cabiddu
            Reporter:
            nicola.cabiddu@mongodb.com Nicola Cabiddu
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: