From: Roman Khabibov <roman.habibov@tarantool.org> To: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Cc: tarantool-patches@dev.tarantool.org Subject: Re: [Tarantool-patches] [PATCH v2 2/3] sql: don't select from _index during parsing Date: Tue, 3 Mar 2020 15:47:38 +0300 [thread overview] Message-ID: <D9FC7B96-6B8D-4CB8-929A-71DE92BCFE4F@tarantool.org> (raw) In-Reply-To: <20200303101204.16338-3-roman.habibov@tarantool.org> Don’t see the previous mail of this commit. sql: don't select from _index during parsing Remove function box_index_by_name() from parser to avoid selects during parsing. Add the ability to choose index during VDBE code compilation which will be used to find the tuple to drop from a system space. Needed for #4120 --- src/box/space.h | 19 +++++++++++ src/box/sql/build.c | 79 +++++++++++++++++++++----------------------- src/box/sql/pragma.c | 8 ++--- src/box/sql/vdbe.c | 10 +++--- 4 files changed, 64 insertions(+), 52 deletions(-) diff --git a/src/box/space.h b/src/box/space.h index 9aea4e5be..bbdd3ef70 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -287,6 +287,25 @@ space_index(struct space *space, uint32_t id) return NULL; } +/** + * Get index by index name. + * + * @param space Space index belongs to. + * @param index_name Name of index to be found. + * + * @retval NULL if the index is not found. + */ +static inline struct index * +space_index_by_name(struct space *space, const char *index_name) +{ + for(uint32_t i = 0; i < space->index_count; i++) { + struct index *index = space->index[i]; + if (strcmp(index_name, index->def->name) == 0) + return index; + } + return NULL; +} + /** * Return true if the unique constraint must be checked for * the index with the given id before inserting a tuple into diff --git a/src/box/sql/build.c b/src/box/sql/build.c index d9bf8de91..fef069640 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -47,7 +47,6 @@ #include "sqlInt.h" #include "vdbeInt.h" #include "tarantoolInt.h" -#include "box/box.h" #include "box/ck_constraint.h" #include "box/fk_constraint.h" #include "box/sequence.h" @@ -116,24 +115,6 @@ sql_finish_coding(struct Parse *parse_context) parse_context->is_aborted = true; } } -/** - * Find index by its name. - * - * @param space Space index belongs to. - * @param name Name of index to be found. - * - * @retval NULL in case index doesn't exist. - */ -static struct index * -sql_space_index_by_name(struct space *space, const char *name) -{ - for (uint32_t i = 0; i < space->index_count; ++i) { - struct index *idx = space->index[i]; - if (strcmp(name, idx->def->name) == 0) - return idx; - } - return NULL; -} bool sql_space_column_is_in_pk(struct space *space, uint32_t column) @@ -1469,6 +1450,40 @@ vdbe_emit_stat_space_clear(struct Parse *parse, const char *stat_table_name, sql_table_delete_from(parse, src_list, where); } +/** + * Generate VDBE program to remove entry from _index space. + * + * @param parse_context Parsing context. + * @param name Index name. + * @param space_def Def of table which index belongs to. + * @param errcode Type of printing error: "no such index" or + * "no such constraint". + * @param if_exist True if there was <IF EXISTS> in the query. + */ +static void +vdbe_emit_index_drop(struct Parse *parse_context, const char *name, + struct space_def *space_def, int errcode, bool if_exist) +{ + assert(errcode == ER_NO_SUCH_INDEX_NAME || + errcode == ER_NO_SUCH_CONSTRAINT); + struct Vdbe *vdbe = sqlGetVdbe(parse_context); + assert(vdbe != NULL); + assert(parse_context->db != NULL); + int key_reg = sqlGetTempRange(parse_context, 3); + sqlVdbeAddOp2(vdbe, OP_Integer, space_def->id, key_reg); + sqlVdbeAddOp4(vdbe, OP_String8, 0, key_reg + 1, 0, + sqlDbStrDup(parse_context->db, name), P4_DYNAMIC); + const char *error_msg = + tt_sprintf(tnt_errcode_desc(errcode), name, space_def->name); + if (vdbe_emit_halt_with_presence_test(parse_context, BOX_INDEX_ID, 2, + key_reg, 2, errcode, error_msg, + if_exist, OP_Found) != 0) + return; + sqlVdbeAddOp3(vdbe, OP_MakeRecord, key_reg, 2, key_reg + 2); + sqlVdbeAddOp3(vdbe, OP_SDelete, BOX_INDEX_ID, key_reg + 2, 2); + sqlReleaseTempRange(parse_context, key_reg, 3); +} + /** * Generate VDBE program to remove entry from _fk_constraint space. * @@ -2401,7 +2416,7 @@ sql_create_index(struct Parse *parse) { parse->is_aborted = true; goto exit_create_index; } - if (sql_space_index_by_name(space, name) != NULL) { + if (space_index_by_name(space, name) != NULL) { if (! create_entity_def->if_not_exist) { diag_set(ClientError, ER_INDEX_EXISTS_IN_SPACE, name, def->name); @@ -2695,29 +2710,9 @@ sql_drop_index(struct Parse *parse_context) parse_context->is_aborted = true; goto exit_drop_index; } - 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) { - diag_set(ClientError, ER_NO_SUCH_INDEX_NAME, - index_name, table_name); - parse_context->is_aborted = true; - } - goto exit_drop_index; - } - /* - * Generate code to remove entry from _index space - * But firstly, delete statistics since schema - * changes after DDL. - */ - int record_reg = ++parse_context->nMem; - int space_id_reg = ++parse_context->nMem; - int index_id_reg = ++parse_context->nMem; - sqlVdbeAddOp2(v, OP_Integer, space->def->id, space_id_reg); - sqlVdbeAddOp2(v, OP_Integer, index_id, index_id_reg); - sqlVdbeAddOp3(v, OP_MakeRecord, space_id_reg, 2, record_reg); - sqlVdbeAddOp2(v, OP_SDelete, BOX_INDEX_ID, record_reg); + vdbe_emit_index_drop(parse_context, index_name, space->def, + ER_NO_SUCH_INDEX_NAME, if_exists); sqlVdbeChangeP5(v, OPFLAG_NCHANGE); exit_drop_index: sqlSrcListDelete(db, table_list); diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c index a77bf4b16..c15f2e0d1 100644 --- a/src/box/sql/pragma.c +++ b/src/box/sql/pragma.c @@ -33,7 +33,6 @@ * This file contains code used to implement the PRAGMA command. */ #include "box/index.h" -#include "box/box.h" #include "box/tuple.h" #include "box/fk_constraint.h" #include "box/schema.h" @@ -192,12 +191,9 @@ sql_pragma_index_info(struct Parse *parse, struct space *space = space_by_name(tbl_name); if (space == NULL) return; - uint32_t iid = box_index_id_by_name(space->def->id, idx_name, - strlen(idx_name)); - if (iid == BOX_ID_NIL) + struct index *idx = space_index_by_name(space, idx_name); + if (idx == NULL) return; - struct index *idx = space_index(space, iid); - assert(idx != NULL); parse->nMem = 6; struct Vdbe *v = sqlGetVdbe(parse); assert(v != NULL); diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 620d74e66..912a10153 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -4460,11 +4460,12 @@ case OP_SInsert: { break; } -/* Opcode: SDelete P1 P2 * * P5 - * Synopsis: space id = P1, key = r[P2] +/* Opcode: SDelete P1 P2 P3 * P5 + * Synopsis: space id = P1, key = r[P2], searching index id = P3 * * This opcode is used only during DDL routine. - * Delete entry with given key from system space. + * Delete entry with given key from system space. P3 is the index + * number by which to search for the key. * * If P5 is set to OPFLAG_NCHANGE, account overall changes * made to database. @@ -4472,13 +4473,14 @@ case OP_SInsert: { case OP_SDelete: { assert(pOp->p1 > 0); assert(pOp->p2 >= 0); + assert(pOp->p3 >= 0); pIn2 = &aMem[pOp->p2]; struct space *space = space_by_id(pOp->p1); assert(space != NULL); assert(space_is_system(space)); assert(p->errorAction == ON_CONFLICT_ACTION_ABORT); - if (sql_delete_by_key(space, 0, pIn2->z, pIn2->n) != 0) + if (sql_delete_by_key(space, pOp->p3, pIn2->z, pIn2->n) != 0) goto abort_due_to_error; if (pOp->p5 & OPFLAG_NCHANGE) p->nChange++; -- 2.21.0 (Apple Git-122)
next prev parent reply other threads:[~2020-03-03 12:47 UTC|newest] Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-03-03 10:12 [Tarantool-patches] [PATCH v2 0/3] Add ability to drop constraints Roman Khabibov 2020-03-03 10:12 ` [Tarantool-patches] [PATCH v2 1/3] sql: improve "no such constraint" error message Roman Khabibov 2020-03-03 10:12 ` [Tarantool-patches] [PATCH v2 2/3] sql: don't select from _index during parsing Roman Khabibov 2020-03-03 12:47 ` Roman Khabibov [this message] 2020-03-03 10:12 ` [Tarantool-patches] [PATCH v2 3/3] sql: support constraint drop Roman Khabibov 2020-03-03 22:13 ` [Tarantool-patches] [PATCH v2 0/3] Add ability to drop constraints Vladislav Shpilevoy 2020-03-05 6:32 ` Kirill Yukhin 2020-03-04 21:09 ` Nikita Pettik -- strict thread matches above, loose matches on Subject: below -- 2020-02-29 12:46 Roman Khabibov 2020-02-29 12:46 ` [Tarantool-patches] [PATCH v2 2/3] sql: don't select from _index during parsing Roman Khabibov 2020-02-29 15:31 ` Vladislav Shpilevoy 2020-03-03 10:15 ` Roman Khabibov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=D9FC7B96-6B8D-4CB8-929A-71DE92BCFE4F@tarantool.org \ --to=roman.habibov@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 2/3] sql: don'\''t select from _index during parsing' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox