/* * __cursor_col_modify -- * Column-store delete, insert, and update from an application cursor. */ static inline int __cursor_col_modify( WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, bool is_remove) { return (__wt_col_modify(session, cbt, cbt->iface.recno, &cbt->iface.value, NULL, is_remove)); }
/* * __col_instantiate -- * Update a column-store page entry based on a lookaside table update list. */ static int __col_instantiate(WT_SESSION_IMPL *session, uint64_t recno, WT_REF *ref, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd) { /* Search the page and add updates. */ WT_RET(__wt_col_search(session, recno, ref, cbt)); WT_RET(__wt_col_modify(session, cbt, recno, NULL, upd, 0)); return (0); }
/* * __wt_btcur_update -- * Update a record in the tree. */ int __wt_btcur_update(WT_CURSOR_BTREE *cbt) { WT_BTREE *btree; WT_CURSOR *cursor; WT_SESSION_IMPL *session; int ret; btree = cbt->btree; cursor = &cbt->iface; session = (WT_SESSION_IMPL *)cursor->session; WT_BSTAT_INCR(session, cursor_updates); if (btree->type == BTREE_ROW) WT_RET(__cursor_size_chk(session, &cursor->key)); WT_RET(__cursor_size_chk(session, &cursor->value)); retry: __cursor_func_init(cbt, 1); switch (btree->type) { case BTREE_COL_FIX: if (cursor->value.size != 1) WT_RET_MSG(session, EINVAL, "item size of %" PRIu32 " does not match " "fixed-length file requirement of 1 byte", cursor->value.size); /* FALLTHROUGH */ case BTREE_COL_VAR: WT_ERR(__wt_col_search(session, cbt, 1)); /* * Update the record if it exists. Creating a record past the * end of the tree in a fixed-length column-store implicitly * fills the gap with empty records. Update the record in that * case, the record exists. */ if ((cbt->compare != 0 || __cursor_invalid(cbt)) && !__cursor_fix_implicit(btree, cbt)) ret = WT_NOTFOUND; else if ((ret = __wt_col_modify(session, cbt, 3)) == WT_RESTART) goto retry; break; case BTREE_ROW: /* Update the record it it exists. */ WT_ERR(__wt_row_search(session, cbt, 1)); if (cbt->compare != 0 || __cursor_invalid(cbt)) ret = WT_NOTFOUND; else if ((ret = __wt_row_modify(session, cbt, 0)) == WT_RESTART) goto retry; break; WT_ILLEGAL_VALUE(session); } err: __cursor_func_resolve(cbt, ret); return (ret); }
/* * __wt_btcur_remove -- * Remove a record from the tree. */ int __wt_btcur_remove(WT_CURSOR_BTREE *cbt) { WT_BTREE *btree; WT_CURSOR *cursor; WT_SESSION_IMPL *session; int ret; btree = cbt->btree; cursor = &cbt->iface; session = (WT_SESSION_IMPL *)cursor->session; WT_BSTAT_INCR(session, cursor_removes); if (btree->type == BTREE_ROW) WT_RET(__cursor_size_chk(session, &cursor->key)); retry: __cursor_func_init(cbt, 1); switch (btree->type) { case BTREE_COL_FIX: case BTREE_COL_VAR: WT_ERR(__wt_col_search(session, cbt, 1)); /* * Remove the record if it exists. Creating a record past the * end of the tree in a fixed-length column-store implicitly * fills the gap with empty records. Return success in that * case, the record was deleted successfully. */ if (cbt->compare != 0 || __cursor_invalid(cbt)) ret = __cursor_fix_implicit(btree, cbt) ? 0 : WT_NOTFOUND; else if ((ret = __wt_col_modify(session, cbt, 2)) == WT_RESTART) goto retry; break; case BTREE_ROW: /* Remove the record if it exists. */ WT_ERR(__wt_row_search(session, cbt, 1)); if (cbt->compare != 0 || __cursor_invalid(cbt)) ret = WT_NOTFOUND; else if ((ret = __wt_row_modify(session, cbt, 1)) == WT_RESTART) goto retry; break; WT_ILLEGAL_VALUE(session); } err: __cursor_func_resolve(cbt, ret); return (ret); }
/* * __wt_btcur_insert -- * Insert a record into the tree. */ int __wt_btcur_insert(WT_CURSOR_BTREE *cbt) { WT_BTREE *btree; WT_CURSOR *cursor; WT_SESSION_IMPL *session; int ret; btree = cbt->btree; cursor = &cbt->iface; session = (WT_SESSION_IMPL *)cursor->session; WT_BSTAT_INCR(session, cursor_inserts); if (btree->type == BTREE_ROW) WT_RET(__cursor_size_chk(session, &cursor->key)); WT_RET(__cursor_size_chk(session, &cursor->value)); retry: __cursor_func_init(cbt, 1); switch (btree->type) { case BTREE_COL_FIX: case BTREE_COL_VAR: /* * If WT_CURSTD_APPEND is set, insert a new record (ignoring * the application's record number). First we search for the * maximum possible record number so the search ends on the * last page. The real record number is assigned by the * serialized append operation. * __wt_col_append_serial_func */ if (F_ISSET(cursor, WT_CURSTD_APPEND)) cbt->iface.recno = UINT64_MAX; WT_ERR(__wt_col_search(session, cbt, 1)); if (F_ISSET(cursor, WT_CURSTD_APPEND)) cbt->iface.recno = 0; /* * If WT_CURSTD_OVERWRITE set, insert/update the key/value pair. * * If WT_CURSTD_OVERWRITE not set, fail if the key exists, else * insert the key/value pair. Creating a record past the end * of the tree in a fixed-length column-store implicitly fills * the gap with empty records. Fail in that case, the record * exists. */ if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE) && ((cbt->compare == 0 && !__cursor_invalid(cbt)) || (cbt->compare != 0 && __cursor_fix_implicit(btree, cbt)))) { ret = WT_DUPLICATE_KEY; break; } if ((ret = __wt_col_modify(session, cbt, 3)) == WT_RESTART) goto retry; if (F_ISSET(cursor, WT_CURSTD_APPEND) && ret == 0) cbt->iface.recno = cbt->recno; break; case BTREE_ROW: /* * If WT_CURSTD_OVERWRITE not set, fail if the key exists, else * insert the key/value pair. * * If WT_CURSTD_OVERWRITE set, insert/update the key/value pair. */ WT_ERR(__wt_row_search(session, cbt, 1)); if (cbt->compare == 0 && !__cursor_invalid(cbt) && !F_ISSET(cursor, WT_CURSTD_OVERWRITE)) { ret = WT_DUPLICATE_KEY; break; } if ((ret = __wt_row_modify(session, cbt, 0)) == WT_RESTART) goto retry; break; WT_ILLEGAL_VALUE(session); } err: __cursor_func_resolve(cbt, ret); return (ret); }