From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 572DF2D64F for ; Fri, 12 Oct 2018 07:38:31 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 04xfOvt7F-XU for ; Fri, 12 Oct 2018 07:38:31 -0400 (EDT) Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id B6E182D5F8 for ; Fri, 12 Oct 2018 07:38:30 -0400 (EDT) From: Kirill Yukhin Subject: [tarantool-patches] [PATCH v2 1/2] Add space names cache Date: Fri, 12 Oct 2018 14:38:18 +0300 Message-Id: <32338133284dcb28db1b85654680cdece188904a.1539344128.git.kyukhin@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: korablev@tarantool.org Cc: tarantool-patches@freelists.org, Kirill Yukhin Since SQL is heavily using name -> space mapping, introduce (instead of scanning _space space) dedicated cache, which maps space name to space pointer. Update SQL sources thoroughly. Remove function which deletes from cache, making replace more general: it might be used for both insertions, deletions and replaces. --- src/box/alter.cc | 18 ++++--- src/box/schema.cc | 123 ++++++++++++++++++++++++++++++++++++------ src/box/schema.h | 12 ++++- src/box/sql/alter.c | 11 ++-- src/box/sql/analyze.c | 44 ++++++--------- src/box/sql/build.c | 57 +++++++------------- src/box/sql/delete.c | 26 ++++----- src/box/sql/insert.c | 7 +-- src/box/sql/pragma.c | 32 ++++------- test/box/stat.result | 6 +-- 10 files changed, 196 insertions(+), 140 deletions(-) diff --git a/src/box/alter.cc b/src/box/alter.cc index de3943c..8f84196 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -810,7 +810,8 @@ alter_space_rollback(struct trigger *trigger, void * /* event */) */ space_swap_triggers(alter->new_space, alter->old_space); space_swap_fkeys(alter->new_space, alter->old_space); - struct space *new_space = space_cache_replace(alter->old_space); + struct space *new_space = space_cache_replace(alter->old_space, + alter->new_space); assert(new_space == alter->new_space); (void) new_space; alter_space_delete(alter); @@ -913,7 +914,8 @@ alter_space_do(struct txn *txn, struct alter_space *alter) * The new space is ready. Time to update the space * cache with it. */ - struct space *old_space = space_cache_replace(alter->new_space); + struct space *old_space = space_cache_replace(alter->new_space, + alter->old_space); (void) old_space; assert(old_space == alter->old_space); @@ -1421,7 +1423,7 @@ on_drop_space_rollback(struct trigger *trigger, void *event) { (void) event; struct space *space = (struct space *)trigger->data; - space_cache_replace(space); + space_cache_replace(space, NULL); } /** @@ -1447,7 +1449,7 @@ on_create_space_rollback(struct trigger *trigger, void *event) { (void) event; struct space *space = (struct space *)trigger->data; - struct space *cached = space_cache_delete(space_id(space)); + struct space *cached = space_cache_delete(space); (void) cached; assert(cached == space); space_delete(space); @@ -1610,8 +1612,8 @@ on_drop_view_rollback(struct trigger *trigger, void *event) * * - space cache should be updated, and changes in the space * cache should be reflected in Lua bindings - * (this is done in space_cache_replace() and - * space_cache_delete()) + * (this is done in space_cache_replace(), + * space_cache_delete() and space_name_cache_delete()) * * - the space which is changed should be rebuilt according * to the nature of the modification, i.e. indexes added/dropped, @@ -1695,7 +1697,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) * cache right away to achieve linearisable * execution on a replica. */ - (void) space_cache_replace(space); + (void) space_cache_replace(space, NULL); /* * Do not forget to update schema_version right after * inserting the space to the space_cache, since no @@ -1787,7 +1789,7 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event) * cache right away to achieve linearisable * execution on a replica. */ - struct space *space = space_cache_delete(space_id(old_space)); + struct space *space = space_cache_delete(old_space); /* * Do not forget to update schema_version right after * deleting the space from the space_cache, since no diff --git a/src/box/schema.cc b/src/box/schema.cc index 2d2be26..f109b34 100644 --- a/src/box/schema.cc +++ b/src/box/schema.cc @@ -55,6 +55,7 @@ /** All existing spaces. */ static struct mh_i32ptr_t *spaces; +static struct mh_strnptr_t *spaces_by_name; static struct mh_i32ptr_t *funcs; static struct mh_strnptr_t *funcs_by_name; static struct mh_i32ptr_t *sequences; @@ -95,6 +96,17 @@ space_by_id(uint32_t id) return (struct space *) mh_i32ptr_node(spaces, space)->val; } +/** Return space by its name */ +struct space * +space_by_name(const char *name) +{ + mh_int_t space = mh_strnptr_find_inp(spaces_by_name, name, + strlen(name)); + if (space == mh_end(spaces_by_name)) + return NULL; + return (struct space *) mh_strnptr_node(spaces_by_name, space)->val; +} + /** Return current schema version */ uint32_t box_schema_version() @@ -160,14 +172,26 @@ space_foreach(int (*func)(struct space *sp, void *udata), void *udata) /** Delete a space from the space cache and Lua. */ struct space * -space_cache_delete(uint32_t id) +space_cache_delete(struct space *space) { - mh_int_t k = mh_i32ptr_find(spaces, id, NULL); + mh_int_t k = mh_i32ptr_find(spaces, space_id(space), NULL); assert(k != mh_end(spaces)); - struct space *space = (struct space *)mh_i32ptr_node(spaces, k)->val; + struct space *space_by_id = (struct space *)mh_i32ptr_node(spaces, + k)->val; + assert(space_by_id == space); mh_i32ptr_del(spaces, k, NULL); + + const char *name = space_name(space); + k = mh_strnptr_find_inp(spaces_by_name, name, strlen(name)); + assert(k != mh_end(spaces_by_name)); + struct space *space_by_n = (struct space *)mh_strnptr_node(spaces_by_name, + k)->val; + assert(space_by_n == space_by_id); + (void)space_by_id; + mh_strnptr_del(spaces_by_name, k, NULL); + space_cache_version++; - return space; + return space_by_n; } /** @@ -175,17 +199,83 @@ space_cache_delete(uint32_t id) * the old space instance, if any, or NULL if it's a new space. */ struct space * -space_cache_replace(struct space *space) +space_cache_replace(struct space *new_space, struct space *old_space) { - const struct mh_i32ptr_node_t node = { space_id(space), space }; - struct mh_i32ptr_node_t old, *p_old = &old; - mh_int_t k = mh_i32ptr_put(spaces, &node, &p_old, NULL); - if (k == mh_end(spaces)) { - panic_syserror("Out of memory for the data " - "dictionary cache."); + assert(new_space != NULL || old_space != NULL); + struct space *old_space_by_n = NULL; + struct space *old_space_by_id = NULL; + if (new_space != NULL) { + /* + * If replacing is performed and space name was + * changed, then need to explicitly remove old + * entry from spaces cache. + * NB: Sincce space_id never changed - no need + * to do so for space_id cache. + */ + if (old_space != NULL && strcmp(space_name(old_space), + new_space->def->name) != 0) { + const char *name = space_name(old_space); + mh_int_t k = mh_strnptr_find_inp(spaces_by_name, name, + strlen(name)); + assert(k != mh_end(spaces_by_name)); + mh_strnptr_del(spaces_by_name, k, NULL); + old_space_by_n = (struct space *)mh_strnptr_node(spaces_by_name, + k)->val; + space_cache_version++; + } + const struct mh_i32ptr_node_t node_p = { space_id(new_space), + new_space }; + struct mh_i32ptr_node_t old, *p_old = &old; + mh_int_t k = mh_i32ptr_put(spaces, &node_p, &p_old, NULL); + if (k == mh_end(spaces)) { + panic_syserror("Out of memory for the data " + "dictionary cache."); + } + const char *name = space_name(new_space); + uint32_t name_len = strlen(name); + uint32_t hash = mh_strn_hash(name, name_len); + const struct mh_strnptr_node_t node_s = { name, name_len, hash, + new_space }; + struct mh_strnptr_node_t old_s, *p_old_s = &old_s; + k = mh_strnptr_put(spaces_by_name, &node_s, &p_old_s, NULL); + if (k == mh_end(spaces_by_name)) { + panic_syserror("Out of memory for the data " + "dictionary cache."); + } + assert(old_space_by_n == NULL || p_old_s == NULL); + if(old_space_by_n == NULL && p_old != NULL) { + assert(p_old->val == p_old_s->val); + old_space_by_n = (struct space *)p_old->val; + } + } else { + mh_int_t k = mh_i32ptr_find(spaces, space_id(old_space), NULL); + assert(k != mh_end(spaces)); + old_space_by_id = (struct space *)mh_i32ptr_node(spaces, k)->val; + assert(old_space_by_id == old_space); + mh_i32ptr_del(spaces, k, NULL); + const char *name = space_name(old_space); + k = mh_strnptr_find_inp(spaces_by_name, name, strlen(name)); + assert(k != mh_end(spaces_by_name)); + old_space_by_n = (struct space *)mh_strnptr_node(spaces_by_name, + k)->val; + assert(old_space_by_n == old_space_by_id); + (void)old_space_by_id; + mh_strnptr_del(spaces_by_name, k, NULL); } space_cache_version++; - return p_old ? (struct space *) p_old->val : NULL; + return old_space_by_n; +} + +/** Delete a space from the space name cache. */ +struct space * +space_name_cache_delete(const char *name) +{ + mh_int_t k = mh_strnptr_find_inp(spaces_by_name, name, strlen(name)); + assert(k != mh_end(spaces_by_name)); + struct space *space = (struct space *)mh_strnptr_node(spaces_by_name, + k)->val; + mh_strnptr_del(spaces_by_name, k, NULL); + return space; } /** A wrapper around space_new() for data dictionary spaces. */ @@ -220,7 +310,7 @@ sc_space_new(uint32_t id, const char *name, rlist_create(&key_list); rlist_add_entry(&key_list, index_def, link); struct space *space = space_new_xc(def, &key_list); - (void) space_cache_replace(space); + (void) space_cache_replace(space, NULL); if (replace_trigger) trigger_add(&space->on_replace, replace_trigger); if (stmt_begin_trigger) @@ -303,6 +393,7 @@ schema_init() /* Initialize the space cache. */ spaces = mh_i32ptr_new(); + spaces_by_name = mh_strnptr_new(); funcs = mh_i32ptr_new(); funcs_by_name = mh_strnptr_new(); sequences = mh_i32ptr_new(); @@ -431,7 +522,7 @@ schema_init() }); RLIST_HEAD(key_list); struct space *space = space_new_xc(def, &key_list); - space_cache_replace(space); + space_cache_replace(space, NULL); init_system_space(space); trigger_run_xc(&on_alter_space, space); } @@ -447,10 +538,12 @@ schema_free(void) struct space *space = (struct space *) mh_i32ptr_node(spaces, i)->val; - space_cache_delete(space_id(space)); + space_cache_delete(space); + space_name_cache_delete(space_name(space)); space_delete(space); } mh_i32ptr_delete(spaces); + mh_strnptr_delete(spaces_by_name); while (mh_size(funcs) > 0) { mh_int_t i = mh_first(funcs); diff --git a/src/box/schema.h b/src/box/schema.h index 264c16b..c54f5a8 100644 --- a/src/box/schema.h +++ b/src/box/schema.h @@ -58,6 +58,14 @@ extern struct latch schema_lock; struct space * space_by_id(uint32_t id); +/** + * Try to look up a space by space name in the space name cache. + * + * @return NULL if space not found, otherwise space object. + */ +struct space * +space_by_name(const char *name); + uint32_t box_schema_version(); @@ -137,11 +145,11 @@ space_cache_find_xc(uint32_t id) * Returns the old space, if any. */ struct space * -space_cache_replace(struct space *space); +space_cache_replace(struct space *new_space, struct space *old_space); /** Delete a space from the space cache. */ struct space * -space_cache_delete(uint32_t id); +space_cache_delete(struct space *space); void schema_init(); diff --git a/src/box/sql/alter.c b/src/box/sql/alter.c index 3d72e31..7c28437 100644 --- a/src/box/sql/alter.c +++ b/src/box/sql/alter.c @@ -47,18 +47,17 @@ sql_alter_table_rename(struct Parse *parse, struct SrcList *src_tab, if (new_name == NULL) goto exit_rename_table; /* Check that new name isn't occupied by another table. */ - uint32_t space_id = box_space_id_by_name(new_name, strlen(new_name)); - if (space_id != BOX_ID_NIL) { + struct space *space = space_by_name(new_name); + if (space != NULL) { diag_set(ClientError, ER_SPACE_EXISTS, new_name); goto tnt_error; } const char *tbl_name = src_tab->a[0].zName; - space_id = box_space_id_by_name(tbl_name, strlen(tbl_name)); - if (space_id == BOX_ID_NIL) { + space = space_by_name(tbl_name); + if (space == NULL) { diag_set(ClientError, ER_NO_SUCH_SPACE, tbl_name); goto tnt_error; } - struct space *space = space_by_id(space_id); assert(space != NULL); if (space->def->opts.is_view) { diag_set(ClientError, ER_ALTER_SPACE, tbl_name, @@ -68,7 +67,7 @@ sql_alter_table_rename(struct Parse *parse, struct SrcList *src_tab, sql_set_multi_write(parse, false); /* Drop and reload the internal table schema. */ struct Vdbe *v = sqlite3GetVdbe(parse); - sqlite3VdbeAddOp4(v, OP_RenameTable, space_id, 0, 0, new_name, + sqlite3VdbeAddOp4(v, OP_RenameTable, space->def->id, 0, 0, new_name, P4_DYNAMIC); exit_rename_table: sqlite3SrcListDelete(db, src_tab); diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c index 674d53d..ad068a5 100644 --- a/src/box/sql/analyze.c +++ b/src/box/sql/analyze.c @@ -1114,16 +1114,15 @@ sqlite3Analyze(Parse * pParse, Token * pName) /* Form 2: Analyze table named */ char *z = sqlite3NameFromToken(db, pName); if (z != NULL) { - uint32_t space_id = box_space_id_by_name(z, strlen(z)); - if (space_id != BOX_ID_NIL) { - struct space *sp = space_by_id(space_id); - assert(sp != NULL); - if (sp->def->opts.is_view) { + struct space *space = space_by_name(z); + if (space != NULL) { + assert(space != NULL); + if (space->def->opts.is_view) { sqlite3ErrorMsg(pParse, "VIEW isn't "\ "allowed to be "\ "analyzed"); } else { - vdbe_emit_analyze_table(pParse, sp); + vdbe_emit_analyze_table(pParse, space); } } else { diag_set(ClientError, ER_NO_SUCH_SPACE, z); @@ -1224,13 +1223,12 @@ analysis_loader(void *data, int argc, char **argv, char **unused) struct analysis_index_info *info = (struct analysis_index_info *) data; assert(info->stats != NULL); struct index_stat *stat = &info->stats[info->index_count++]; - uint32_t space_id = box_space_id_by_name(argv[0], strlen(argv[0])); - if (space_id == BOX_ID_NIL) + struct space *space = space_by_name(argv[0]); + if (space == NULL) return -1; - struct space *space = space_by_id(space_id); - assert(space != NULL); struct index *index; - uint32_t iid = box_index_id_by_name(space_id, argv[1], strlen(argv[1])); + uint32_t iid = box_index_id_by_name(space->def->id, argv[1], + strlen(argv[1])); /* * Convention is if index's name matches with space's * one, then it is primary index. @@ -1395,13 +1393,10 @@ load_stat_from_space(struct sqlite3 *db, const char *sql_select_prepare, if (index_name == NULL) continue; uint32_t sample_count = sqlite3_column_int(stmt, 2); - uint32_t space_id = box_space_id_by_name(space_name, - strlen(space_name)); - assert(space_id != BOX_ID_NIL); - struct space *space = space_by_id(space_id); + struct space *space = space_by_name(space_name); assert(space != NULL); struct index *index; - uint32_t iid = box_index_id_by_name(space_id, index_name, + uint32_t iid = box_index_id_by_name(space->def->id, index_name, strlen(index_name)); if (sqlite3_stricmp(space_name, index_name) == 0 && iid == BOX_ID_NIL) @@ -1466,13 +1461,10 @@ load_stat_from_space(struct sqlite3 *db, const char *sql_select_prepare, const char *index_name = (char *)sqlite3_column_text(stmt, 1); if (index_name == NULL) continue; - uint32_t space_id = box_space_id_by_name(space_name, - strlen(space_name)); - assert(space_id != BOX_ID_NIL); - struct space *space = space_by_id(space_id); - assert(space != NULL); + struct space *space = space_by_name(space_name); + assert (space != NULL); struct index *index; - uint32_t iid = box_index_id_by_name(space_id, index_name, + uint32_t iid = box_index_id_by_name(space->def->id, index_name, strlen(index_name)); if (iid != BOX_ID_NIL) { index = space_index(space, iid); @@ -1550,14 +1542,10 @@ load_stat_to_index(struct sqlite3 *db, const char *sql_select_load, const char *index_name = (char *)sqlite3_column_text(stmt, 1); if (index_name == NULL) continue; - uint32_t space_id = box_space_id_by_name(space_name, - strlen(space_name)); - if (space_id == BOX_ID_NIL) - return -1; - struct space *space = space_by_id(space_id); + struct space *space = space_by_name(space_name); assert(space != NULL); struct index *index; - uint32_t iid = box_index_id_by_name(space_id, index_name, + uint32_t iid = box_index_id_by_name(space->def->id, index_name, strlen(index_name)); if (iid != BOX_ID_NIL) { index = space_index(space, iid); diff --git a/src/box/sql/build.c b/src/box/sql/build.c index a806fb4..c5a527d 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -329,8 +329,8 @@ sqlite3StartTable(Parse *pParse, Token *pName, int noErr) if (sqlite3CheckIdentifierName(pParse, zName) != SQLITE_OK) goto cleanup; - uint32_t space_id = box_space_id_by_name(zName, strlen(zName)); - if (space_id != BOX_ID_NIL) { + struct space *space = space_by_name(zName); + if (space != NULL) { if (!noErr) { sqlite3ErrorMsg(pParse, "table %s already exists", zName); @@ -1863,9 +1863,8 @@ sql_drop_table(struct Parse *parse_context, struct SrcList *table_name_list, assert(parse_context->nErr == 0); assert(table_name_list->nSrc == 1); const char *space_name = table_name_list->a[0].zName; - uint32_t space_id = box_space_id_by_name(space_name, - strlen(space_name)); - if (space_id == BOX_ID_NIL) { + struct space *space = space_by_name(space_name); + if (space == NULL) { if (!is_view && !if_exists) sqlite3ErrorMsg(parse_context, "no such table: %s", space_name); @@ -1874,8 +1873,6 @@ sql_drop_table(struct Parse *parse_context, struct SrcList *table_name_list, space_name); goto exit_drop_table; } - struct space *space = space_by_id(space_id); - assert(space != NULL); /* * Ensure DROP TABLE is not used on a view, * and DROP VIEW is not used on a table. @@ -1990,17 +1987,13 @@ sql_create_foreign_key(struct Parse *parse_context, struct SrcList *child, } assert(!is_alter || (child != NULL && child->nSrc == 1)); struct space *child_space = NULL; - uint32_t child_id = 0; if (is_alter) { const char *child_name = child->a[0].zName; - child_id = box_space_id_by_name(child_name, - strlen(child_name)); - if (child_id == BOX_ID_NIL) { + child_space = space_by_name(child_name); + if (child_space == NULL) { diag_set(ClientError, ER_NO_SUCH_SPACE, child_name); goto tnt_error; } - child_space = space_by_id(child_id); - assert(child_space != NULL); } else { struct fkey_parse *fk = region_alloc(&parse_context->region, sizeof(*fk)); @@ -2016,8 +2009,7 @@ sql_create_foreign_key(struct Parse *parse_context, struct SrcList *child, parent_name = sqlite3NameFromToken(db, parent); if (parent_name == NULL) goto exit_create_fk; - uint32_t parent_id = box_space_id_by_name(parent_name, - strlen(parent_name)); + struct space *parent_space = space_by_name(parent_name); /* * Within ALTER TABLE ADD CONSTRAINT FK also can be * self-referenced, but in this case parent (which is @@ -2025,9 +2017,7 @@ sql_create_foreign_key(struct Parse *parse_context, struct SrcList *child, */ is_self_referenced = !is_alter && strcmp(parent_name, new_tab->def->name) == 0; - struct space *parent_space; - if (parent_id == BOX_ID_NIL) { - parent_space = NULL; + if (parent_space == NULL) { if (is_self_referenced) { struct fkey_parse *fk = rlist_first_entry(&parse_context->new_fkey, @@ -2039,8 +2029,6 @@ sql_create_foreign_key(struct Parse *parse_context, struct SrcList *child, goto tnt_error; } } else { - parent_space = space_by_id(parent_id); - assert(parent_space != NULL); if (parent_space->def->opts.is_view) { sqlite3ErrorMsg(parse_context, "referenced table can't be view"); @@ -2092,8 +2080,8 @@ sql_create_foreign_key(struct Parse *parse_context, struct SrcList *child, goto tnt_error; } fk->field_count = child_cols_count; - fk->child_id = child_id; - fk->parent_id = parent_id; + fk->child_id = child_space != NULL ? child_space->def->id : 0; + fk->parent_id = parent_space != NULL ? parent_space->def->id : 0; fk->is_deferred = is_deferred; fk->match = (enum fkey_match) ((actions >> 16) & 0xff); fk->on_update = (enum fkey_action) ((actions >> 8) & 0xff); @@ -2184,9 +2172,8 @@ sql_drop_foreign_key(struct Parse *parse_context, struct SrcList *table, { assert(table != NULL && table->nSrc == 1); const char *table_name = table->a[0].zName; - uint32_t child_id = box_space_id_by_name(table_name, - strlen(table_name)); - if (child_id == BOX_ID_NIL) { + struct space *child = space_by_name(table_name); + if (child == NULL) { diag_set(ClientError, ER_NO_SUCH_SPACE, table_name); parse_context->rc = SQL_TARANTOOL_ERROR; parse_context->nErr++; @@ -2195,7 +2182,8 @@ sql_drop_foreign_key(struct Parse *parse_context, struct SrcList *table, char *constraint_name = sqlite3NameFromToken(parse_context->db, constraint); if (constraint_name != NULL) - vdbe_emit_fkey_drop(parse_context, constraint_name, child_id); + vdbe_emit_fkey_drop(parse_context, constraint_name, + child->def->id); } /* @@ -2415,8 +2403,8 @@ sql_create_index(struct Parse *parse, struct Token *token, if (tbl_name != NULL) { assert(token != NULL && token->z != NULL); const char *name = tbl_name->a[0].zName; - uint32_t space_id = box_space_id_by_name(name, strlen(name)); - if (space_id == BOX_ID_NIL) { + space = space_by_name(name); + if (space == NULL) { if (! if_not_exist) { diag_set(ClientError, ER_NO_SUCH_SPACE, name); parse->rc = SQL_TARANTOOL_ERROR; @@ -2424,8 +2412,6 @@ sql_create_index(struct Parse *parse, struct Token *token, } goto exit_create_index; } - space = space_by_id(space_id); - assert(space != NULL); def = space->def; } else { if (parse->pNewTable == NULL) @@ -2738,16 +2724,15 @@ sql_drop_index(struct Parse *parse_context, struct SrcList *index_name_list, sqlite3VdbeCountChanges(v); assert(index_name_list->nSrc == 1); assert(table_token->n > 0); - uint32_t space_id = box_space_id_by_name(table_name, - strlen(table_name)); - if (space_id == BOX_ID_NIL) { + struct space *space = space_by_name(table_name); + if (space == NULL) { if (!if_exists) sqlite3ErrorMsg(parse_context, "no such space: %s", table_name); goto exit_drop_index; } const char *index_name = index_name_list->a[0].zName; - uint32_t index_id = box_index_id_by_name(space_id, index_name, + uint32_t index_id = box_index_id_by_name(space->def->id, index_name, strlen(index_name)); if (index_id == BOX_ID_NIL) { if (!if_exists) @@ -2755,8 +2740,6 @@ sql_drop_index(struct Parse *parse_context, struct SrcList *index_name_list, table_name, index_name); goto exit_drop_index; } - struct space *space = space_by_id(space_id); - assert(space != NULL); struct index *index = space_index(space, index_id); assert(index != NULL); /* @@ -2779,7 +2762,7 @@ sql_drop_index(struct Parse *parse_context, struct SrcList *index_name_list, sql_clear_stat_spaces(parse_context, table_name, index->def->name); int record_reg = ++parse_context->nMem; int space_id_reg = ++parse_context->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, space_id, space_id_reg); + sqlite3VdbeAddOp2(v, OP_Integer, space->def->id, space_id_reg); sqlite3VdbeAddOp2(v, OP_Integer, index_id, space_id_reg + 1); sqlite3VdbeAddOp3(v, OP_MakeRecord, space_id_reg, 2, record_reg); sqlite3VdbeAddOp2(v, OP_SDelete, BOX_INDEX_ID, record_reg); diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c index 8f6c76f..72e0575 100644 --- a/src/box/sql/delete.c +++ b/src/box/sql/delete.c @@ -36,15 +36,14 @@ #include "tarantoolInt.h" struct Table * -sql_lookup_table(struct Parse *parse, struct SrcList_item *tbl_name) +sql_lookup_table(struct Parse *parse, struct SrcList_item *src_name) { - assert(tbl_name != NULL); - assert(tbl_name->pTab == NULL); - uint32_t space_id = box_space_id_by_name(tbl_name->zName, - strlen(tbl_name->zName)); - struct space *space = space_by_id(space_id); - if (space_id == BOX_ID_NIL || space == NULL) { - sqlite3ErrorMsg(parse, "no such table: %s", tbl_name->zName); + assert(src_name != NULL); + assert(src_name->pTab == NULL); + const char *name = src_name->zName; + struct space *space = space_by_name(name); + if (space == NULL) { + sqlite3ErrorMsg(parse, "no such table: %s", name); return NULL; } assert(space != NULL); @@ -61,8 +60,8 @@ sql_lookup_table(struct Parse *parse, struct SrcList_item *tbl_name) table->def = space->def; table->space = space; table->nTabRef = 1; - tbl_name->pTab = table; - if (sqlite3IndexedByLookup(parse, tbl_name) != 0) + src_name->pTab = table; + if (sqlite3IndexedByLookup(parse, src_name) != 0) table = NULL; return table; } @@ -98,14 +97,11 @@ sql_table_truncate(struct Parse *parse, struct SrcList *tab_list) goto cleanup; const char *tab_name = tab_list->a->zName; - uint32_t space_id = box_space_id_by_name(tab_name, strlen(tab_name)); - if (space_id == BOX_ID_NIL) { + struct space *space = space_by_name(tab_name); + if (space == NULL) { diag_set(ClientError, ER_NO_SUCH_SPACE, tab_name); goto tarantool_error; } - struct space *space = space_cache_find(space_id); - assert(space != NULL); - if (! rlist_empty(&space->parent_fkey)) { const char *err_msg = tt_sprintf("can not truncate space '%s' because other " diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c index 5862917..eef27bc 100644 --- a/src/box/sql/insert.c +++ b/src/box/sql/insert.c @@ -1197,13 +1197,10 @@ xferOptimization(Parse * pParse, /* Parser context */ * we have to check the semantics. */ pItem = pSelect->pSrc->a; - uint32_t src_id = box_space_id_by_name(pItem->zName, - strlen(pItem->zName)); + struct space *src = space_by_name(pItem->zName); /* FROM clause does not contain a real table. */ - if (src_id == BOX_ID_NIL) + if (src == NULL) return 0; - struct space *src = space_by_id(src_id); - assert(src != NULL); /* Src and dest may not be the same table. */ if (src->def->id == dest->def->id) return 0; diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c index 2e007f9..9ece82a 100644 --- a/src/box/sql/pragma.c +++ b/src/box/sql/pragma.c @@ -257,11 +257,9 @@ sql_pragma_table_info(struct Parse *parse, const char *tbl_name) { if (tbl_name == NULL) return; - uint32_t space_id = box_space_id_by_name(tbl_name, strlen(tbl_name)); - if (space_id == BOX_ID_NIL) + struct space *space = space_by_name(tbl_name); + if (space == NULL) return; - struct space *space = space_by_id(space_id); - assert(space != NULL); struct index *pk = space_index(space, 0); parse->nMem = 6; if (space->def->opts.is_view) @@ -336,14 +334,12 @@ sql_pragma_index_info(struct Parse *parse, const PragmaName *pragma, { if (idx_name == NULL || tbl_name == NULL) return; - uint32_t space_id = box_space_id_by_name(tbl_name, strlen(tbl_name)); - if (space_id == BOX_ID_NIL) + struct space *space = space_by_name(tbl_name); + if (space == NULL) return; - struct space *space = space_by_id(space_id); - assert(space != NULL); if (space->def->opts.sql == NULL) return; - uint32_t iid = box_index_id_by_name(space_id, idx_name, + uint32_t iid = box_index_id_by_name(space->def->id, idx_name, strlen(idx_name)); if (iid == BOX_ID_NIL) return; @@ -390,11 +386,9 @@ sql_pragma_index_list(struct Parse *parse, const char *tbl_name) { if (tbl_name == NULL) return; - uint32_t space_id = box_space_id_by_name(tbl_name, strlen(tbl_name)); - if (space_id == BOX_ID_NIL) + struct space *space = space_by_name(tbl_name); + if (space == NULL) return; - struct space *space = space_by_id(space_id); - assert(space != NULL); parse->nMem = 5; struct Vdbe *v = sqlite3GetVdbe(parse); for (uint32_t i = 0; i < space->index_count; ++i) { @@ -516,15 +510,13 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */ case PragTyp_COLLATION_LIST:{ int i = 0; - uint32_t space_id; - space_id = box_space_id_by_name("_collation", - (uint32_t) strlen("_collation")); + struct space *space = space_by_name("_collation"); char key_buf[16]; /* 16 is enough to encode 0 len array */ char *key_end = key_buf; key_end = mp_encode_array(key_end, 0); box_tuple_t *tuple; box_iterator_t* iter; - iter = box_index_iterator(space_id, 0,ITER_ALL, key_buf, key_end); + iter = box_index_iterator(space->def->id, 0,ITER_ALL, key_buf, key_end); int rc = box_iterator_next(iter, &tuple); (void) rc; assert(rc == 0); @@ -544,11 +536,9 @@ sqlite3Pragma(Parse * pParse, Token * pId, /* First part of [schema.]id field */ case PragTyp_FOREIGN_KEY_LIST:{ if (zRight == NULL) break; - uint32_t space_id = box_space_id_by_name(zRight, - strlen(zRight)); - if (space_id == BOX_ID_NIL) + struct space *space = space_by_name(zRight); + if (space == NULL) break; - struct space *space = space_by_id(space_id); int i = 0; pParse->nMem = 8; struct fkey *fkey; diff --git a/test/box/stat.result b/test/box/stat.result index 60ba88f..af1607d 100644 --- a/test/box/stat.result +++ b/test/box/stat.result @@ -24,7 +24,7 @@ box.stat.REPLACE.total ... box.stat.SELECT.total --- -- 2 +- 1 ... box.stat.ERROR.total --- @@ -59,7 +59,7 @@ box.stat.REPLACE.total ... box.stat.SELECT.total --- -- 5 +- 4 ... -- check exceptions space:get('Impossible value') @@ -118,7 +118,7 @@ box.stat.REPLACE.total ... box.stat.SELECT.total --- -- 2 +- 1 ... box.stat.ERROR.total --- -- 2.19.1