diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/cursor/cur_index.c')
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_index.c | 73 |
1 files changed, 58 insertions, 15 deletions
diff --git a/src/third_party/wiredtiger/src/cursor/cur_index.c b/src/third_party/wiredtiger/src/cursor/cur_index.c index bf086bcc813..7b234eab280 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_index.c +++ b/src/third_party/wiredtiger/src/cursor/cur_index.c @@ -61,6 +61,35 @@ err: cursor->saved_err = ret; } /* + * __curindex_compare -- + * WT_CURSOR->compare method for the index cursor type. + */ +static int +__curindex_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) +{ + WT_CURSOR_INDEX *cindex; + WT_DECL_RET; + WT_SESSION_IMPL *session; + + cindex = (WT_CURSOR_INDEX *)a; + CURSOR_API_CALL(a, session, compare, NULL); + + /* Check both cursors are "index:" type. */ + if (!WT_PREFIX_MATCH(a->uri, "index:") || + !WT_PREFIX_MATCH(b->uri, "index:")) + WT_ERR_MSG(session, EINVAL, + "Cursors must reference the same object"); + + WT_CURSOR_CHECKKEY(a); + WT_CURSOR_CHECKKEY(b); + + ret = __wt_compare( + session, cindex->index->collator, &a->key, &b->key, cmpp); + +err: API_END_RET(session, ret); +} + +/* * __curindex_move -- * When an index cursor changes position, set the primary key in the * associated column groups and update their positions to match. @@ -189,32 +218,46 @@ __curindex_search(WT_CURSOR *cursor) WT_CURSOR *child; WT_CURSOR_INDEX *cindex; WT_DECL_RET; + WT_ITEM found_key; WT_SESSION_IMPL *session; - int exact; + int cmp; cindex = (WT_CURSOR_INDEX *)cursor; child = cindex->child; CURSOR_API_CALL(cursor, session, search, NULL); /* - * We expect partial matches, but we want the smallest item that - * matches the prefix. Fail if there is no matching item. + * We are searching using the application-specified key, which + * (usually) doesn't contain the primary key, so it is just a prefix of + * any matching index key. Do a search_near, step to the next entry if + * we land on one that is too small, then check that the prefix + * matches. */ __wt_cursor_set_raw_key(child, &cursor->key); - WT_ERR(child->search_near(child, &exact)); + WT_ERR(child->search_near(child, &cmp)); + + if (cmp < 0) + WT_ERR(child->next(child)); /* * We expect partial matches, and want the smallest record with a key - * greater than or equal to the search key. The only way for the key - * to be equal is if there is an index on the primary key, because - * otherwise the primary key columns will be appended to the index key, - * but we don't disallow that (odd) case. + * greater than or equal to the search key. + * + * If the key we find is shorter than the search key, it can't possibly + * match. + * + * The only way for the key to be exactly equal is if there is an index + * on the primary key, because otherwise the primary key columns will + * be appended to the index key, but we don't disallow that (odd) case. */ - if (exact < 0) - WT_ERR(child->next(child)); - - if (child->key.size < cursor->key.size || - memcmp(child->key.data, cursor->key.data, cursor->key.size) != 0) { + found_key = child->key; + if (found_key.size < cursor->key.size) + WT_ERR(WT_NOTFOUND); + found_key.size = cursor->key.size; + + WT_ERR(__wt_compare( + session, cindex->index->collator, &cursor->key, &found_key, &cmp)); + if (cmp != 0) { ret = WT_NOTFOUND; goto err; } @@ -342,8 +385,8 @@ __wt_curindex_open(WT_SESSION_IMPL *session, __curindex_get_value, /* get-value */ __wt_cursor_set_key, /* set-key */ __curindex_set_value, /* set-value */ - __wt_cursor_notsup, /* compare */ - __wt_cursor_notsup, /* equals */ + __curindex_compare, /* compare */ + __wt_cursor_equals, /* equals */ __curindex_next, /* next */ __curindex_prev, /* prev */ __curindex_reset, /* reset */ |