/* * __truncate_table -- * WT_SESSION::truncate for a table. */ static int __truncate_table(WT_SESSION_IMPL *session, const char *uri, const char *cfg[]) { WT_DECL_RET; WT_TABLE *table; u_int i; WT_RET(__wt_schema_get_table( session, uri, strlen(uri), false, 0, &table)); WT_STAT_DATA_INCR(session, cursor_truncate); /* Truncate the column groups. */ for (i = 0; i < WT_COLGROUPS(table); i++) WT_ERR(__wt_schema_truncate( session, table->cgroups[i]->source, cfg)); /* Truncate the indices. */ WT_ERR(__wt_schema_open_indices(session, table)); for (i = 0; i < table->nindices; i++) WT_ERR(__wt_schema_truncate( session, table->indices[i]->source, cfg)); err: WT_TRET(__wt_schema_release_table(session, table)); return (ret); }
/* * __session_truncate -- * WT_SESSION->truncate method. */ static int __session_truncate(WT_SESSION *wt_session, const char *uri, WT_CURSOR *start, WT_CURSOR *stop, const char *config) { WT_DECL_RET; WT_SESSION_IMPL *session; WT_CURSOR *cursor; int cmp; session = (WT_SESSION_IMPL *)wt_session; SESSION_TXN_API_CALL(session, truncate, config, cfg); /* * If the URI is specified, we don't need a start/stop, if start/stop * is specified, we don't need a URI. * * If no URI is specified, and both cursors are specified, start/stop * must reference the same object. * * Any specified cursor must have been initialized. */ if ((uri == NULL && start == NULL && stop == NULL) || (uri != NULL && (start != NULL || stop != NULL))) WT_ERR_MSG(session, EINVAL, "the truncate method should be passed either a URI or " "start/stop cursors, but not both"); if (uri != NULL) { WT_WITH_SCHEMA_LOCK(session, ret = __wt_schema_truncate(session, uri, cfg)); goto done; } /* Truncate is only supported for file and table objects. */ cursor = start == NULL ? stop : start; if (!WT_PREFIX_MATCH(cursor->uri, "file:") && !WT_PREFIX_MATCH(cursor->uri, "table:")) WT_ERR(__wt_bad_object_type(session, cursor->uri)); /* * If both cursors set, check they're correctly ordered with respect to * each other. We have to test this before any search, the search can * change the initial cursor position. * * Rather happily, the compare routine will also confirm the cursors * reference the same object and the keys are set. */ if (start != NULL && stop != NULL) { WT_ERR(start->compare(start, stop, &cmp)); if (cmp > 0) WT_ERR_MSG(session, EINVAL, "the start cursor position is after the stop " "cursor position"); } /* * Truncate does not require keys actually exist so that applications * can discard parts of the object's name space without knowing exactly * what records currently appear in the object. For this reason, do a * search-near, rather than a search. Additionally, we have to correct * after calling search-near, to position the start/stop cursors on the * next record greater than/less than the original key. If the cursors * hit the beginning/end of the object, or the start/stop keys cross, * we're done, the range must be empty. */ if (start != NULL) { WT_ERR(start->search_near(start, &cmp)); if (cmp < 0 && (ret = start->next(start)) != 0) { WT_ERR_NOTFOUND_OK(ret); goto done; } } if (stop != NULL) { WT_ERR(stop->search_near(stop, &cmp)); if (cmp > 0 && (ret = stop->prev(stop)) != 0) { WT_ERR_NOTFOUND_OK(ret); goto done; } if (start != NULL) { WT_ERR(start->compare(start, stop, &cmp)); if (cmp > 0) goto done; } } if (WT_PREFIX_MATCH(cursor->uri, "file:")) WT_ERR(__wt_curfile_truncate(session, start, stop)); else WT_ERR(__wt_curtable_truncate(session, start, stop)); done: err: TXN_API_END_NOTFOUND_MAP(session, ret); }
/* * __session_truncate -- * WT_SESSION->truncate method. */ static int __session_truncate(WT_SESSION *wt_session, const char *uri, WT_CURSOR *start, WT_CURSOR *stop, const char *config) { WT_SESSION_IMPL *session; int ret; session = (WT_SESSION_IMPL *)wt_session; SESSION_API_CALL(session, truncate, config, cfg); /* * If the URI is specified, we don't need a start/stop, if start/stop * is specified, we don't need a URI. * * If no URI is specified, and both cursors are specified, start/stop * must reference the same object. * * Any specified cursor must have been initialized. */ if ((uri == NULL && start == NULL && stop == NULL) || (uri != NULL && (start != NULL || stop != NULL))) WT_ERR_MSG(session, EINVAL, "the truncate method should be passed either a URI or " "start/stop cursors, but not both"); if (start != NULL && stop != NULL && strcmp(start->uri, stop->uri) != 0) WT_ERR_MSG(session, EINVAL, "truncate method cursors must reference the same object"); if ((start != NULL && !F_ISSET(start, WT_CURSTD_KEY_SET)) || (stop != NULL && !F_ISSET(stop, WT_CURSTD_KEY_SET))) WT_ERR_MSG(session, EINVAL, "the truncate method cursors must have their keys set"); if (uri == NULL) { /* * From a starting/stopping cursor to the begin/end of the * object is easy, walk the object. */ if (start == NULL) for (;;) { WT_ERR(stop->remove(stop)); if ((ret = stop->prev(stop)) != 0) { if (ret == WT_NOTFOUND) ret = 0; break; } } else for (;;) { WT_ERR(start->remove(start)); if (stop != NULL && start->equals(start, stop)) break; if ((ret = start->next(start)) != 0) { if (ret == WT_NOTFOUND) ret = 0; break; } } } else ret = __wt_schema_truncate(session, uri, cfg); err: API_END_NOTFOUND_MAP(session, ret); }