summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/schema/schema_create.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/schema/schema_create.c')
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_create.c1242
1 files changed, 592 insertions, 650 deletions
diff --git a/src/third_party/wiredtiger/src/schema/schema_create.c b/src/third_party/wiredtiger/src/schema/schema_create.c
index 21b7e6c305c..bb4a61687eb 100644
--- a/src/third_party/wiredtiger/src/schema/schema_create.c
+++ b/src/third_party/wiredtiger/src/schema/schema_create.c
@@ -10,730 +10,672 @@
/*
* __wt_direct_io_size_check --
- * Return a size from the configuration, complaining if it's insufficient
- * for direct I/O.
+ * Return a size from the configuration, complaining if it's insufficient for direct I/O.
*/
int
-__wt_direct_io_size_check(WT_SESSION_IMPL *session,
- const char **cfg, const char *config_name, uint32_t *allocsizep)
+__wt_direct_io_size_check(
+ WT_SESSION_IMPL *session, const char **cfg, const char *config_name, uint32_t *allocsizep)
{
- WT_CONFIG_ITEM cval;
- WT_CONNECTION_IMPL *conn;
- int64_t align;
-
- *allocsizep = 0;
-
- conn = S2C(session);
-
- WT_RET(__wt_config_gets(session, cfg, config_name, &cval));
-
- /*
- * This function exists as a place to hang this comment: if direct I/O
- * is configured, page sizes must be at least as large as any buffer
- * alignment as well as a multiple of the alignment. Linux gets unhappy
- * if you configure direct I/O and then don't do I/O in alignments and
- * units of its happy place.
- */
- if (FLD_ISSET(conn->direct_io,
- WT_DIRECT_IO_CHECKPOINT | WT_DIRECT_IO_DATA)) {
- align = (int64_t)conn->buffer_alignment;
- if (align != 0 && (cval.val < align || cval.val % align != 0))
- WT_RET_MSG(session, EINVAL,
- "when direct I/O is configured, the %s size must "
- "be at least as large as the buffer alignment as "
- "well as a multiple of the buffer alignment",
- config_name);
- }
- *allocsizep = (uint32_t)cval.val;
- return (0);
+ WT_CONFIG_ITEM cval;
+ WT_CONNECTION_IMPL *conn;
+ int64_t align;
+
+ *allocsizep = 0;
+
+ conn = S2C(session);
+
+ WT_RET(__wt_config_gets(session, cfg, config_name, &cval));
+
+ /*
+ * This function exists as a place to hang this comment: if direct I/O is configured, page sizes
+ * must be at least as large as any buffer alignment as well as a multiple of the alignment.
+ * Linux gets unhappy if you configure direct I/O and then don't do I/O in alignments and units
+ * of its happy place.
+ */
+ if (FLD_ISSET(conn->direct_io, WT_DIRECT_IO_CHECKPOINT | WT_DIRECT_IO_DATA)) {
+ align = (int64_t)conn->buffer_alignment;
+ if (align != 0 && (cval.val < align || cval.val % align != 0))
+ WT_RET_MSG(session, EINVAL,
+ "when direct I/O is configured, the %s size must "
+ "be at least as large as the buffer alignment as "
+ "well as a multiple of the buffer alignment",
+ config_name);
+ }
+ *allocsizep = (uint32_t)cval.val;
+ return (0);
}
/*
* __create_file --
- * Create a new 'file:' object.
+ * Create a new 'file:' object.
*/
static int
-__create_file(WT_SESSION_IMPL *session,
- const char *uri, bool exclusive, const char *config)
+__create_file(WT_SESSION_IMPL *session, const char *uri, bool exclusive, const char *config)
{
- WT_DECL_ITEM(val);
- WT_DECL_RET;
- const char *filename, **p, *filecfg[] =
- { WT_CONFIG_BASE(session, file_meta), config, NULL, NULL };
- char *fileconf;
- uint32_t allocsize;
- bool is_metadata;
-
- fileconf = NULL;
-
- is_metadata = strcmp(uri, WT_METAFILE_URI) == 0;
-
- filename = uri;
- WT_PREFIX_SKIP_REQUIRED(session, filename, "file:");
-
- /* Check if the file already exists. */
- if (!is_metadata && (ret =
- __wt_metadata_search(session, uri, &fileconf)) != WT_NOTFOUND) {
- if (exclusive)
- WT_TRET(EEXIST);
- goto err;
- }
-
- /* Sanity check the allocation size. */
- WT_ERR(__wt_direct_io_size_check(
- session, filecfg, "allocation_size", &allocsize));
-
- /* Create the file. */
- WT_ERR(__wt_block_manager_create(session, filename, allocsize));
- if (WT_META_TRACKING(session))
- WT_ERR(__wt_meta_track_fileop(session, NULL, uri));
-
- /*
- * If creating an ordinary file, append the file ID and current version
- * numbers to the passed-in configuration and insert the resulting
- * configuration into the metadata.
- */
- if (!is_metadata) {
- WT_ERR(__wt_scr_alloc(session, 0, &val));
- WT_ERR(__wt_buf_fmt(session, val,
- "id=%" PRIu32 ",version=(major=%d,minor=%d)",
- ++S2C(session)->next_file_id,
- WT_BTREE_MAJOR_VERSION_MAX, WT_BTREE_MINOR_VERSION_MAX));
- for (p = filecfg; *p != NULL; ++p)
- ;
- *p = val->data;
- WT_ERR(__wt_config_collapse(session, filecfg, &fileconf));
- WT_ERR(__wt_metadata_insert(session, uri, fileconf));
- }
-
- /*
- * Open the file to check that it was setup correctly. We don't need to
- * pass the configuration, we just wrote the collapsed configuration
- * into the metadata file, and it's going to be read/used by underlying
- * functions.
- *
- * Keep the handle exclusive until it is released at the end of the
- * call, otherwise we could race with a drop.
- */
- WT_ERR(__wt_session_get_dhandle(
- session, uri, NULL, NULL, WT_DHANDLE_EXCLUSIVE));
- if (WT_META_TRACKING(session))
- WT_ERR(__wt_meta_track_handle_lock(session, true));
- else
- WT_ERR(__wt_session_release_dhandle(session));
-
-err: __wt_scr_free(session, &val);
- __wt_free(session, fileconf);
- return (ret);
+ WT_DECL_ITEM(val);
+ WT_DECL_RET;
+ const char *filename, **p,
+ *filecfg[] = {WT_CONFIG_BASE(session, file_meta), config, NULL, NULL};
+ char *fileconf;
+ uint32_t allocsize;
+ bool is_metadata;
+
+ fileconf = NULL;
+
+ is_metadata = strcmp(uri, WT_METAFILE_URI) == 0;
+
+ filename = uri;
+ WT_PREFIX_SKIP_REQUIRED(session, filename, "file:");
+
+ /* Check if the file already exists. */
+ if (!is_metadata && (ret = __wt_metadata_search(session, uri, &fileconf)) != WT_NOTFOUND) {
+ if (exclusive)
+ WT_TRET(EEXIST);
+ goto err;
+ }
+
+ /* Sanity check the allocation size. */
+ WT_ERR(__wt_direct_io_size_check(session, filecfg, "allocation_size", &allocsize));
+
+ /* Create the file. */
+ WT_ERR(__wt_block_manager_create(session, filename, allocsize));
+ if (WT_META_TRACKING(session))
+ WT_ERR(__wt_meta_track_fileop(session, NULL, uri));
+
+ /*
+ * If creating an ordinary file, append the file ID and current version numbers to the passed-in
+ * configuration and insert the resulting configuration into the metadata.
+ */
+ if (!is_metadata) {
+ WT_ERR(__wt_scr_alloc(session, 0, &val));
+ WT_ERR(__wt_buf_fmt(session, val, "id=%" PRIu32 ",version=(major=%d,minor=%d)",
+ ++S2C(session)->next_file_id, WT_BTREE_MAJOR_VERSION_MAX, WT_BTREE_MINOR_VERSION_MAX));
+ for (p = filecfg; *p != NULL; ++p)
+ ;
+ *p = val->data;
+ WT_ERR(__wt_config_collapse(session, filecfg, &fileconf));
+ WT_ERR(__wt_metadata_insert(session, uri, fileconf));
+ }
+
+ /*
+ * Open the file to check that it was setup correctly. We don't need to
+ * pass the configuration, we just wrote the collapsed configuration
+ * into the metadata file, and it's going to be read/used by underlying
+ * functions.
+ *
+ * Keep the handle exclusive until it is released at the end of the
+ * call, otherwise we could race with a drop.
+ */
+ WT_ERR(__wt_session_get_dhandle(session, uri, NULL, NULL, WT_DHANDLE_EXCLUSIVE));
+ if (WT_META_TRACKING(session))
+ WT_ERR(__wt_meta_track_handle_lock(session, true));
+ else
+ WT_ERR(__wt_session_release_dhandle(session));
+
+err:
+ __wt_scr_free(session, &val);
+ __wt_free(session, fileconf);
+ return (ret);
}
/*
* __wt_schema_colgroup_source --
- * Get the URI of the data source for a column group.
+ * Get the URI of the data source for a column group.
*/
int
-__wt_schema_colgroup_source(WT_SESSION_IMPL *session,
- WT_TABLE *table, const char *cgname, const char *config, WT_ITEM *buf)
+__wt_schema_colgroup_source(
+ WT_SESSION_IMPL *session, WT_TABLE *table, const char *cgname, const char *config, WT_ITEM *buf)
{
- WT_CONFIG_ITEM cval;
- WT_DECL_RET;
- size_t len;
- const char *prefix, *suffix, *tablename;
-
- tablename = table->iface.name + strlen("table:");
- if ((ret = __wt_config_getones(session, config, "type", &cval)) == 0 &&
- !WT_STRING_MATCH("file", cval.str, cval.len)) {
- prefix = cval.str;
- len = cval.len;
- suffix = "";
- } else {
- prefix = "file";
- len = strlen(prefix);
- suffix = ".wt";
- }
- WT_RET_NOTFOUND_OK(ret);
-
- if (cgname == NULL)
- WT_RET(__wt_buf_fmt(session, buf, "%.*s:%s%s",
- (int)len, prefix, tablename, suffix));
- else
- WT_RET(__wt_buf_fmt(session, buf, "%.*s:%s_%s%s",
- (int)len, prefix, tablename, cgname, suffix));
-
- return (0);
+ WT_CONFIG_ITEM cval;
+ WT_DECL_RET;
+ size_t len;
+ const char *prefix, *suffix, *tablename;
+
+ tablename = table->iface.name + strlen("table:");
+ if ((ret = __wt_config_getones(session, config, "type", &cval)) == 0 &&
+ !WT_STRING_MATCH("file", cval.str, cval.len)) {
+ prefix = cval.str;
+ len = cval.len;
+ suffix = "";
+ } else {
+ prefix = "file";
+ len = strlen(prefix);
+ suffix = ".wt";
+ }
+ WT_RET_NOTFOUND_OK(ret);
+
+ if (cgname == NULL)
+ WT_RET(__wt_buf_fmt(session, buf, "%.*s:%s%s", (int)len, prefix, tablename, suffix));
+ else
+ WT_RET(
+ __wt_buf_fmt(session, buf, "%.*s:%s_%s%s", (int)len, prefix, tablename, cgname, suffix));
+
+ return (0);
}
/*
* __create_colgroup --
- * Create a column group.
+ * Create a column group.
*/
static int
-__create_colgroup(WT_SESSION_IMPL *session,
- const char *name, bool exclusive, const char *config)
+__create_colgroup(WT_SESSION_IMPL *session, const char *name, bool exclusive, const char *config)
{
- WT_CONFIG_ITEM cval;
- WT_DECL_RET;
- WT_ITEM confbuf, fmt, namebuf;
- WT_TABLE *table;
- size_t tlen;
- const char **cfgp, *cfg[4] =
- { WT_CONFIG_BASE(session, colgroup_meta), config, NULL, NULL };
- const char *sourcecfg[] = { config, NULL, NULL };
- const char *cgname, *source, *sourceconf, *tablename;
- char *cgconf, *origconf;
- bool exists, tracked;
-
- sourceconf = NULL;
- cgconf = origconf = NULL;
- WT_CLEAR(fmt);
- WT_CLEAR(confbuf);
- WT_CLEAR(namebuf);
- exists = tracked = false;
-
- tablename = name;
- WT_PREFIX_SKIP_REQUIRED(session, tablename, "colgroup:");
- cgname = strchr(tablename, ':');
- if (cgname != NULL) {
- tlen = (size_t)(cgname - tablename);
- ++cgname;
- } else
- tlen = strlen(tablename);
-
- if ((ret = __wt_schema_get_table(
- session, tablename, tlen, true, WT_DHANDLE_EXCLUSIVE, &table)) != 0)
- WT_RET_MSG(session, (ret == WT_NOTFOUND) ? ENOENT : ret,
- "Can't create '%s' for non-existent table '%.*s'",
- name, (int)tlen, tablename);
-
- if (WT_META_TRACKING(session)) {
- WT_WITH_DHANDLE(session, &table->iface,
- ret = __wt_meta_track_handle_lock(session, false));
- WT_ERR(ret);
- tracked = true;
- }
-
- /* Make sure the column group is referenced from the table. */
- if (cgname != NULL && (ret =
- __wt_config_subgets(session, &table->cgconf, cgname, &cval)) != 0)
- WT_ERR_MSG(session, EINVAL,
- "Column group '%s' not found in table '%.*s'",
- cgname, (int)tlen, tablename);
-
- /* Check if the column group already exists. */
- if ((ret = __wt_metadata_search(session, name, &origconf)) == 0) {
- if (exclusive)
- WT_ERR(EEXIST);
- exists = true;
- }
- WT_ERR_NOTFOUND_OK(ret);
-
- /* Find the first NULL entry in the cfg stack. */
- for (cfgp = &cfg[1]; *cfgp; cfgp++)
- ;
-
- /* Add the source to the colgroup config before collapsing. */
- if (__wt_config_getones(
- session, config, "source", &cval) == 0 && cval.len != 0) {
- WT_ERR(__wt_buf_fmt(
- session, &namebuf, "%.*s", (int)cval.len, cval.str));
- source = namebuf.data;
- } else {
- WT_ERR(__wt_schema_colgroup_source(
- session, table, cgname, config, &namebuf));
- source = namebuf.data;
- WT_ERR(__wt_buf_fmt(
- session, &confbuf, "source=\"%s\"", source));
- *cfgp++ = confbuf.data;
- }
-
- /* Calculate the key/value formats: these go into the source config. */
- WT_ERR(__wt_buf_fmt(session, &fmt, "key_format=%s", table->key_format));
- if (cgname == NULL)
- WT_ERR(__wt_buf_catfmt
- (session, &fmt, ",value_format=%s", table->value_format));
- else {
- if (__wt_config_getones(session, config, "columns", &cval) != 0)
- WT_ERR_MSG(session, EINVAL,
- "No 'columns' configuration for '%s'", name);
- WT_ERR(__wt_buf_catfmt(session, &fmt, ",value_format="));
- WT_ERR(__wt_struct_reformat(session,
- table, cval.str, cval.len, NULL, true, &fmt));
- }
- sourcecfg[1] = fmt.data;
- WT_ERR(__wt_config_merge(session, sourcecfg, NULL, &sourceconf));
- WT_ERR(__wt_schema_create(session, source, sourceconf));
-
- WT_ERR(__wt_config_collapse(session, cfg, &cgconf));
-
- if (!exists) {
- WT_ERR(__wt_metadata_insert(session, name, cgconf));
- WT_ERR(__wt_schema_open_colgroups(session, table));
- }
-
-err: __wt_free(session, cgconf);
- __wt_free(session, sourceconf);
- __wt_free(session, origconf);
- __wt_buf_free(session, &confbuf);
- __wt_buf_free(session, &fmt);
- __wt_buf_free(session, &namebuf);
-
- if (!tracked)
- WT_TRET(__wt_schema_release_table(session, &table));
- return (ret);
+ WT_CONFIG_ITEM cval;
+ WT_DECL_RET;
+ WT_ITEM confbuf, fmt, namebuf;
+ WT_TABLE *table;
+ size_t tlen;
+ char *cgconf, *origconf;
+ const char **cfgp, *cfg[4] = {WT_CONFIG_BASE(session, colgroup_meta), config, NULL, NULL};
+ const char *cgname, *source, *sourceconf, *tablename;
+ const char *sourcecfg[] = {config, NULL, NULL};
+ bool exists, tracked;
+
+ sourceconf = NULL;
+ cgconf = origconf = NULL;
+ WT_CLEAR(fmt);
+ WT_CLEAR(confbuf);
+ WT_CLEAR(namebuf);
+ exists = tracked = false;
+
+ tablename = name;
+ WT_PREFIX_SKIP_REQUIRED(session, tablename, "colgroup:");
+ cgname = strchr(tablename, ':');
+ if (cgname != NULL) {
+ tlen = (size_t)(cgname - tablename);
+ ++cgname;
+ } else
+ tlen = strlen(tablename);
+
+ if ((ret = __wt_schema_get_table(
+ session, tablename, tlen, true, WT_DHANDLE_EXCLUSIVE, &table)) != 0)
+ WT_RET_MSG(session, (ret == WT_NOTFOUND) ? ENOENT : ret,
+ "Can't create '%s' for non-existent table '%.*s'", name, (int)tlen, tablename);
+
+ if (WT_META_TRACKING(session)) {
+ WT_WITH_DHANDLE(session, &table->iface, ret = __wt_meta_track_handle_lock(session, false));
+ WT_ERR(ret);
+ tracked = true;
+ }
+
+ /* Make sure the column group is referenced from the table. */
+ if (cgname != NULL && (ret = __wt_config_subgets(session, &table->cgconf, cgname, &cval)) != 0)
+ WT_ERR_MSG(session, EINVAL, "Column group '%s' not found in table '%.*s'", cgname,
+ (int)tlen, tablename);
+
+ /* Check if the column group already exists. */
+ if ((ret = __wt_metadata_search(session, name, &origconf)) == 0) {
+ if (exclusive)
+ WT_ERR(EEXIST);
+ exists = true;
+ }
+ WT_ERR_NOTFOUND_OK(ret);
+
+ /* Find the first NULL entry in the cfg stack. */
+ for (cfgp = &cfg[1]; *cfgp; cfgp++)
+ ;
+
+ /* Add the source to the colgroup config before collapsing. */
+ if (__wt_config_getones(session, config, "source", &cval) == 0 && cval.len != 0) {
+ WT_ERR(__wt_buf_fmt(session, &namebuf, "%.*s", (int)cval.len, cval.str));
+ source = namebuf.data;
+ } else {
+ WT_ERR(__wt_schema_colgroup_source(session, table, cgname, config, &namebuf));
+ source = namebuf.data;
+ WT_ERR(__wt_buf_fmt(session, &confbuf, "source=\"%s\"", source));
+ *cfgp++ = confbuf.data;
+ }
+
+ /* Calculate the key/value formats: these go into the source config. */
+ WT_ERR(__wt_buf_fmt(session, &fmt, "key_format=%s", table->key_format));
+ if (cgname == NULL)
+ WT_ERR(__wt_buf_catfmt(session, &fmt, ",value_format=%s", table->value_format));
+ else {
+ if (__wt_config_getones(session, config, "columns", &cval) != 0)
+ WT_ERR_MSG(session, EINVAL, "No 'columns' configuration for '%s'", name);
+ WT_ERR(__wt_buf_catfmt(session, &fmt, ",value_format="));
+ WT_ERR(__wt_struct_reformat(session, table, cval.str, cval.len, NULL, true, &fmt));
+ }
+ sourcecfg[1] = fmt.data;
+ WT_ERR(__wt_config_merge(session, sourcecfg, NULL, &sourceconf));
+ WT_ERR(__wt_schema_create(session, source, sourceconf));
+
+ WT_ERR(__wt_config_collapse(session, cfg, &cgconf));
+
+ if (!exists) {
+ WT_ERR(__wt_metadata_insert(session, name, cgconf));
+ WT_ERR(__wt_schema_open_colgroups(session, table));
+ }
+
+err:
+ __wt_free(session, cgconf);
+ __wt_free(session, sourceconf);
+ __wt_free(session, origconf);
+ __wt_buf_free(session, &confbuf);
+ __wt_buf_free(session, &fmt);
+ __wt_buf_free(session, &namebuf);
+
+ if (!tracked)
+ WT_TRET(__wt_schema_release_table(session, &table));
+ return (ret);
}
/*
* __wt_schema_index_source --
- * Get the URI of the data source for an index.
+ * Get the URI of the data source for an index.
*/
int
-__wt_schema_index_source(WT_SESSION_IMPL *session,
- WT_TABLE *table, const char *idxname, const char *config, WT_ITEM *buf)
+__wt_schema_index_source(
+ WT_SESSION_IMPL *session, WT_TABLE *table, const char *idxname, const char *config, WT_ITEM *buf)
{
- WT_CONFIG_ITEM cval;
- WT_DECL_RET;
- size_t len;
- const char *prefix, *suffix, *tablename;
-
- tablename = table->iface.name + strlen("table:");
- if ((ret = __wt_config_getones(session, config, "type", &cval)) == 0 &&
- !WT_STRING_MATCH("file", cval.str, cval.len)) {
- prefix = cval.str;
- len = cval.len;
- suffix = "_idx";
- } else {
- prefix = "file";
- len = strlen(prefix);
- suffix = ".wti";
- }
- WT_RET_NOTFOUND_OK(ret);
-
- WT_RET(__wt_buf_fmt(session, buf, "%.*s:%s_%s%s",
- (int)len, prefix, tablename, idxname, suffix));
-
- return (0);
+ WT_CONFIG_ITEM cval;
+ WT_DECL_RET;
+ size_t len;
+ const char *prefix, *suffix, *tablename;
+
+ tablename = table->iface.name + strlen("table:");
+ if ((ret = __wt_config_getones(session, config, "type", &cval)) == 0 &&
+ !WT_STRING_MATCH("file", cval.str, cval.len)) {
+ prefix = cval.str;
+ len = cval.len;
+ suffix = "_idx";
+ } else {
+ prefix = "file";
+ len = strlen(prefix);
+ suffix = ".wti";
+ }
+ WT_RET_NOTFOUND_OK(ret);
+
+ WT_RET(
+ __wt_buf_fmt(session, buf, "%.*s:%s_%s%s", (int)len, prefix, tablename, idxname, suffix));
+
+ return (0);
}
/*
* __fill_index --
- * Fill the index from the current contents of the table.
+ * Fill the index from the current contents of the table.
*/
static int
__fill_index(WT_SESSION_IMPL *session, WT_TABLE *table, WT_INDEX *idx)
{
- WT_CURSOR *tcur, *icur;
- WT_DECL_RET;
- WT_SESSION *wt_session;
-
- wt_session = &session->iface;
- tcur = NULL;
- icur = NULL;
- WT_RET(__wt_schema_open_colgroups(session, table));
-
- /*
- * If the column groups have not been completely created,
- * there cannot be data inserted yet, and we're done.
- */
- if (!table->cg_complete)
- return (0);
-
- WT_ERR(wt_session->open_cursor(wt_session,
- idx->source, NULL, "bulk=unordered", &icur));
- WT_ERR(wt_session->open_cursor(wt_session,
- table->iface.name, NULL, "readonly", &tcur));
-
- while ((ret = tcur->next(tcur)) == 0)
- WT_ERR(__wt_apply_single_idx(session, idx,
- icur, (WT_CURSOR_TABLE *)tcur, icur->insert));
-
- WT_ERR_NOTFOUND_OK(ret);
+ WT_CURSOR *tcur, *icur;
+ WT_DECL_RET;
+ WT_SESSION *wt_session;
+
+ wt_session = &session->iface;
+ tcur = NULL;
+ icur = NULL;
+ WT_RET(__wt_schema_open_colgroups(session, table));
+
+ /*
+ * If the column groups have not been completely created, there cannot be data inserted yet, and
+ * we're done.
+ */
+ if (!table->cg_complete)
+ return (0);
+
+ WT_ERR(wt_session->open_cursor(wt_session, idx->source, NULL, "bulk=unordered", &icur));
+ WT_ERR(wt_session->open_cursor(wt_session, table->iface.name, NULL, "readonly", &tcur));
+
+ while ((ret = tcur->next(tcur)) == 0)
+ WT_ERR(__wt_apply_single_idx(session, idx, icur, (WT_CURSOR_TABLE *)tcur, icur->insert));
+
+ WT_ERR_NOTFOUND_OK(ret);
err:
- if (icur)
- WT_TRET(icur->close(icur));
- if (tcur)
- WT_TRET(tcur->close(tcur));
- return (ret);
+ if (icur)
+ WT_TRET(icur->close(icur));
+ if (tcur)
+ WT_TRET(tcur->close(tcur));
+ return (ret);
}
/*
* __create_index --
- * Create an index.
+ * Create an index.
*/
static int
-__create_index(WT_SESSION_IMPL *session,
- const char *name, bool exclusive, const char *config)
+__create_index(WT_SESSION_IMPL *session, const char *name, bool exclusive, const char *config)
{
- WT_CONFIG kcols, pkcols;
- WT_CONFIG_ITEM ckey, cval, icols, kval;
- WT_DECL_PACK_VALUE(pv);
- WT_DECL_RET;
- WT_INDEX *idx;
- WT_ITEM confbuf, extra_cols, fmt, namebuf;
- WT_PACK pack;
- WT_TABLE *table;
- const char *cfg[4] =
- { WT_CONFIG_BASE(session, index_meta), NULL, NULL, NULL };
- const char *sourcecfg[] = { config, NULL, NULL };
- const char *source, *sourceconf, *idxname, *tablename;
- char *idxconf, *origconf;
- size_t tlen;
- bool exists, have_extractor;
- u_int i, npublic_cols;
-
- sourceconf = NULL;
- idxconf = origconf = NULL;
- WT_CLEAR(confbuf);
- WT_CLEAR(fmt);
- WT_CLEAR(extra_cols);
- WT_CLEAR(namebuf);
- exists = have_extractor = false;
-
- tablename = name;
- WT_PREFIX_SKIP_REQUIRED(session, tablename, "index:");
- idxname = strchr(tablename, ':');
- if (idxname == NULL)
- WT_RET_MSG(session, EINVAL, "Invalid index name, "
- "should be <table name>:<index name>: %s", name);
-
- /*
- * Note: it would be better to keep the table exclusive here, while
- * changing its indexes. We don't because some operation we perform
- * below reacquire the table handle (such as opening a cursor on the
- * table in order to fill the index). If we keep the handle exclusive
- * here, those operations wanting ordinary access will conflict,
- * leading to errors. At the same time, we don't want to allow
- * table cursors that have already been fully opened to remain open
- * across this call.
- *
- * Temporarily getting the table exclusively serves the purpose
- * of ensuring that cursors on the table that are already open
- * must at least be closed before this call proceeds.
- */
- tlen = (size_t)(idxname++ - tablename);
- if ((ret = __wt_schema_get_table(
- session, tablename, tlen, true, WT_DHANDLE_EXCLUSIVE, &table)) != 0)
- WT_RET_MSG(session, ret,
- "Can't create an index for table: %.*s",
- (int)tlen, tablename);
- WT_RET(__wt_schema_release_table(session, &table));
-
- if ((ret = __wt_schema_get_table(
- session, tablename, tlen, true, 0, &table)) != 0)
- WT_RET_MSG(session, ret,
- "Can't create an index for a non-existent table: %.*s",
- (int)tlen, tablename);
-
- if (table->is_simple)
- WT_ERR_MSG(session, EINVAL,
- "%s requires a table with named columns", name);
-
- /* Check if the index already exists. */
- if ((ret = __wt_metadata_search(session, name, &origconf)) == 0) {
- if (exclusive)
- WT_ERR(EEXIST);
- exists = true;
- }
- WT_ERR_NOTFOUND_OK(ret);
-
- if (__wt_config_getones(session, config, "source", &cval) == 0) {
- WT_ERR(__wt_buf_fmt(session, &namebuf,
- "%.*s", (int)cval.len, cval.str));
- source = namebuf.data;
- } else {
- WT_ERR(__wt_schema_index_source(
- session, table, idxname, config, &namebuf));
- source = namebuf.data;
-
- /* Add the source name to the index config before collapsing. */
- WT_ERR(__wt_buf_catfmt(session, &confbuf,
- ",source=\"%s\"", source));
- }
-
- if (__wt_config_getones_none(
- session, config, "extractor", &cval) == 0 && cval.len != 0) {
- have_extractor = true;
- /* Custom extractors must supply a key format. */
- if ((ret = __wt_config_getones(
- session, config, "key_format", &kval)) != 0)
- WT_ERR_MSG(session, EINVAL,
- "%s: custom extractors require a key_format", name);
- }
-
- /* Calculate the key/value formats. */
- WT_CLEAR(icols);
- if (__wt_config_getones(session, config, "columns", &icols) != 0 &&
- !have_extractor)
- WT_ERR_MSG(session, EINVAL,
- "%s: requires 'columns' configuration", name);
-
- /*
- * Count the public columns using the declared columns for normal
- * indices or the key format for custom extractors.
- */
- npublic_cols = 0;
- if (!have_extractor) {
- __wt_config_subinit(session, &kcols, &icols);
- while ((ret = __wt_config_next(&kcols, &ckey, &cval)) == 0)
- ++npublic_cols;
- WT_ERR_NOTFOUND_OK(ret);
- } else {
- WT_ERR(__pack_initn(session, &pack, kval.str, kval.len));
- while ((ret = __pack_next(&pack, &pv)) == 0)
- ++npublic_cols;
- WT_ERR_NOTFOUND_OK(ret);
- }
-
- /*
- * The key format for an index is somewhat subtle: the application
- * specifies a set of columns that it will use for the key, but the
- * engine usually adds some hidden columns in order to derive the
- * primary key. These hidden columns are part of the source's
- * key_format, which we are calculating now, but not part of an index
- * cursor's key_format.
- */
- __wt_config_subinit(session, &pkcols, &table->colconf);
- for (i = 0; i < table->nkey_columns &&
- (ret = __wt_config_next(&pkcols, &ckey, &cval)) == 0;
- i++) {
- /*
- * If the primary key column is already in the secondary key,
- * don't add it again.
- */
- if (__wt_config_subgetraw(session, &icols, &ckey, &cval) == 0) {
- if (have_extractor)
- WT_ERR_MSG(session, EINVAL,
- "an index with a custom extractor may not "
- "include primary key columns");
- continue;
- }
- WT_ERR(__wt_buf_catfmt(
- session, &extra_cols, "%.*s,", (int)ckey.len, ckey.str));
- }
- WT_ERR_NOTFOUND_OK(ret);
-
- /* Index values are empty: all columns are packed into the index key. */
- WT_ERR(__wt_buf_fmt(session, &fmt, "value_format=,key_format="));
-
- if (have_extractor) {
- WT_ERR(__wt_buf_catfmt(session, &fmt, "%.*s",
- (int)kval.len, kval.str));
- WT_CLEAR(icols);
- }
-
- /*
- * Construct the index key format, or append the primary key columns
- * for custom extractors.
- */
- WT_ERR(__wt_struct_reformat(session, table,
- icols.str, icols.len, (const char *)extra_cols.data, false, &fmt));
-
- /* Check for a record number index key, which makes no sense. */
- WT_ERR(__wt_config_getones(session, fmt.data, "key_format", &cval));
- if (cval.len == 1 && cval.str[0] == 'r')
- WT_ERR_MSG(session, EINVAL,
- "column-store index may not use the record number as its "
- "index key");
-
- WT_ERR(__wt_buf_catfmt(
- session, &fmt, ",index_key_columns=%u", npublic_cols));
-
- sourcecfg[1] = fmt.data;
- WT_ERR(__wt_config_merge(session, sourcecfg, NULL, &sourceconf));
-
- WT_ERR(__wt_schema_create(session, source, sourceconf));
-
- cfg[1] = sourceconf;
- cfg[2] = confbuf.data;
- WT_ERR(__wt_config_collapse(session, cfg, &idxconf));
-
- if (!exists) {
- WT_ERR(__wt_metadata_insert(session, name, idxconf));
-
- /* Make sure that the configuration is valid. */
- WT_ERR(__wt_schema_open_index(
- session, table, idxname, strlen(idxname), &idx));
-
- /* If there is data in the table, fill the index. */
- WT_ERR(__fill_index(session, table, idx));
- }
-
-err: __wt_free(session, idxconf);
- __wt_free(session, origconf);
- __wt_free(session, sourceconf);
- __wt_buf_free(session, &confbuf);
- __wt_buf_free(session, &extra_cols);
- __wt_buf_free(session, &fmt);
- __wt_buf_free(session, &namebuf);
-
- WT_TRET(__wt_schema_release_table(session, &table));
- return (ret);
+ WT_CONFIG kcols, pkcols;
+ WT_CONFIG_ITEM ckey, cval, icols, kval;
+ WT_DECL_PACK_VALUE(pv);
+ WT_DECL_RET;
+ WT_INDEX *idx;
+ WT_ITEM confbuf, extra_cols, fmt, namebuf;
+ WT_PACK pack;
+ WT_TABLE *table;
+ size_t tlen;
+ u_int i, npublic_cols;
+ char *idxconf, *origconf;
+ const char *cfg[4] = {WT_CONFIG_BASE(session, index_meta), NULL, NULL, NULL};
+ const char *source, *sourceconf, *idxname, *tablename;
+ const char *sourcecfg[] = {config, NULL, NULL};
+ bool exists, have_extractor;
+
+ sourceconf = NULL;
+ idxconf = origconf = NULL;
+ WT_CLEAR(confbuf);
+ WT_CLEAR(fmt);
+ WT_CLEAR(extra_cols);
+ WT_CLEAR(namebuf);
+ exists = have_extractor = false;
+
+ tablename = name;
+ WT_PREFIX_SKIP_REQUIRED(session, tablename, "index:");
+ idxname = strchr(tablename, ':');
+ if (idxname == NULL)
+ WT_RET_MSG(session, EINVAL,
+ "Invalid index name, "
+ "should be <table name>:<index name>: %s",
+ name);
+
+ /*
+ * Note: it would be better to keep the table exclusive here, while
+ * changing its indexes. We don't because some operation we perform
+ * below reacquire the table handle (such as opening a cursor on the
+ * table in order to fill the index). If we keep the handle exclusive
+ * here, those operations wanting ordinary access will conflict,
+ * leading to errors. At the same time, we don't want to allow
+ * table cursors that have already been fully opened to remain open
+ * across this call.
+ *
+ * Temporarily getting the table exclusively serves the purpose
+ * of ensuring that cursors on the table that are already open
+ * must at least be closed before this call proceeds.
+ */
+ tlen = (size_t)(idxname++ - tablename);
+ if ((ret = __wt_schema_get_table(
+ session, tablename, tlen, true, WT_DHANDLE_EXCLUSIVE, &table)) != 0)
+ WT_RET_MSG(session, ret, "Can't create an index for table: %.*s", (int)tlen, tablename);
+ WT_RET(__wt_schema_release_table(session, &table));
+
+ if ((ret = __wt_schema_get_table(session, tablename, tlen, true, 0, &table)) != 0)
+ WT_RET_MSG(session, ret, "Can't create an index for a non-existent table: %.*s", (int)tlen,
+ tablename);
+
+ if (table->is_simple)
+ WT_ERR_MSG(session, EINVAL, "%s requires a table with named columns", name);
+
+ /* Check if the index already exists. */
+ if ((ret = __wt_metadata_search(session, name, &origconf)) == 0) {
+ if (exclusive)
+ WT_ERR(EEXIST);
+ exists = true;
+ }
+ WT_ERR_NOTFOUND_OK(ret);
+
+ if (__wt_config_getones(session, config, "source", &cval) == 0) {
+ WT_ERR(__wt_buf_fmt(session, &namebuf, "%.*s", (int)cval.len, cval.str));
+ source = namebuf.data;
+ } else {
+ WT_ERR(__wt_schema_index_source(session, table, idxname, config, &namebuf));
+ source = namebuf.data;
+
+ /* Add the source name to the index config before collapsing. */
+ WT_ERR(__wt_buf_catfmt(session, &confbuf, ",source=\"%s\"", source));
+ }
+
+ if (__wt_config_getones_none(session, config, "extractor", &cval) == 0 && cval.len != 0) {
+ have_extractor = true;
+ /* Custom extractors must supply a key format. */
+ if ((ret = __wt_config_getones(session, config, "key_format", &kval)) != 0)
+ WT_ERR_MSG(session, EINVAL, "%s: custom extractors require a key_format", name);
+ }
+
+ /* Calculate the key/value formats. */
+ WT_CLEAR(icols);
+ if (__wt_config_getones(session, config, "columns", &icols) != 0 && !have_extractor)
+ WT_ERR_MSG(session, EINVAL, "%s: requires 'columns' configuration", name);
+
+ /*
+ * Count the public columns using the declared columns for normal indices or the key format for
+ * custom extractors.
+ */
+ npublic_cols = 0;
+ if (!have_extractor) {
+ __wt_config_subinit(session, &kcols, &icols);
+ while ((ret = __wt_config_next(&kcols, &ckey, &cval)) == 0)
+ ++npublic_cols;
+ WT_ERR_NOTFOUND_OK(ret);
+ } else {
+ WT_ERR(__pack_initn(session, &pack, kval.str, kval.len));
+ while ((ret = __pack_next(&pack, &pv)) == 0)
+ ++npublic_cols;
+ WT_ERR_NOTFOUND_OK(ret);
+ }
+
+ /*
+ * The key format for an index is somewhat subtle: the application specifies a set of columns
+ * that it will use for the key, but the engine usually adds some hidden columns in order to
+ * derive the primary key. These hidden columns are part of the source's key_format, which we
+ * are calculating now, but not part of an index cursor's key_format.
+ */
+ __wt_config_subinit(session, &pkcols, &table->colconf);
+ for (i = 0; i < table->nkey_columns && (ret = __wt_config_next(&pkcols, &ckey, &cval)) == 0;
+ i++) {
+ /*
+ * If the primary key column is already in the secondary key, don't add it again.
+ */
+ if (__wt_config_subgetraw(session, &icols, &ckey, &cval) == 0) {
+ if (have_extractor)
+ WT_ERR_MSG(session, EINVAL,
+ "an index with a custom extractor may not "
+ "include primary key columns");
+ continue;
+ }
+ WT_ERR(__wt_buf_catfmt(session, &extra_cols, "%.*s,", (int)ckey.len, ckey.str));
+ }
+ WT_ERR_NOTFOUND_OK(ret);
+
+ /* Index values are empty: all columns are packed into the index key. */
+ WT_ERR(__wt_buf_fmt(session, &fmt, "value_format=,key_format="));
+
+ if (have_extractor) {
+ WT_ERR(__wt_buf_catfmt(session, &fmt, "%.*s", (int)kval.len, kval.str));
+ WT_CLEAR(icols);
+ }
+
+ /*
+ * Construct the index key format, or append the primary key columns for custom extractors.
+ */
+ WT_ERR(__wt_struct_reformat(
+ session, table, icols.str, icols.len, (const char *)extra_cols.data, false, &fmt));
+
+ /* Check for a record number index key, which makes no sense. */
+ WT_ERR(__wt_config_getones(session, fmt.data, "key_format", &cval));
+ if (cval.len == 1 && cval.str[0] == 'r')
+ WT_ERR_MSG(session, EINVAL,
+ "column-store index may not use the record number as its "
+ "index key");
+
+ WT_ERR(__wt_buf_catfmt(session, &fmt, ",index_key_columns=%u", npublic_cols));
+
+ sourcecfg[1] = fmt.data;
+ WT_ERR(__wt_config_merge(session, sourcecfg, NULL, &sourceconf));
+
+ WT_ERR(__wt_schema_create(session, source, sourceconf));
+
+ cfg[1] = sourceconf;
+ cfg[2] = confbuf.data;
+ WT_ERR(__wt_config_collapse(session, cfg, &idxconf));
+
+ if (!exists) {
+ WT_ERR(__wt_metadata_insert(session, name, idxconf));
+
+ /* Make sure that the configuration is valid. */
+ WT_ERR(__wt_schema_open_index(session, table, idxname, strlen(idxname), &idx));
+
+ /* If there is data in the table, fill the index. */
+ WT_ERR(__fill_index(session, table, idx));
+ }
+
+err:
+ __wt_free(session, idxconf);
+ __wt_free(session, origconf);
+ __wt_free(session, sourceconf);
+ __wt_buf_free(session, &confbuf);
+ __wt_buf_free(session, &extra_cols);
+ __wt_buf_free(session, &fmt);
+ __wt_buf_free(session, &namebuf);
+
+ WT_TRET(__wt_schema_release_table(session, &table));
+ return (ret);
}
/*
* __create_table --
- * Create a table.
+ * Create a table.
*/
static int
-__create_table(WT_SESSION_IMPL *session,
- const char *uri, bool exclusive, const char *config)
+__create_table(WT_SESSION_IMPL *session, const char *uri, bool exclusive, const char *config)
{
- WT_CONFIG conf;
- WT_CONFIG_ITEM cgkey, cgval, cval;
- WT_DECL_RET;
- WT_TABLE *table;
- const char *cfg[4] =
- { WT_CONFIG_BASE(session, table_meta), config, NULL, NULL };
- const char *tablename;
- char *tableconf, *cgname;
- size_t cgsize;
- int ncolgroups;
-
- cgname = NULL;
- table = NULL;
- tableconf = NULL;
-
- WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_TABLE_WRITE));
-
- tablename = uri;
- WT_PREFIX_SKIP_REQUIRED(session, tablename, "table:");
-
- /* Check if the table already exists. */
- if ((ret = __wt_metadata_search(
- session, uri, &tableconf)) != WT_NOTFOUND) {
- if (exclusive)
- WT_TRET(EEXIST);
- goto err;
- }
-
- WT_ERR(__wt_config_gets(session, cfg, "colgroups", &cval));
- __wt_config_subinit(session, &conf, &cval);
- for (ncolgroups = 0;
- (ret = __wt_config_next(&conf, &cgkey, &cgval)) == 0;
- ncolgroups++)
- ;
- WT_ERR_NOTFOUND_OK(ret);
-
- WT_ERR(__wt_config_collapse(session, cfg, &tableconf));
- WT_ERR(__wt_metadata_insert(session, uri, tableconf));
-
- if (ncolgroups == 0) {
- cgsize = strlen("colgroup:") + strlen(tablename) + 1;
- WT_ERR(__wt_calloc_def(session, cgsize, &cgname));
- WT_ERR(__wt_snprintf(cgname, cgsize, "colgroup:%s", tablename));
- WT_ERR(__create_colgroup(session, cgname, exclusive, config));
- }
-
- /*
- * Open the table to check that it was setup correctly. Keep the
- * handle exclusive until it is released at the end of the call.
- */
- WT_ERR(__wt_schema_get_table_uri(
- session, uri, true, WT_DHANDLE_EXCLUSIVE, &table));
- if (WT_META_TRACKING(session)) {
- WT_WITH_DHANDLE(session, &table->iface,
- ret = __wt_meta_track_handle_lock(session, true));
- WT_ERR(ret);
- table = NULL;
- }
-
-err: WT_TRET(__wt_schema_release_table(session, &table));
- __wt_free(session, cgname);
- __wt_free(session, tableconf);
- return (ret);
+ WT_CONFIG conf;
+ WT_CONFIG_ITEM cgkey, cgval, cval;
+ WT_DECL_RET;
+ WT_TABLE *table;
+ size_t cgsize;
+ int ncolgroups;
+ char *tableconf, *cgname;
+ const char *cfg[4] = {WT_CONFIG_BASE(session, table_meta), config, NULL, NULL};
+ const char *tablename;
+
+ cgname = NULL;
+ table = NULL;
+ tableconf = NULL;
+
+ WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_TABLE_WRITE));
+
+ tablename = uri;
+ WT_PREFIX_SKIP_REQUIRED(session, tablename, "table:");
+
+ /* Check if the table already exists. */
+ if ((ret = __wt_metadata_search(session, uri, &tableconf)) != WT_NOTFOUND) {
+ if (exclusive)
+ WT_TRET(EEXIST);
+ goto err;
+ }
+
+ WT_ERR(__wt_config_gets(session, cfg, "colgroups", &cval));
+ __wt_config_subinit(session, &conf, &cval);
+ for (ncolgroups = 0; (ret = __wt_config_next(&conf, &cgkey, &cgval)) == 0; ncolgroups++)
+ ;
+ WT_ERR_NOTFOUND_OK(ret);
+
+ WT_ERR(__wt_config_collapse(session, cfg, &tableconf));
+ WT_ERR(__wt_metadata_insert(session, uri, tableconf));
+
+ if (ncolgroups == 0) {
+ cgsize = strlen("colgroup:") + strlen(tablename) + 1;
+ WT_ERR(__wt_calloc_def(session, cgsize, &cgname));
+ WT_ERR(__wt_snprintf(cgname, cgsize, "colgroup:%s", tablename));
+ WT_ERR(__create_colgroup(session, cgname, exclusive, config));
+ }
+
+ /*
+ * Open the table to check that it was setup correctly. Keep the handle exclusive until it is
+ * released at the end of the call.
+ */
+ WT_ERR(__wt_schema_get_table_uri(session, uri, true, WT_DHANDLE_EXCLUSIVE, &table));
+ if (WT_META_TRACKING(session)) {
+ WT_WITH_DHANDLE(session, &table->iface, ret = __wt_meta_track_handle_lock(session, true));
+ WT_ERR(ret);
+ table = NULL;
+ }
+
+err:
+ WT_TRET(__wt_schema_release_table(session, &table));
+ __wt_free(session, cgname);
+ __wt_free(session, tableconf);
+ return (ret);
}
/*
* __create_data_source --
- * Create a custom data source.
+ * Create a custom data source.
*/
static int
-__create_data_source(WT_SESSION_IMPL *session,
- const char *uri, const char *config, WT_DATA_SOURCE *dsrc)
+__create_data_source(
+ WT_SESSION_IMPL *session, const char *uri, const char *config, WT_DATA_SOURCE *dsrc)
{
- WT_CONFIG_ITEM cval;
- const char *cfg[] = {
- WT_CONFIG_BASE(session, WT_SESSION_create), config, NULL };
-
- /*
- * Check to be sure the key/value formats are legal: the underlying
- * data source doesn't have access to the functions that check.
- */
- WT_RET(__wt_config_gets(session, cfg, "key_format", &cval));
- WT_RET(__wt_struct_confchk(session, &cval));
- WT_RET(__wt_config_gets(session, cfg, "value_format", &cval));
- WT_RET(__wt_struct_confchk(session, &cval));
-
- /*
- * User-specified collators aren't supported for data-source objects.
- */
- if (__wt_config_getones_none(
- session, config, "collator", &cval) != WT_NOTFOUND && cval.len != 0)
- WT_RET_MSG(session, EINVAL,
- "WT_DATA_SOURCE objects do not support WT_COLLATOR "
- "ordering");
-
- return (dsrc->create(dsrc, &session->iface, uri, (WT_CONFIG_ARG *)cfg));
+ WT_CONFIG_ITEM cval;
+ const char *cfg[] = {WT_CONFIG_BASE(session, WT_SESSION_create), config, NULL};
+
+ /*
+ * Check to be sure the key/value formats are legal: the underlying data source doesn't have
+ * access to the functions that check.
+ */
+ WT_RET(__wt_config_gets(session, cfg, "key_format", &cval));
+ WT_RET(__wt_struct_confchk(session, &cval));
+ WT_RET(__wt_config_gets(session, cfg, "value_format", &cval));
+ WT_RET(__wt_struct_confchk(session, &cval));
+
+ /*
+ * User-specified collators aren't supported for data-source objects.
+ */
+ if (__wt_config_getones_none(session, config, "collator", &cval) != WT_NOTFOUND &&
+ cval.len != 0)
+ WT_RET_MSG(session, EINVAL,
+ "WT_DATA_SOURCE objects do not support WT_COLLATOR "
+ "ordering");
+
+ return (dsrc->create(dsrc, &session->iface, uri, (WT_CONFIG_ARG *)cfg));
}
/*
* __schema_create --
- * Process a WT_SESSION::create operation for all supported types.
+ * Process a WT_SESSION::create operation for all supported types.
*/
static int
-__schema_create(
- WT_SESSION_IMPL *session, const char *uri, const char *config)
+__schema_create(WT_SESSION_IMPL *session, const char *uri, const char *config)
{
- WT_CONFIG_ITEM cval;
- WT_DATA_SOURCE *dsrc;
- WT_DECL_RET;
- bool exclusive;
-
- exclusive =
- __wt_config_getones(session, config, "exclusive", &cval) == 0 &&
- cval.val != 0;
-
- /*
- * We track create operations: if we fail in the middle of creating a
- * complex object, we want to back it all out.
- */
- WT_RET(__wt_meta_track_on(session));
-
- if (WT_PREFIX_MATCH(uri, "colgroup:"))
- ret = __create_colgroup(session, uri, exclusive, config);
- else if (WT_PREFIX_MATCH(uri, "file:"))
- ret = __create_file(session, uri, exclusive, config);
- else if (WT_PREFIX_MATCH(uri, "lsm:"))
- ret = __wt_lsm_tree_create(session, uri, exclusive, config);
- else if (WT_PREFIX_MATCH(uri, "index:"))
- ret = __create_index(session, uri, exclusive, config);
- else if (WT_PREFIX_MATCH(uri, "table:"))
- ret = __create_table(session, uri, exclusive, config);
- else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL)
- ret = dsrc->create == NULL ?
- __wt_object_unsupported(session, uri) :
- __create_data_source(session, uri, config, dsrc);
- else
- ret = __wt_bad_object_type(session, uri);
-
- session->dhandle = NULL;
- WT_TRET(__wt_meta_track_off(session, true, ret != 0));
-
- return (ret);
+ WT_CONFIG_ITEM cval;
+ WT_DATA_SOURCE *dsrc;
+ WT_DECL_RET;
+ bool exclusive;
+
+ exclusive = __wt_config_getones(session, config, "exclusive", &cval) == 0 && cval.val != 0;
+
+ /*
+ * We track create operations: if we fail in the middle of creating a complex object, we want to
+ * back it all out.
+ */
+ WT_RET(__wt_meta_track_on(session));
+
+ if (WT_PREFIX_MATCH(uri, "colgroup:"))
+ ret = __create_colgroup(session, uri, exclusive, config);
+ else if (WT_PREFIX_MATCH(uri, "file:"))
+ ret = __create_file(session, uri, exclusive, config);
+ else if (WT_PREFIX_MATCH(uri, "lsm:"))
+ ret = __wt_lsm_tree_create(session, uri, exclusive, config);
+ else if (WT_PREFIX_MATCH(uri, "index:"))
+ ret = __create_index(session, uri, exclusive, config);
+ else if (WT_PREFIX_MATCH(uri, "table:"))
+ ret = __create_table(session, uri, exclusive, config);
+ else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL)
+ ret = dsrc->create == NULL ? __wt_object_unsupported(session, uri) :
+ __create_data_source(session, uri, config, dsrc);
+ else
+ ret = __wt_bad_object_type(session, uri);
+
+ session->dhandle = NULL;
+ WT_TRET(__wt_meta_track_off(session, true, ret != 0));
+
+ return (ret);
}
/*
* __wt_schema_create --
- * Process a WT_SESSION::create operation for all supported types.
+ * Process a WT_SESSION::create operation for all supported types.
*/
int
-__wt_schema_create(
- WT_SESSION_IMPL *session, const char *uri, const char *config)
+__wt_schema_create(WT_SESSION_IMPL *session, const char *uri, const char *config)
{
- WT_DECL_RET;
- WT_SESSION_IMPL *int_session;
+ WT_DECL_RET;
+ WT_SESSION_IMPL *int_session;
- WT_RET(__wt_schema_internal_session(session, &int_session));
- ret = __schema_create(int_session, uri, config);
- WT_TRET(__wt_schema_session_release(session, int_session));
- return (ret);
+ WT_RET(__wt_schema_internal_session(session, &int_session));
+ ret = __schema_create(int_session, uri, config);
+ WT_TRET(__wt_schema_session_release(session, int_session));
+ return (ret);
}