Uploaded image for project: 'WiredTiger'
  1. WiredTiger
  2. WT-1714

broken search in index with custom collator

    • Type: Icon: Task Task
    • Resolution: Done
    • WT2.5.3
    • Affects Version/s: None
    • Component/s: None
    • Labels:

      Hi!

      I implemented custom index collator as described in [Custom Collators for Indices] (http://source.wiredtiger.com/develop/custom_collators.html)
      But looks like I need to consider the case when search on secondary key is performed and thus I have no primary key for the first key given to

      Unable to find source-code formatter for language: wt_collator. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      ::compare()

      Could you please advise how I can do that?

      Test that demonstrates the problem:

      #include <assert.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      #include <wiredtiger.h>
      
      #define WT_HOME "index_collator.db"
      
      #define WT_CALL(call) \
          do { \
              const int __rc = call; \
              if (__rc != 0) { \
                  fprintf(stderr, # call " at (%s:%d) failed: %s [%d]\n", __FILE__, __LINE__, wiredtiger_strerror(__rc), __rc); \
                  exit(EXIT_FAILURE); \
              } \
          } while (0)
      
      static int
      compare_int(int a, int b)
      {
          return (a < b ? -1 : (a > b ? 1 : 0));
      }
      
      static int
      index_compare(WT_COLLATOR *collator, WT_SESSION *session,
                    const WT_ITEM *key1, const WT_ITEM *key2, int *cmp)
      {
          int rc;
          int ikey1 = 12345, pkey1 = 54321, ikey2 = 67890, pkey2 = 9876;
      
          WT_CALL(wiredtiger_struct_unpack(session, key1->data, key1->size, "ii", &ikey1, &pkey1));
          WT_CALL(wiredtiger_struct_unpack(session, key2->data, key2->size, "ii", &ikey2, &pkey2));
      
          printf("index_compare: ikey1 = %d, pkey1 = %d, ikey2 = %d, pkey2 = %d\n", ikey1, pkey1, ikey2, pkey2);
      
          if ((*cmp = compare_int(ikey1, ikey2)) != 0)
              return 0;
      
          *cmp = compare_int(pkey1, pkey2);
          return 0;
      }
      
      static WT_COLLATOR index_coll = { index_compare, NULL, NULL };
      
      int
      main(void)
      {
          WT_CONNECTION *conn;
          WT_SESSION *session;
          WT_CURSOR *cursor;
      
          assert(system("rm -rf \"" WT_HOME "\" && mkdir \"" WT_HOME "\"") == 0);
      
          WT_CALL(wiredtiger_open(WT_HOME, NULL, "create", &conn));
          WT_CALL(conn->open_session(conn, NULL, NULL, &session));
      
          WT_CALL(conn->add_collator(conn, "index_coll", &index_coll, NULL));
      
          WT_CALL(session->create(session, "table:main", "key_format=i,value_format=i,columns=(k,v)"));
          WT_CALL(session->create(session, "index:main:index", "columns=(v),collator=index_coll"));
      
          WT_CALL(session->open_cursor(session, "table:main", NULL, NULL, &cursor));
          cursor->set_key(cursor, 13);
          cursor->set_value(cursor, 17);
          WT_CALL(cursor->insert(cursor));
          WT_CALL(cursor->close(cursor));
      
          WT_CALL(session->open_cursor(session, "index:main:index", NULL, NULL, &cursor));
      
          while (cursor->next(cursor) == 0) {
              int ikey, val;
              WT_CALL(cursor->get_key(cursor, &ikey));
              WT_CALL(cursor->get_value(cursor, &val));
              printf("ikey = %d, value = %d\n", ikey, val);
          }
      
          cursor->set_key(cursor, 17);
          WT_CALL(cursor->search(cursor));
      
          WT_CALL(cursor->close(cursor));
      
          WT_CALL(conn->close(conn, NULL));
      
          return 0;
      }
      

      Running it I can get:

      $ ./index_collator
      ikey = 17, value = 17
      wiredtiger_struct_unpack(session, key1->data, key1->size, "ii", &ikey1, &pkey1) at (index_collator.c:32) failed: Invalid argument [22]
      $ ./index_collator
      ikey = 17, value = 17
      index_compare: ikey1 = 17, pkey1 = 2962, ikey2 = 17, pkey2 = 13
      cursor->search(cursor) at (index_collator.c:79) failed: WT_NOTFOUND: item not found [-31803]
      $ ./index_collator
      ikey = 17, value = 17
      index_compare: ikey1 = 17, pkey1 = -21, ikey2 = 17, pkey2 = 13
      index_compare: ikey1 = 17, pkey1 = -21, ikey2 = 17, pkey2 = 13
      index_compare: ikey1 = 17, pkey1 = -21, ikey2 = 17, pkey2 = 13
      

      Thanks!

            Assignee:
            donald.anderson@mongodb.com Donald Anderson
            Reporter:
            dmitri-shubin Dmitri Shubin
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: