From: "n.pettik" <korablev@tarantool.org> To: tarantool-patches@freelists.org Cc: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Subject: [tarantool-patches] Re: [PATCH 3/3] sql: implement point where for DELETE stmts Date: Mon, 18 Jun 2018 15:29:53 +0300 [thread overview] Message-ID: <8E3011EE-AF57-4055-AE08-58DABDB1CC40@tarantool.org> (raw) In-Reply-To: <5b82e05e-3977-5189-7291-c302712dda58@tarantool.org> Thanks for fixes, I have squashed them. > 1. How about rename this function to parser_emit_open_cursor? > According to Tarantool naming convention a method name should > be called as 'object_action_subject'. > > Now we have too many different prefixes of parser methods: > sqlite3, sql, parse, parser, <no_prefix>. Lets use 'parser’. Ok, but I decided to call it vdbe_emit_open_cursor() since all staff connected with code generation rather belongs to vdbe: +++ b/src/box/sql/analyze.c @@ -178,7 +178,7 @@ openStatTable(Parse * pParse, /* Parsing context */ for (i = 0; aTable[i]; i++) { struct space *space = space_by_id(SQLITE_PAGENO_TO_SPACEID(aRoot[i])); - sql_emit_open_cursor(pParse, iStatCur + i, aRoot[i], space); + vdbe_emit_open_cursor(pParse, iStatCur + i, aRoot[i], space); +++ b/src/box/sql/build.c @@ -1181,8 +1181,8 @@ space_checks_expr_list(uint32_t space_id) } int -sql_emit_open_cursor(struct Parse *parse_context, int cursor, int index_id, - struct space *space) +vdbe_emit_open_cursor(struct Parse *parse_context, int cursor, int index_id, + struct space *space) { assert(space != NULL); struct Vdbe *vdbe = parse_context->pVdbe; @@ -2651,7 +2651,7 @@ sqlite3RefillIndex(Parse * pParse, Index * pIndex, int memRootPage) sqlite3VdbeAddOp2(v, OP_Clear, SQLITE_PAGENO_TO_SPACEID(tnum), 0); struct space *space = space_by_id(SQLITE_PAGENO_TO_SPACEID(tnum)); - sql_emit_open_cursor(pParse, iIdx, tnum, space); + vdbe_emit_open_cursor(pParse, iIdx, tnum, space); +++ b/src/box/sql/expr.c @@ -2489,8 +2489,8 @@ sqlite3FindInIndex(Parse * pParse, /* Parsing context */ P4_DYNAMIC); struct space *space = space_by_id(SQLITE_PAGENO_TO_SPACEID(pIdx->tnum)); - sql_emit_open_cursor(pParse, iTab, - pIdx->tnum, space); + vdbe_emit_open_cursor(pParse, iTab, + pIdx->tnum, space); +++ b/src/box/sql/insert.c @@ -55,7 +55,7 @@ sqlite3OpenTable(Parse * pParse, /* Generate code into this VDBE */ assert(pPk != 0); assert(pPk->tnum == pTab->tnum); struct space *space = space_by_id(SQLITE_PAGENO_TO_SPACEID(pPk->tnum)); - sql_emit_open_cursor(pParse, iCur, pPk->tnum, space); + vdbe_emit_open_cursor(pParse, iCur, pPk->tnum, space); @@ -1943,11 +1941,11 @@ xferOptimization(Parse * pParse, /* Parser context */ assert(pSrcIdx); struct space *src_space = space_by_id(SQLITE_PAGENO_TO_SPACEID(pSrcIdx->tnum)); - sql_emit_open_cursor(pParse, iSrc, pSrcIdx->tnum, src_space); + vdbe_emit_open_cursor(pParse, iSrc, pSrcIdx->tnum, src_space); VdbeComment((v, "%s", pSrcIdx->zName)); struct space *dest_space = space_by_id(SQLITE_PAGENO_TO_SPACEID(pDestIdx->tnum)); - sql_emit_open_cursor(pParse, iDest, pDestIdx->tnum, dest_space); + vdbe_emit_open_cursor(pParse, iDest, pDestIdx->tnum, dest_space); +++ b/src/box/sql/select.c @@ -6107,9 +6107,9 @@ sqlite3Select(Parse * pParse, /* The parser context */ * Open the cursor, execute the OP_Count, * close the cursor. */ - sql_emit_open_cursor(pParse, cursor, - space->def->id << 10, - space); + vdbe_emit_open_cursor(pParse, cursor, + space->def->id << 10, + space); +++ b/src/box/sql/sqliteInt.h @@ -3564,8 +3564,8 @@ void sqlite3EndTable(Parse *, Token *, Token *, Select *); * @retval address of last opcode. */ int -sql_emit_open_cursor(struct Parse *parse, int cursor, int index_id, - struct space *space); +vdbe_emit_open_cursor(struct Parse *parse, int cursor, int index_id, + struct space *space); >>> >>>> +} >>>> diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c >>>> index 2b59130..de4e0c1 100644 >>>> --- a/src/box/sql/delete.c >>>> +++ b/src/box/sql/delete.c >>>> @@ -184,7 +184,7 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, >>>> memset(&nc, 0, sizeof(nc)); >>>> nc.pParse = parse; >>>> if (tab_list->a[0].pTab == NULL) { >>>> - struct Table *t = malloc(sizeof(struct Table)); >>>> + struct Table *t = calloc(sizeof(struct Table), 1); >>> >>> 4. It must the part of the previous patch. >> Refactored this way: >> +++ b/src/box/sql/delete.c >> @@ -104,17 +104,28 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, >> strlen(tab_name)); >> if (space_id == BOX_ID_NIL) >> goto delete_from_cleanup; >> + /* >> + * In this case space has been created via Lua >> + * facilities, so there is no corresponding entry >> + * in table hash. Thus, lets create simple >> + * wrapper around space_def to support interface. >> + */ >> + space = space_by_id(space_id); >> + tab_list->a[0].pTab = sql_table_construct_from_space(space); >> + if (tab_list->a[0].pTab == NULL) >> + goto delete_from_cleanup; > > 2. As I proposed in the review, why can not we use stack struct Table here? > Just declare it at the beginning of the function and here save its pointer. Well, OK it is possible: +++ b/src/box/sql/delete.c @@ -111,9 +111,12 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list, * wrapper around space_def to support interface. */ space = space_by_id(space_id); - tab_list->a[0].pTab = sql_table_construct_from_space(space); - if (tab_list->a[0].pTab == NULL) - goto delete_from_cleanup; + struct Table tmp_tab; + memset(&tmp_tab, 0, sizeof(tmp_tab)); + tmp_tab.def = space->def; + /* Prevent from freeing memory in DeleteTable. */ + tmp_tab.nTabRef = 2; + tab_list->a[0].pTab = &tmp_tab; -struct Table * -sql_table_construct_from_space(const struct space *space) -{ - assert(space != NULL); - struct Table *table = calloc(1, sizeof(*table)); - if (table == NULL) { - diag_set(OutOfMemory, sizeof(table), "calloc", "table"); - return NULL; - } - table->def = space_def_dup(space->def); - if (table->def == NULL) - return NULL; - return table; -} - - -/** - * Create wrapper around space_def of the given space. - * This routine is required to support original SQLite interface, - * which accepts struct Table and struct Index DD arguments. - * Both table and space def are allocated on heap. - * - * @param space Space to be prototype. - * @retval New instance of struct Table allocated on malloc, - * or NULL in case of OOM. - */ -struct Table * -sql_table_construct_from_space(const struct space *space); - > > >> @@ -107,32 +107,22 @@ sqlite3IndexAffinityStr(sqlite3 *db, Index *index) >> char * >> sql_index_affinity_str(struct sqlite3 * db, struct index_def *def) >> { >> - char *aff; >> - /* The first time a column affinity string for a particular index is >> - * required, it is allocated and populated here. It is then stored as >> - * a member of the Index structure for subsequent use. >> - * >> - * The column affinity string will eventually be deleted by >> - * sqliteDeleteIndex() when the Index structure itself is cleaned >> - * up. >> - */ >> - int nColumn = def->key_def->part_count; >> - aff = (char *)sqlite3DbMallocRaw(0, nColumn + 1); >> + uint32_t column_count = def->key_def->part_count; >> + char *aff = (char *)sqlite3DbMallocRaw(0, column_count + 1); >> if (aff == NULL) { >> sqlite3OomFault(db); >> - return 0; >> + return NULL; >> } > > 3. Why not just pass db to sqlite3DbMallocRaw? It does OomFault for us. Ok: @@ -108,11 +108,9 @@ char * sql_index_affinity_str(struct sqlite3 *db, struct index_def *def) { uint32_t column_count = def->key_def->part_count; - char *aff = (char *)sqlite3DbMallocRaw(0, column_count + 1); - if (aff == NULL) { - sqlite3OomFault(db); + char *aff = (char *)sqlite3DbMallocRaw(db, column_count + 1); + if (aff == NULL) return NULL; - } >> 11 files changed, 256 insertions(+), 253 deletions(-) >>> diff --git a/src/box/sql/resolve.c b/src/box/sql/resolve.c >> index 23e16189a..e7d9723fa 100644 >> --- a/src/box/sql/resolve.c >> +++ b/src/box/sql/resolve.c >> @@ -39,6 +39,9 @@ >> #include <stdlib.h> >> #include <string.h> >> +#include "box/box.h" >> +#include "box/schema.h" > > 4. Why do you need these headers? Looks like I forgot to remove them. Anyway, in your fixes you removed them. Thx. >> */ >> static int >> -sql_where_shortcut(struct WhereLoopBuilder *builder) >> +where_assign_loop_terms(struct WhereLoop *loop, struct WhereClause *where, >> + int cursor, struct space_def *space_def, >> + struct index_def *idx_def) > > 5. Why WhereClause new method has prefix 'sql_where_', but WhereLoop method has prefix > 'where_'? Lets make it 'where_clause_find_term' and 'where_loop_assign_terms’. -sql_where_find_term(struct WhereClause *where_clause, int cursor, int column, - Bitmask is_ready, u32 op, struct space_def *space_def, - struct key_def *key_def) +where_clase_find_term(struct WhereClause *where_clause, int cursor, int column, + Bitmask is_ready, u32 op, struct space_def *space_def, + struct key_def *key_def) @@ -4133,7 +4133,7 @@ wherePathSolver(WhereInfo * pWInfo, LogEst nRowEst) * @retval 0 on success, -1 otherwise. */ static int -where_assign_loop_terms(struct WhereLoop *loop, struct WhereClause *where, +where_loop_assign_terms(struct WhereLoop *loop, struct WhereClause *where, int cursor, struct space_def *space_def, struct index_def *idx_def) @@ -4144,9 +4144,9 @@ where_assign_loop_terms(struct WhereLoop *loop, struct WhereClause *where, uint32_t i; for (i = 0; i < column_count; ++i) { struct WhereTerm *term = - sql_where_find_term(where, cursor, i, 0, WO_EQ, - space_def, idx_def != NULL ? - idx_def->key_def : NULL); + where_clause_find_term(where, cursor, i, 0, WO_EQ, + space_def, idx_def != NULL ? + idx_def->key_def : NULL); @@ -4178,7 +4178,7 @@ where_assign_loop_terms(struct WhereLoop *loop, struct WhereClause *where, * if this query needs the general-purpose query planner. */ static int -sql_where_shortcut(struct WhereLoopBuilder *builder) +where_loop_builder_shortcut(struct WhereLoopBuilder *builder) { struct WhereInfo *where_info = builder->pWInfo; if (where_info->wctrlFlags & WHERE_OR_SUBCLAUSE) @@ -4214,7 +4214,7 @@ sql_where_shortcut(struct WhereLoopBuilder *builder) space->index[i]->def; if (!idx_def->opts.is_unique) continue; - if (where_assign_loop_terms(loop, clause, + if (where_loop_assign_terms(loop, clause, cursor, space_def, idx_def) == 0) break; @@ -4222,7 +4222,7 @@ sql_where_shortcut(struct WhereLoopBuilder *builder) } else { /* Space is ephemeral. */ assert(space_def->id == 0); - where_assign_loop_terms(loop, clause, cursor, + where_loop_assign_terms(loop, clause, cursor, space_def, NULL); @@ -4537,7 +4537,7 @@ sqlite3WhereBegin(Parse * pParse, /* The parser context */ } #endif - if (nTabList != 1 || sql_where_shortcut(&sWLB) == 0) { + if (nTabList != 1 || where_loop_builder_shortcut(&sWLB) == 0) { > >> +/** >> + * Most queries use only a single table (they are not joins) and >> + * have simple == constraints against indexed fields. This >> + * routine attempts to plan those simple cases using much less >> + * ceremony than the general-purpose query planner, and thereby >> + * yield faster sqlite3_prepare() times for the common case. >> + * >> + * @param builder Where-Loop Builder. >> + * @retval Return non-zero on success, i.e. if this query can be >> + * handled by this no-frills query planner. Return zero >> + * if this query needs the general-purpose query planner. >> + */ >> +static int >> +sql_where_shortcut(struct WhereLoopBuilder *builder) > > 6. Same. For example, 'where_loop_builder_shortcut’. Fixed. See code above.
next prev parent reply other threads:[~2018-06-18 12:29 UTC|newest] Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-06-01 15:16 [tarantool-patches] [PATCH 0/3] " Kirill Yukhin 2018-06-01 15:16 ` [tarantool-patches] [PATCH 1/3] sql: fetch primary index for affinity only Kirill Yukhin 2018-06-01 18:00 ` [tarantool-patches] " Vladislav Shpilevoy 2018-06-07 12:03 ` Kirill Yukhin 2018-06-07 15:01 ` Vladislav Shpilevoy 2018-06-08 8:25 ` Kirill Yukhin 2018-06-01 15:16 ` [tarantool-patches] [PATCH 2/3] sql: remove expressions from SQL indexes Kirill Yukhin 2018-06-01 18:00 ` [tarantool-patches] " Vladislav Shpilevoy 2018-06-01 15:16 ` [tarantool-patches] [PATCH 3/3] sql: implement point where for DELETE stmts Kirill Yukhin 2018-06-01 18:00 ` [tarantool-patches] " Vladislav Shpilevoy 2018-06-18 2:11 ` n.pettik 2018-06-18 10:44 ` Vladislav Shpilevoy 2018-06-18 10:51 ` Vladislav Shpilevoy 2018-06-18 12:29 ` n.pettik [this message] 2018-06-18 12:40 ` Vladislav Shpilevoy 2018-06-18 14:00 ` n.pettik 2018-06-18 14:17 ` Vladislav Shpilevoy 2018-06-19 8:03 ` Kirill Yukhin 2018-06-14 12:41 ` [tarantool-patches] Re: [PATCH 0/3] " Kirill Yukhin
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=8E3011EE-AF57-4055-AE08-58DABDB1CC40@tarantool.org \ --to=korablev@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='[tarantool-patches] Re: [PATCH 3/3] sql: implement point where for DELETE stmts' \ /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