diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/cursor')
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_backup.c | 4 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_bulk.c | 20 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_config.c | 4 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_ds.c | 16 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_dump.c | 4 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_file.c | 93 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_index.c | 8 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_join.c | 7 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_json.c | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_log.c | 4 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_metadata.c | 8 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_stat.c | 12 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_std.c | 126 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/cursor/cur_table.c | 67 |
14 files changed, 300 insertions, 75 deletions
diff --git a/src/third_party/wiredtiger/src/cursor/cur_backup.c b/src/third_party/wiredtiger/src/cursor/cur_backup.c index 61ced8d11e7..60750b88900 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_backup.c +++ b/src/third_party/wiredtiger/src/cursor/cur_backup.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -119,8 +119,10 @@ __wt_curbackup_open(WT_SESSION_IMPL *session, __wt_cursor_notsup, /* search */ __wt_cursor_search_near_notsup, /* search-near */ __wt_cursor_notsup, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __wt_cursor_notsup, /* update */ __wt_cursor_notsup, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __curbackup_close); /* close */ WT_CURSOR *cursor; diff --git a/src/third_party/wiredtiger/src/cursor/cur_bulk.c b/src/third_party/wiredtiger/src/cursor/cur_bulk.c index 68611e30ff1..56bcbb741f7 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_bulk.c +++ b/src/third_party/wiredtiger/src/cursor/cur_bulk.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -58,11 +58,11 @@ __curbulk_insert_fix(WT_CURSOR *cursor) if (F_ISSET(cursor, WT_CURSTD_APPEND)) recno = cbulk->recno + 1; else { - WT_CURSOR_CHECKKEY(cursor); + WT_ERR(__cursor_checkkey(cursor)); if ((recno = cursor->recno) <= cbulk->recno) WT_ERR(__bulk_col_keycmp_err(cbulk)); } - WT_CURSOR_CHECKVALUE(cursor); + WT_ERR(__cursor_checkvalue(cursor)); /* * Insert any skipped records as deleted records, update the current @@ -101,7 +101,7 @@ __curbulk_insert_fix_bitmap(WT_CURSOR *cursor) CURSOR_API_CALL(cursor, session, insert, btree); WT_STAT_DATA_INCR(session, cursor_insert_bulk); - WT_CURSOR_CHECKVALUE(cursor); + WT_ERR(__cursor_checkvalue(cursor)); /* Insert the current record. */ ret = __wt_bulk_insert_fix_bitmap(session, cbulk); @@ -140,11 +140,11 @@ __curbulk_insert_var(WT_CURSOR *cursor) if (F_ISSET(cursor, WT_CURSTD_APPEND)) recno = cbulk->recno + 1; else { - WT_CURSOR_CHECKKEY(cursor); + WT_ERR(__cursor_checkkey(cursor)); if ((recno = cursor->recno) <= cbulk->recno) WT_ERR(__bulk_col_keycmp_err(cbulk)); } - WT_CURSOR_CHECKVALUE(cursor); + WT_ERR(__cursor_checkvalue(cursor)); if (!cbulk->first_insert) { /* @@ -241,8 +241,8 @@ __curbulk_insert_row(WT_CURSOR *cursor) CURSOR_API_CALL(cursor, session, insert, btree); WT_STAT_DATA_INCR(session, cursor_insert_bulk); - WT_CURSOR_CHECKKEY(cursor); - WT_CURSOR_CHECKVALUE(cursor); + WT_ERR(__cursor_checkkey(cursor)); + WT_ERR(__cursor_checkvalue(cursor)); /* * If this isn't the first key inserted, compare it against the last key @@ -288,8 +288,8 @@ __curbulk_insert_row_skip_check(WT_CURSOR *cursor) CURSOR_API_CALL(cursor, session, insert, btree); WT_STAT_DATA_INCR(session, cursor_insert_bulk); - WT_CURSOR_CHECKKEY(cursor); - WT_CURSOR_CHECKVALUE(cursor); + WT_ERR(__cursor_checkkey(cursor)); + WT_ERR(__cursor_checkvalue(cursor)); ret = __wt_bulk_insert_row(session, cbulk); diff --git a/src/third_party/wiredtiger/src/cursor/cur_config.c b/src/third_party/wiredtiger/src/cursor/cur_config.c index 4001188e21c..6c198315e33 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_config.c +++ b/src/third_party/wiredtiger/src/cursor/cur_config.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -39,8 +39,10 @@ __wt_curconfig_open(WT_SESSION_IMPL *session, __wt_cursor_notsup, /* search */ __wt_cursor_search_near_notsup, /* search-near */ __wt_cursor_notsup, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __wt_cursor_notsup, /* update */ __wt_cursor_notsup, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __curconfig_close); WT_CURSOR_CONFIG *cconfig; diff --git a/src/third_party/wiredtiger/src/cursor/cur_ds.c b/src/third_party/wiredtiger/src/cursor/cur_ds.c index 131d1ffa930..10de133be75 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_ds.c +++ b/src/third_party/wiredtiger/src/cursor/cur_ds.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -42,7 +42,7 @@ __curds_key_set(WT_CURSOR *cursor) source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source; - WT_CURSOR_NEEDKEY(cursor); + WT_ERR(__cursor_needkey(cursor)); source->recno = cursor->recno; source->key.data = cursor->key.data; @@ -63,7 +63,7 @@ __curds_value_set(WT_CURSOR *cursor) source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source; - WT_CURSOR_NEEDVALUE(cursor); + WT_ERR(__cursor_needvalue(cursor)); source->value.data = cursor->value.data; source->value.size = cursor->value.size; @@ -142,8 +142,8 @@ __curds_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) WT_ERR_MSG(session, EINVAL, "Cursors must reference the same object"); - WT_CURSOR_NEEDKEY(a); - WT_CURSOR_NEEDKEY(b); + WT_ERR(__cursor_needkey(a)); + WT_ERR(__cursor_needkey(b)); if (WT_CURSOR_RECNO(a)) { if (a->recno < b->recno) @@ -317,7 +317,7 @@ __curds_insert(WT_CURSOR *cursor) source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source; - CURSOR_UPDATE_API_CALL(cursor, session, insert, NULL); + CURSOR_UPDATE_API_CALL(cursor, session, insert); __curds_txn_enter(session); @@ -350,7 +350,7 @@ __curds_update(WT_CURSOR *cursor) source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source; - CURSOR_UPDATE_API_CALL(cursor, session, update, NULL); + CURSOR_UPDATE_API_CALL(cursor, session, update); WT_STAT_CONN_INCR(session, cursor_update); WT_STAT_DATA_INCR(session, cursor_update); @@ -458,8 +458,10 @@ __wt_curds_open( __curds_search, /* search */ __curds_search_near, /* search-near */ __curds_insert, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __curds_update, /* update */ __curds_remove, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __curds_close); /* close */ WT_CONFIG_ITEM cval, metadata; diff --git a/src/third_party/wiredtiger/src/cursor/cur_dump.c b/src/third_party/wiredtiger/src/cursor/cur_dump.c index d7f18bb61ac..3e90d321db6 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_dump.c +++ b/src/third_party/wiredtiger/src/cursor/cur_dump.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -369,8 +369,10 @@ __wt_curdump_create(WT_CURSOR *child, WT_CURSOR *owner, WT_CURSOR **cursorp) __curdump_search, /* search */ __curdump_search_near, /* search-near */ __curdump_insert, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __curdump_update, /* update */ __curdump_remove, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __curdump_close); /* close */ WT_CURSOR *cursor; diff --git a/src/third_party/wiredtiger/src/cursor/cur_file.c b/src/third_party/wiredtiger/src/cursor/cur_file.c index 205afb607c3..3b6328a2d93 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_file.c +++ b/src/third_party/wiredtiger/src/cursor/cur_file.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -31,8 +31,8 @@ __curfile_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) WT_ERR_MSG(session, EINVAL, "Cursors must reference the same object"); - WT_CURSOR_CHECKKEY(a); - WT_CURSOR_CHECKKEY(b); + WT_ERR(__cursor_checkkey(a)); + WT_ERR(__cursor_checkkey(b)); ret = __wt_btcur_compare( (WT_CURSOR_BTREE *)a, (WT_CURSOR_BTREE *)b, cmpp); @@ -63,8 +63,8 @@ __curfile_equals(WT_CURSOR *a, WT_CURSOR *b, int *equalp) WT_ERR_MSG(session, EINVAL, "Cursors must reference the same object"); - WT_CURSOR_CHECKKEY(a); - WT_CURSOR_CHECKKEY(b); + WT_ERR(__cursor_checkkey(a)); + WT_ERR(__cursor_checkkey(b)); ret = __wt_btcur_equals( (WT_CURSOR_BTREE *)a, (WT_CURSOR_BTREE *)b, equalp); @@ -182,9 +182,7 @@ __curfile_search(WT_CURSOR *cursor) cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, search, cbt->btree); - - WT_CURSOR_CHECKKEY(cursor); - WT_CURSOR_NOVALUE(cursor); + WT_ERR(__cursor_checkkey(cursor)); WT_ERR(__wt_btcur_search(cbt)); @@ -209,9 +207,7 @@ __curfile_search_near(WT_CURSOR *cursor, int *exact) cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, search_near, cbt->btree); - - WT_CURSOR_CHECKKEY(cursor); - WT_CURSOR_NOVALUE(cursor); + WT_ERR(__cursor_checkkey(cursor)); WT_ERR(__wt_btcur_search_near(cbt, exact)); @@ -235,11 +231,11 @@ __curfile_insert(WT_CURSOR *cursor) WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; - CURSOR_UPDATE_API_CALL(cursor, session, insert, cbt->btree); + CURSOR_UPDATE_API_CALL_BTREE(cursor, session, insert, cbt->btree); if (!F_ISSET(cursor, WT_CURSTD_APPEND)) - WT_CURSOR_CHECKKEY(cursor); - WT_CURSOR_CHECKVALUE(cursor); + WT_ERR(__cursor_checkkey(cursor)); + WT_ERR(__cursor_checkvalue(cursor)); WT_ERR(__wt_btcur_insert(cbt)); @@ -269,10 +265,8 @@ __wt_curfile_insert_check(WT_CURSOR *cursor) WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; - CURSOR_UPDATE_API_CALL(cursor, session, update, cbt->btree); - - WT_CURSOR_CHECKKEY(cursor); - WT_CURSOR_NOVALUE(cursor); + CURSOR_UPDATE_API_CALL_BTREE(cursor, session, update, cbt->btree); + WT_ERR(__cursor_checkkey(cursor)); ret = __wt_btcur_insert_check(cbt); @@ -292,10 +286,9 @@ __curfile_update(WT_CURSOR *cursor) WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)cursor; - CURSOR_UPDATE_API_CALL(cursor, session, update, cbt->btree); - - WT_CURSOR_CHECKKEY(cursor); - WT_CURSOR_CHECKVALUE(cursor); + CURSOR_UPDATE_API_CALL_BTREE(cursor, session, update, cbt->btree); + WT_ERR(__cursor_checkkey(cursor)); + WT_ERR(__cursor_checkvalue(cursor)); WT_ERR(__wt_btcur_update(cbt)); @@ -321,9 +314,7 @@ __curfile_remove(WT_CURSOR *cursor) cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_REMOVE_API_CALL(cursor, session, cbt->btree); - - WT_CURSOR_CHECKKEY(cursor); - WT_CURSOR_NOVALUE(cursor); + WT_ERR(__cursor_checkkey(cursor)); WT_ERR(__wt_btcur_remove(cbt)); @@ -343,6 +334,47 @@ err: CURSOR_UPDATE_API_END(session, ret); } /* + * __curfile_reserve -- + * WT_CURSOR->reserve method for the btree cursor type. + */ +static int +__curfile_reserve(WT_CURSOR *cursor) +{ + WT_CURSOR_BTREE *cbt; + WT_DECL_RET; + WT_SESSION_IMPL *session; + + cbt = (WT_CURSOR_BTREE *)cursor; + CURSOR_UPDATE_API_CALL_BTREE(cursor, session, reserve, cbt->btree); + WT_ERR(__cursor_checkkey(cursor)); + + WT_ERR(__wt_txn_context_check(session, true)); + + WT_ERR(__wt_btcur_reserve(cbt)); + + /* + * Reserve maintains a position and key, which doesn't match the library + * API, where reserve maintains a value. Fix the API by searching after + * each successful reserve operation. + */ + WT_ASSERT(session, + F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT); + WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0); + +err: CURSOR_UPDATE_API_END(session, ret); + + /* + * The application might do a WT_CURSOR.get_value call when we return, + * so we need a value and the underlying functions didn't set one up. + * For various reasons, those functions may not have done a search and + * any previous value in the cursor might race with WT_CURSOR.reserve + * (and in cases like LSM, the reserve never encountered the original + * key). For simplicity, repeat the search here. + */ + return (ret == 0 ? cursor->search(cursor) : ret); +} + +/* * __curfile_close -- * WT_CURSOR->close method for the btree cursor type. */ @@ -403,8 +435,10 @@ __curfile_create(WT_SESSION_IMPL *session, __curfile_search, /* search */ __curfile_search_near, /* search-near */ __curfile_insert, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __curfile_update, /* update */ __curfile_remove, /* remove */ + __curfile_reserve, /* reserve */ __wt_cursor_reconfigure, /* reconfigure */ __curfile_close); /* close */ WT_BTREE *btree; @@ -486,7 +520,14 @@ __curfile_create(WT_SESSION_IMPL *session, WT_STAT_DATA_INCR(session, cursor_create); if (0) { -err: WT_TRET(__curfile_close(cursor)); +err: /* + * Our caller expects to release the data handle if we fail. + * Disconnect it from the cursor before closing. + */ + if (session->dhandle != NULL) + __wt_cursor_dhandle_decr_use(session); + cbt->btree = NULL; + WT_TRET(__curfile_close(cursor)); *cursorp = NULL; } diff --git a/src/third_party/wiredtiger/src/cursor/cur_index.c b/src/third_party/wiredtiger/src/cursor/cur_index.c index 6fc01c0421f..e8fcb1b2702 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_index.c +++ b/src/third_party/wiredtiger/src/cursor/cur_index.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -66,8 +66,8 @@ __curindex_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) WT_ERR_MSG(session, EINVAL, "Cursors must reference the same object"); - WT_CURSOR_CHECKKEY(a); - WT_CURSOR_CHECKKEY(b); + WT_ERR(__cursor_checkkey(a)); + WT_ERR(__cursor_checkkey(b)); ret = __wt_compare( session, cindex->index->collator, &a->key, &b->key, cmpp); @@ -449,8 +449,10 @@ __wt_curindex_open(WT_SESSION_IMPL *session, __curindex_search, /* search */ __curindex_search_near, /* search-near */ __wt_cursor_notsup, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __wt_cursor_notsup, /* update */ __wt_cursor_notsup, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __curindex_close); /* close */ WT_CURSOR_INDEX *cindex; diff --git a/src/third_party/wiredtiger/src/cursor/cur_join.c b/src/third_party/wiredtiger/src/cursor/cur_join.c index 80afaf798dc..e4ccb90139e 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_join.c +++ b/src/third_party/wiredtiger/src/cursor/cur_join.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -34,6 +34,7 @@ static int __curjoin_split_key(WT_SESSION_IMPL *, WT_CURSOR_JOIN *, WT_ITEM *, */ int __wt_curjoin_joined(WT_CURSOR *cursor) + WT_GCC_FUNC_ATTRIBUTE((cold)) { WT_SESSION_IMPL *session; @@ -590,8 +591,10 @@ __curjoin_entry_member(WT_SESSION_IMPL *session, WT_CURSOR_JOIN_ENTRY *entry, __wt_cursor_notsup, /* search */ __wt_cursor_search_near_notsup, /* search-near */ __curjoin_extract_insert, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __wt_cursor_notsup, /* update */ __wt_cursor_notsup, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __wt_cursor_notsup); /* close */ WT_DECL_RET; @@ -1291,8 +1294,10 @@ __wt_curjoin_open(WT_SESSION_IMPL *session, __wt_cursor_notsup, /* search */ __wt_cursor_search_near_notsup, /* search-near */ __wt_cursor_notsup, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __wt_cursor_notsup, /* update */ __wt_cursor_notsup, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __curjoin_close); /* close */ WT_CURSOR *cursor; diff --git a/src/third_party/wiredtiger/src/cursor/cur_json.c b/src/third_party/wiredtiger/src/cursor/cur_json.c index e8ddb767863..99b4fc1ce4f 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_json.c +++ b/src/third_party/wiredtiger/src/cursor/cur_json.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * diff --git a/src/third_party/wiredtiger/src/cursor/cur_log.c b/src/third_party/wiredtiger/src/cursor/cur_log.c index e5b56aa406f..38e9d4a1784 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_log.c +++ b/src/third_party/wiredtiger/src/cursor/cur_log.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -342,8 +342,10 @@ __wt_curlog_open(WT_SESSION_IMPL *session, __curlog_search, /* search */ __wt_cursor_search_near_notsup, /* search-near */ __wt_cursor_notsup, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __wt_cursor_notsup, /* update */ __wt_cursor_notsup, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __curlog_close); /* close */ WT_CURSOR *cursor; diff --git a/src/third_party/wiredtiger/src/cursor/cur_metadata.c b/src/third_party/wiredtiger/src/cursor/cur_metadata.c index fbfc73956e2..d9aeed1fccd 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_metadata.c +++ b/src/third_party/wiredtiger/src/cursor/cur_metadata.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -13,7 +13,7 @@ * backing metadata table cursor. */ #define WT_MD_CURSOR_NEEDKEY(cursor) do { \ - WT_CURSOR_NEEDKEY(cursor); \ + WT_ERR(__cursor_needkey(cursor)); \ WT_ERR(__wt_buf_set(session, \ &((WT_CURSOR_METADATA *)(cursor))->file_cursor->key, \ (cursor)->key.data, (cursor)->key.size)); \ @@ -22,7 +22,7 @@ } while (0) #define WT_MD_CURSOR_NEEDVALUE(cursor) do { \ - WT_CURSOR_NEEDVALUE(cursor); \ + WT_ERR(__cursor_needvalue(cursor)); \ WT_ERR(__wt_buf_set(session, \ &((WT_CURSOR_METADATA *)(cursor))->file_cursor->value, \ (cursor)->value.data, (cursor)->value.size)); \ @@ -550,8 +550,10 @@ __wt_curmetadata_open(WT_SESSION_IMPL *session, __curmetadata_search, /* search */ __curmetadata_search_near, /* search-near */ __curmetadata_insert, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __curmetadata_update, /* update */ __curmetadata_remove, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __curmetadata_close); /* close */ WT_CURSOR *cursor; diff --git a/src/third_party/wiredtiger/src/cursor/cur_stat.c b/src/third_party/wiredtiger/src/cursor/cur_stat.c index 0bff642370d..a1ec1d75918 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_stat.c +++ b/src/third_party/wiredtiger/src/cursor/cur_stat.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -54,7 +54,7 @@ __curstat_get_key(WT_CURSOR *cursor, ...) va_start(ap, cursor); CURSOR_API_CALL(cursor, session, get_key, NULL); - WT_CURSOR_NEEDKEY(cursor); + WT_ERR(__cursor_needkey(cursor)); if (F_ISSET(cursor, WT_CURSTD_RAW)) { WT_ERR(__wt_struct_size( @@ -93,7 +93,7 @@ __curstat_get_value(WT_CURSOR *cursor, ...) va_start(ap, cursor); CURSOR_API_CALL(cursor, session, get_value, NULL); - WT_CURSOR_NEEDVALUE(cursor); + WT_ERR(__cursor_needvalue(cursor)); WT_ERR(cst->stats_desc(cst, WT_STAT_KEY_OFFSET(cst), &desc)); if (F_ISSET(cursor, WT_CURSTD_RAW)) { @@ -287,7 +287,7 @@ __curstat_search(WT_CURSOR *cursor) cst = (WT_CURSOR_STAT *)cursor; CURSOR_API_CALL(cursor, session, search, NULL); - WT_CURSOR_NEEDKEY(cursor); + WT_ERR(__cursor_needkey(cursor)); F_CLR(cursor, WT_CURSTD_VALUE_SET | WT_CURSTD_VALUE_SET); /* Initialize on demand. */ @@ -478,7 +478,7 @@ __curstat_join_desc(WT_CURSOR_STAT *cst, int slot, const char **resultp) strlen(static_desc) + 1; WT_RET(__wt_realloc(session, NULL, len, &cst->desc_buf)); WT_RET(__wt_snprintf( - cst->desc_buf, len, "join: %s%s", sgrp->desc_prefix, static_desc)); + cst->desc_buf, len, "join: %s%s", sgrp->desc_prefix, static_desc)); *resultp = cst->desc_buf; return (0); } @@ -576,8 +576,10 @@ __wt_curstat_open(WT_SESSION_IMPL *session, __curstat_search, /* search */ __wt_cursor_search_near_notsup, /* search-near */ __wt_cursor_notsup, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __wt_cursor_notsup, /* update */ __wt_cursor_notsup, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __curstat_close); /* close */ WT_CONFIG_ITEM cval, sval; diff --git a/src/third_party/wiredtiger/src/cursor/cur_std.c b/src/third_party/wiredtiger/src/cursor/cur_std.c index 99a9e373354..91995ab0e0a 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_std.c +++ b/src/third_party/wiredtiger/src/cursor/cur_std.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -90,6 +90,19 @@ __wt_cursor_equals_notsup(WT_CURSOR *cursor, WT_CURSOR *other, int *equalp) } /* + * __wt_cursor_modify_notsup -- + * Unsupported cursor modify. + */ +int +__wt_cursor_modify_notsup(WT_CURSOR *cursor, WT_MODIFY *entries, int nentries) +{ + WT_UNUSED(entries); + WT_UNUSED(nentries); + + return (__wt_cursor_notsup(cursor)); +} + +/* * __wt_cursor_search_near_notsup -- * Unsupported cursor search-near. */ @@ -136,6 +149,7 @@ __wt_cursor_set_notsup(WT_CURSOR *cursor) cursor->insert = __wt_cursor_notsup; cursor->update = __wt_cursor_notsup; cursor->remove = __wt_cursor_notsup; + cursor->reserve = __wt_cursor_notsup; } /* @@ -275,7 +289,7 @@ __wt_cursor_get_keyv(WT_CURSOR *cursor, uint32_t flags, va_list ap) const char *fmt; CURSOR_API_CALL(cursor, session, get_key, NULL); - if (!F_ISSET(cursor, WT_CURSTD_KEY_EXT | WT_CURSTD_KEY_INT)) + if (!F_ISSET(cursor, WT_CURSTD_KEY_SET)) WT_ERR(__wt_cursor_kv_not_set(cursor, true)); if (WT_CURSOR_RECNO(cursor)) { @@ -581,6 +595,100 @@ err: API_END(session, ret); } /* + * __cursor_modify -- + * WT_CURSOR->modify default implementation. + */ +static int +__cursor_modify(WT_CURSOR *cursor, WT_MODIFY *entries, int nentries) +{ + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_DECL_ITEM(ta); + WT_DECL_ITEM(tb); + WT_DECL_ITEM(tmp); + size_t len, size; + int i; + + CURSOR_UPDATE_API_CALL(cursor, session, modify); + WT_ERR(__cursor_checkkey(cursor)); + + /* Check for a rational modify vector count. */ + if (nentries <= 0) + WT_ERR_MSG( + session, EINVAL, "Illegal modify vector of %d", nentries); + + WT_STAT_CONN_INCR(session, cursor_modify); + WT_STAT_DATA_INCR(session, cursor_modify); + + /* Acquire position and value. */ + WT_ERR(cursor->search(cursor)); + + /* + * Process the entries to figure out how large a buffer we need. This is + * a bit pessimistic because we're ignoring replacement bytes, but it's + * a simpler calculation. + */ + for (size = cursor->value.size, i = 0; i < nentries; ++i) { + if (entries[i].offset >= size) + size = entries[i].offset; + size += entries[i].data.size; + } + + /* Allocate a pair of buffers. */ + WT_ERR(__wt_scr_alloc(session, size, &ta)); + WT_ERR(__wt_scr_alloc(session, size, &tb)); + + /* Apply the change vector to the value. */ + WT_ERR(__wt_buf_set( + session, ta, cursor->value.data, cursor->value.size)); + for (i = 0; i < nentries; ++i) { + /* Take leading bytes from the original, plus any gap bytes. */ + if (entries[i].offset >= ta->size) { + memcpy(tb->mem, ta->mem, ta->size); + if (entries[i].offset > ta->size) + memset((uint8_t *)tb->mem + ta->size, + '\0', entries[i].offset - ta->size); + } else + if (entries[i].offset > 0) + memcpy(tb->mem, ta->mem, entries[i].offset); + tb->size = entries[i].offset; + + /* Take replacement bytes. */ + if (entries[i].data.size > 0) { + memcpy((uint8_t *)tb->mem + tb->size, + entries[i].data.data, entries[i].data.size); + tb->size += entries[i].data.size; + } + + /* Take trailing bytes from the original. */ + len = entries[i].offset + entries[i].size; + if (ta->size > len) { + memcpy((uint8_t *)tb->mem + tb->size, + (uint8_t *)ta->mem + len, ta->size - len); + tb->size += ta->size - len; + } + WT_ASSERT(session, tb->size <= size); + + tmp = ta; + ta = tb; + tb = tmp; + } + + /* Set the cursor's value. */ + ta->data = ta->mem; + cursor->set_value(cursor, ta); + + /* We know both key and value are set, "overwrite" doesn't matter. */ + ret = cursor->update(cursor); + +err: __wt_scr_free(session, &ta); + __wt_scr_free(session, &tb); + + CURSOR_UPDATE_API_END(session, ret); + return (ret); +} + +/* * __wt_cursor_reconfigure -- * Set runtime-configurable settings. */ @@ -705,15 +813,17 @@ __wt_cursor_init(WT_CURSOR *cursor, WT_RET(__wt_config_gets_def(session, cfg, "checkpoint", 0, &cval)); if (cval.len != 0) { cursor->insert = __wt_cursor_notsup; - cursor->update = __wt_cursor_notsup; cursor->remove = __wt_cursor_notsup; + cursor->reserve = __wt_cursor_notsup; + cursor->update = __wt_cursor_notsup; } else { WT_RET( __wt_config_gets_def(session, cfg, "readonly", 0, &cval)); if (cval.val != 0 || F_ISSET(S2C(session), WT_CONN_READONLY)) { cursor->insert = __wt_cursor_notsup; - cursor->update = __wt_cursor_notsup; cursor->remove = __wt_cursor_notsup; + cursor->reserve = __wt_cursor_notsup; + cursor->update = __wt_cursor_notsup; } } @@ -754,6 +864,14 @@ __wt_cursor_init(WT_CURSOR *cursor, F_SET(cursor, WT_CURSTD_RAW); /* + * WT_CURSOR.modify supported on 'u' value formats, but may have been + * already initialized. + */ + if (WT_STREQ(cursor->value_format, "u") && + cursor->modify == __wt_cursor_modify_notsup) + cursor->modify = __cursor_modify; + + /* * Cursors that are internal to some other cursor (such as file cursors * inside a table cursor) should be closed after the containing cursor. * Arrange for that to happen by putting internal cursors after their diff --git a/src/third_party/wiredtiger/src/cursor/cur_table.c b/src/third_party/wiredtiger/src/cursor/cur_table.c index 3b72bb0730f..3959d58476b 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_table.c +++ b/src/third_party/wiredtiger/src/cursor/cur_table.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2014-2017 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * @@ -91,8 +91,10 @@ __wt_apply_single_idx(WT_SESSION_IMPL *session, WT_INDEX *idx, __wt_cursor_notsup, /* search */ __wt_cursor_search_near_notsup, /* search-near */ __curextract_insert, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __wt_cursor_notsup, /* update */ __wt_cursor_notsup, /* remove */ + __wt_cursor_notsup, /* reserve */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __wt_cursor_notsup); /* close */ WT_CURSOR_EXTRACTOR extract_cursor; @@ -110,8 +112,7 @@ __wt_apply_single_idx(WT_SESSION_IMPL *session, WT_INDEX *idx, WT_RET(__wt_cursor_get_raw_key(&ctable->iface, &key)); WT_RET(__wt_cursor_get_raw_value(&ctable->iface, &value)); ret = idx->extractor->extract(idx->extractor, - &session->iface, &key, &value, - &extract_cursor.iface); + &session->iface, &key, &value, &extract_cursor.iface); __wt_buf_free(session, &extract_cursor.iface.key); WT_RET(ret); @@ -190,12 +191,13 @@ __wt_curtable_get_value(WT_CURSOR *cursor, ...) WT_SESSION_IMPL *session; va_list ap; - va_start(ap, cursor); JOINABLE_CURSOR_API_CALL(cursor, session, get_value, NULL); - WT_ERR(__wt_curtable_get_valuev(cursor, ap)); -err: va_end(ap); - API_END_RET(session, ret); + va_start(ap, cursor); + ret = __wt_curtable_get_valuev(cursor, ap); + va_end(ap); + +err: API_END_RET(session, ret); } /* @@ -323,8 +325,8 @@ __curtable_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) if (strcmp(a->internal_uri, b->internal_uri) != 0) WT_ERR_MSG(session, EINVAL, "comparison method cursors must reference the same object"); - WT_CURSOR_CHECKKEY(WT_CURSOR_PRIMARY(a)); - WT_CURSOR_CHECKKEY(WT_CURSOR_PRIMARY(b)); + WT_ERR(__cursor_checkkey(WT_CURSOR_PRIMARY(a))); + WT_ERR(__cursor_checkkey(WT_CURSOR_PRIMARY(b))); ret = WT_CURSOR_PRIMARY(a)->compare( WT_CURSOR_PRIMARY(a), WT_CURSOR_PRIMARY(b), cmpp); @@ -483,7 +485,7 @@ __curtable_insert(WT_CURSOR *cursor) u_int i; ctable = (WT_CURSOR_TABLE *)cursor; - JOINABLE_CURSOR_UPDATE_API_CALL(cursor, session, insert, NULL); + JOINABLE_CURSOR_UPDATE_API_CALL(cursor, session, insert); WT_ERR(__curtable_open_indices(ctable)); /* @@ -562,7 +564,7 @@ __curtable_update(WT_CURSOR *cursor) WT_SESSION_IMPL *session; ctable = (WT_CURSOR_TABLE *)cursor; - JOINABLE_CURSOR_UPDATE_API_CALL(cursor, session, update, NULL); + JOINABLE_CURSOR_UPDATE_API_CALL(cursor, session, update); WT_ERR(__curtable_open_indices(ctable)); /* @@ -661,6 +663,47 @@ err: CURSOR_UPDATE_API_END(session, ret); } /* + * __curtable_reserve -- + * WT_CURSOR->reserve method for the table cursor type. + */ +static int +__curtable_reserve(WT_CURSOR *cursor) +{ + WT_CURSOR_TABLE *ctable; + WT_DECL_RET; + WT_SESSION_IMPL *session; + + ctable = (WT_CURSOR_TABLE *)cursor; + JOINABLE_CURSOR_UPDATE_API_CALL(cursor, session, update); + + /* + * We don't have to open the indices here, but it makes the code similar + * to other cursor functions, and it's odd for a reserve call to succeed + * but the subsequent update fail opening indices. + * + * Check for a transaction before index open, opening the indices will + * start a transaction if one isn't running. + */ + WT_ERR(__wt_txn_context_check(session, true)); + WT_ERR(__curtable_open_indices(ctable)); + + /* Reserve in column groups, ignore indices. */ + APPLY_CG(ctable, reserve); + +err: CURSOR_UPDATE_API_END(session, ret); + + /* + * The application might do a WT_CURSOR.get_value call when we return, + * so we need a value and the underlying functions didn't set one up. + * For various reasons, those functions may not have done a search and + * any previous value in the cursor might race with WT_CURSOR.reserve + * (and in cases like LSM, the reserve never encountered the original + * key). For simplicity, repeat the search here. + */ + return (ret == 0 ? cursor->search(cursor) : ret); +} + +/* * __wt_table_range_truncate -- * Truncate of a cursor range, table implementation. */ @@ -907,8 +950,10 @@ __wt_curtable_open(WT_SESSION_IMPL *session, __curtable_search, /* search */ __curtable_search_near, /* search-near */ __curtable_insert, /* insert */ + __wt_cursor_modify_notsup, /* modify */ __curtable_update, /* update */ __curtable_remove, /* remove */ + __curtable_reserve, /* reserve */ __wt_cursor_reconfigure, /* reconfigure */ __curtable_close); /* close */ WT_CONFIG_ITEM cval; |