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.c118
1 files changed, 65 insertions, 53 deletions
diff --git a/src/third_party/wiredtiger/src/schema/schema_create.c b/src/third_party/wiredtiger/src/schema/schema_create.c
index 1ba0961cced..641c99793c3 100644
--- a/src/third_party/wiredtiger/src/schema/schema_create.c
+++ b/src/third_party/wiredtiger/src/schema/schema_create.c
@@ -69,8 +69,7 @@ __create_file(WT_SESSION_IMPL *session,
is_metadata = strcmp(uri, WT_METAFILE_URI) == 0;
filename = uri;
- if (!WT_PREFIX_SKIP(filename, "file:"))
- return (__wt_unexpected_object_type(session, uri, "file:"));
+ WT_PREFIX_SKIP_REQUIRED(session, filename, "file:");
/* Check if the file already exists. */
if (!is_metadata && (ret =
@@ -116,12 +115,12 @@ __create_file(WT_SESSION_IMPL *session,
* 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_btree(
+ 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_btree(session));
+ WT_ERR(__wt_session_release_dhandle(session));
err: __wt_scr_free(session, &val);
__wt_free(session, fileconf);
@@ -141,7 +140,7 @@ __wt_schema_colgroup_source(WT_SESSION_IMPL *session,
size_t len;
const char *prefix, *suffix, *tablename;
- tablename = table->name + strlen("table:");
+ 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;
@@ -182,19 +181,17 @@ __create_colgroup(WT_SESSION_IMPL *session,
const char *sourcecfg[] = { config, NULL, NULL };
const char *cgname, *source, *sourceconf, *tablename;
char *cgconf, *origconf;
- bool exists;
+ bool exists, tracked;
sourceconf = NULL;
cgconf = origconf = NULL;
WT_CLEAR(fmt);
WT_CLEAR(confbuf);
WT_CLEAR(namebuf);
- exists = false;
+ exists = tracked = false;
tablename = name;
- if (!WT_PREFIX_SKIP(tablename, "colgroup:"))
- return (
- __wt_unexpected_object_type(session, name, "colgroup:"));
+ WT_PREFIX_SKIP_REQUIRED(session, tablename, "colgroup:");
cgname = strchr(tablename, ':');
if (cgname != NULL) {
tlen = (size_t)(cgname - tablename);
@@ -202,12 +199,19 @@ __create_colgroup(WT_SESSION_IMPL *session,
} else
tlen = strlen(tablename);
- if ((ret =
- __wt_schema_get_table(session, tablename, tlen, true, &table)) != 0)
+ 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)
@@ -273,7 +277,8 @@ err: __wt_free(session, cgconf);
__wt_buf_free(session, &fmt);
__wt_buf_free(session, &namebuf);
- __wt_schema_release_table(session, table);
+ if (!tracked)
+ WT_TRET(__wt_schema_release_table(session, table));
return (ret);
}
@@ -290,7 +295,7 @@ __wt_schema_index_source(WT_SESSION_IMPL *session,
size_t len;
const char *prefix, *suffix, *tablename;
- tablename = table->name + strlen("table:");
+ 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;
@@ -335,7 +340,7 @@ __fill_index(WT_SESSION_IMPL *session, WT_TABLE *table, WT_INDEX *idx)
WT_ERR(wt_session->open_cursor(wt_session,
idx->source, NULL, "bulk=unordered", &icur));
WT_ERR(wt_session->open_cursor(wt_session,
- table->name, NULL, "readonly", &tcur));
+ table->iface.name, NULL, "readonly", &tcur));
while ((ret = tcur->next(tcur)) == 0)
WT_ERR(__wt_apply_single_idx(session, idx,
@@ -384,16 +389,26 @@ __create_index(WT_SESSION_IMPL *session,
exists = have_extractor = false;
tablename = name;
- if (!WT_PREFIX_SKIP(tablename, "index:"))
- return (__wt_unexpected_object_type(session, name, "index:"));
+ 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 get 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 get the handle exclusive
+ * here, those operations wanting ordinary access will conflict,
+ * leading to errors.
+ *
+ * Instead, we rely on the global table lock to protect the set of
+ * available indexes.
+ */
tlen = (size_t)(idxname++ - tablename);
- if ((ret =
- __wt_schema_get_table(session, tablename, tlen, true, &table)) != 0)
+ 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);
@@ -540,7 +555,7 @@ err: __wt_free(session, idxconf);
__wt_buf_free(session, &fmt);
__wt_buf_free(session, &namebuf);
- __wt_schema_release_table(session, table);
+ WT_TRET(__wt_schema_release_table(session, table));
return (ret);
}
@@ -550,7 +565,7 @@ err: __wt_free(session, idxconf);
*/
static int
__create_table(WT_SESSION_IMPL *session,
- const char *name, bool exclusive, const char *config)
+ const char *uri, bool exclusive, const char *config)
{
WT_CONFIG conf;
WT_CONFIG_ITEM cgkey, cgval, cval;
@@ -562,24 +577,23 @@ __create_table(WT_SESSION_IMPL *session,
char *tableconf, *cgname;
size_t cgsize;
int ncolgroups;
- bool exists;
cgname = NULL;
table = NULL;
tableconf = NULL;
- exists = false;
- tablename = name;
- if (!WT_PREFIX_SKIP(tablename, "table:"))
- return (__wt_unexpected_object_type(session, name, "table:"));
+ WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_TABLE_WRITE));
- if ((ret = __wt_schema_get_table(session,
- tablename, strlen(tablename), false, &table)) == 0) {
+ 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_ERR(EEXIST);
- exists = true;
+ WT_TRET(EEXIST);
+ goto err;
}
- WT_ERR_NOTFOUND_OK(ret);
WT_ERR(__wt_config_gets(session, cfg, "colgroups", &cval));
__wt_config_subinit(session, &conf, &cval);
@@ -590,32 +604,30 @@ __create_table(WT_SESSION_IMPL *session,
WT_ERR_NOTFOUND_OK(ret);
WT_ERR(__wt_config_collapse(session, cfg, &tableconf));
+ WT_ERR(__wt_metadata_insert(session, uri, tableconf));
- if (!exists) {
- WT_ERR(__wt_metadata_insert(session, name, tableconf));
-
- /* Attempt to open the table now to catch any errors. */
- WT_ERR(__wt_schema_get_table(
- session, tablename, strlen(tablename), true, &table));
-
- 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));
- }
+ 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));
}
- if (0) {
-err: if (table != NULL) {
- WT_TRET(__wt_schema_remove_table(session, table));
- table = NULL;
- }
+ /*
+ * 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;
}
- if (table != NULL)
- __wt_schema_release_table(session, table);
+
+err: if (table != NULL)
+ WT_TRET(__wt_schema_release_table(session, table));
__wt_free(session, cgname);
__wt_free(session, tableconf);
return (ret);