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

[C-API] Query arguments with list of strings are not copied when query is parsed

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: None
    • Component/s: None
    • None

      While implementing support for passing lists as query arguments to the RQL IN operator in Realm Kotlin (https://github.com/realm/realm-kotlin/pull/1389) to support something like:

      realm.writeBlocking {
          copyToRealm(QuerySample().apply { stringField = "1" }) 
          copyToRealm(QuerySample().apply { stringField = "2" }) 
      }
      realm.query<QuerySample>("stringField IN $0", listOf("1", "2") ).find().run {
          assertEquals(2, size)
      }
      

      The above test fails as the query does not return any objects.

      After debugging and verifying that arguments are correctly transferred as part of calling
      realm_query_parse I wrote this C-API test:

      SECTION("string in list") {
                      char foo[] = "foo";
                      realm_value_t str = rlm_str_val(foo);
                      realm_value_t list_arg[2] = {str, rlm_str_val("bar")};
      
                      write([&]() {
                          CHECK(realm_set_value(obj1.get(), foo_properties["string"], rlm_str_val("foo"), false));
                      });
      
                      static const size_t num_args = 1;
                      realm_query_arg_t args[num_args] = { realm_query_arg_t{2, true, &list_arg[0]} };
                      realm_query_arg_t* arg_list = &args[0];
                      auto q_string_in_list = cptr_checked(realm_query_parse(realm, class_foo.key, "string IN $0", num_args, arg_list));
                          
                      char* s = foo;
                      s[0] = 'a';
                      size_t count;
      
                      CHECK(checked(realm_query_count(q_string_in_list.get(), &count)));
                      CHECK(1 == count);
      }
      

      Seems to be that buffers referenced from realm_value_t.string}}s referenced from the {{realm_query_arg_t is not copied into C-API memory space. This is different behavior compared to all other methods in the C-API and I would have expected realm_query_parse to get hold of any data needed to execute the query at a later stage. A similar test for passing a single non-list string argument to realm_query_parse returns the correct result even if the buffer is changed between parsing and executing the actual query.

      Kotlin tests for integer and boolean argument lists works. I assume that this is because that the are copied as part of converting {{realm_value_t}}s to mixed.

      But the similar test with list of links also doesn't work even though they should be fully contained in the realm_value_t, so there might be more to it.

      The above test is pushed to https://github.com/realm/realm-core/commits/cr/query-in-string-list

      Core version

      Core version: ~13.10.1 commit a546bd453eea532fce14dfdeebf14973f3852ad7

            Assignee:
            nicola.cabiddu@mongodb.com Nicola Cabiddu
            Reporter:
            claus.rorbech@mongodb.com Claus Rørbech (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: