From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org Cc: v.shpilevoy@tarantool.org, Kirill Shcherbatov <kshcherbatov@tarantool.org> Subject: [tarantool-patches] [PATCH v1 1/2] sql: get rid off sqlite3NestedParse in clean stats Date: Wed, 4 Jul 2018 20:17:54 +0300 [thread overview] Message-ID: <bd8d0b6358200f3c3656a4c365bfe0d484b09071.1530724375.git.kshcherbatov@tarantool.org> (raw) In-Reply-To: <cover.1530724375.git.kshcherbatov@tarantool.org> In-Reply-To: <cover.1530724375.git.kshcherbatov@tarantool.org> Now we manually generate AST structures to drop outdated stats from _sql_stat1 and _sql_stat4 spaces instead of starting sqlite3NestedParse. This function become totally useless and could be removed. Part of #3496. --- src/box/sql/analyze.c | 39 +++++++++++------------ src/box/sql/build.c | 82 ++++++++++++++++++++++++++++++++++++------------- src/box/sql/sqliteInt.h | 13 ++++++++ 3 files changed, 94 insertions(+), 40 deletions(-) diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c index 5f73f02..e08c151 100644 --- a/src/box/sql/analyze.c +++ b/src/box/sql/analyze.c @@ -116,7 +116,7 @@ #include "tarantoolInt.h" #include "vdbeInt.h" -/* +/** * This routine generates code that opens the sql_statN tables. * The _sql_stat1 table is always relevant. _sql_stat4 is only opened when * appropriate compile-time options are provided. @@ -127,21 +127,24 @@ * or it may be a NULL pointer. If it is not NULL, then all entries in * the sql_statN tables associated with the named table are deleted. * If zWhere==0, then code is generated to delete all stat table entries. + * + * @param parse Parsing context. + * @param stat_cursor Open the _sql_stat1 table on this cursor. + * @param index_name Delete records of this table if specified. + * @param table_name Delete records of this index if specified. */ static void -openStatTable(Parse * pParse, /* Parsing context */ - int iStatCur, /* Open the _sql_stat1 table on this cursor */ - const char *zWhere, /* Delete entries for this table or index */ - const char *zWhereType /* Either "tbl" or "idx" */ - ) +vdbe_stat_space_open(struct Parse *parse, int stat_cursor, + const char *index_name, const char *table_name) { const char *aTable[] = { "_sql_stat1", "_sql_stat4", NULL}; int i; - sqlite3 *db = pParse->db; - Vdbe *v = sqlite3GetVdbe(pParse); + struct sqlite3 *db = parse->db; + struct Vdbe *v = sqlite3GetVdbe(parse); + assert(v != NULL); int aRoot[ArraySize(aTable)]; u8 aCreateTbl[ArraySize(aTable)]; @@ -160,10 +163,9 @@ openStatTable(Parse * pParse, /* Parsing context */ assert(pStat != NULL); aRoot[i] = pStat->tnum; aCreateTbl[i] = 0; - if (zWhere) { - sqlite3NestedParse(pParse, - "DELETE FROM \"%s\" WHERE \"%s\"=%Q", - zTab, zWhereType, zWhere); + if (table_name != NULL || index_name != NULL) { + vdbe_stat_space_clear(parse, zTab, index_name, + table_name); } else { /* * The sql_stat[134] table already exists. @@ -178,7 +180,7 @@ openStatTable(Parse * pParse, /* Parsing context */ for (i = 0; aTable[i]; i++) { struct space *space = space_by_id(SQLITE_PAGENO_TO_SPACEID(aRoot[i])); - vdbe_emit_open_cursor(pParse, iStatCur + i, aRoot[i], space); + vdbe_emit_open_cursor(parse, stat_cursor + i, aRoot[i], space); sqlite3VdbeChangeP5(v, aCreateTbl[i]); VdbeComment((v, aTable[i])); } @@ -1117,7 +1119,7 @@ sql_analyze_database(Parse *parser) sql_set_multi_write(parser, false); int stat_cursor = parser->nTab; parser->nTab += 3; - openStatTable(parser, stat_cursor, NULL, NULL); + vdbe_stat_space_open(parser, stat_cursor, NULL, NULL); int reg = parser->nMem + 1; int tab_cursor = parser->nTab; for (struct HashElem *k = sqliteHashFirst(&schema->tblHash); k != NULL; @@ -1145,11 +1147,10 @@ analyzeTable(Parse * pParse, Table * pTab, Index * pOnlyIdx) sql_set_multi_write(pParse, false); iStatCur = pParse->nTab; pParse->nTab += 3; - if (pOnlyIdx) { - openStatTable(pParse, iStatCur, pOnlyIdx->zName, "idx"); - } else { - openStatTable(pParse, iStatCur, pTab->def->name, "tbl"); - } + if (pOnlyIdx != NULL) + vdbe_stat_space_open(pParse, iStatCur, pOnlyIdx->zName, NULL); + else + vdbe_stat_space_open(pParse, iStatCur, NULL, pTab->def->name); analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem + 1, pParse->nTab); loadAnalysis(pParse); diff --git a/src/box/sql/build.c b/src/box/sql/build.c index 0072f84..ac53906 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -2050,6 +2050,63 @@ sql_store_select(struct Parse *parse_context, struct Select *select) } /** + * Create expression record of with struct ID EQ STRING. + * + * @param parse The parsing context. + * @param col_type_name Name of column. + * @param col_name Name of row. + * @retval not NULL on success. + * @retval NULL on failure. + */ +static struct Expr * +sql_id_eq_str_expr(struct Parse *parse, const char *col_type_name, + const char *col_name) +{ + struct sqlite3 *db = parse->db; + + struct Expr *col_type_expr = + sqlite3Expr(db, TK_ID, col_type_name); + struct Expr *col_name_expr = + sqlite3Expr(db, TK_STRING, col_name); + struct Expr *col_eq_expr = + sqlite3PExpr(parse, TK_EQ, col_type_expr, col_name_expr); + if (col_type_expr == NULL || col_name_expr == NULL) { + sql_expr_delete(db, col_eq_expr, false); + col_eq_expr = NULL; + } + return col_eq_expr; +} + +void +vdbe_stat_space_clear(struct Parse *parse, const char *stat_table_name, + const char *idx_name, const char *table_name) +{ + assert(idx_name != NULL || table_name != NULL); + struct sqlite3 *db = parse->db; + assert(!db->mallocFailed); + struct SrcList *src_list = sql_alloc_src_list(db); + if (src_list != NULL) + src_list->a[0].zName = sqlite3DbStrDup(db, stat_table_name); + struct Expr *where = NULL; + if (idx_name != NULL) { + struct Expr *expr = sql_id_eq_str_expr(parse, "idx", idx_name); + if (expr != NULL) + where = sqlite3ExprAnd(db, expr, where); + } + if (table_name != NULL) { + struct Expr *expr = sql_id_eq_str_expr(parse, "tbl", table_name); + if (expr != NULL) + where = sqlite3ExprAnd(db, expr, where); + } + /** + * On memory allocation error + * sql_table delete_from releases memory + * for its own. + */ + sql_table_delete_from(parse, src_list, where); +} + +/** * Remove entries from the _sql_stat1 and _sql_stat4 * system spaces after a DROP INDEX or DROP TABLE command. * @@ -2062,27 +2119,10 @@ static void sql_clear_stat_spaces(Parse *parse, const char *table_name, const char *idx_name) { - if (idx_name != NULL) { - sqlite3NestedParse(parse, - "DELETE FROM \"_sql_stat1\" " - "WHERE (\"idx\"=%Q AND " - "\"tbl\"=%Q)", - idx_name, table_name); - sqlite3NestedParse(parse, - "DELETE FROM \"_sql_stat4\" " - "WHERE (\"idx\"=%Q AND " - "\"tbl\"=%Q)", - idx_name, table_name); - } else { - sqlite3NestedParse(parse, - "DELETE FROM \"_sql_stat1\" " - "WHERE \"tbl\"=%Q", - table_name); - sqlite3NestedParse(parse, - "DELETE FROM \"_sql_stat4\" " - "WHERE \"tbl\"=%Q", - table_name); - } + vdbe_stat_space_clear(parse, "_sql_stat4", idx_name, + table_name); + vdbe_stat_space_clear(parse, "_sql_stat1", idx_name, + table_name); } /** diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index 8b75ae8..a0a874c 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -4847,4 +4847,17 @@ vdbe_emit_halt_with_presence_test(struct Parse *parser, int space_id, const char *error_src, bool no_error, int cond_opcode); +/** + * Generate VDBE code to delete records from system _sql_stat1 or + * _sql_stat4 table. + * + * @param parse The parsing context. + * @param stat_table_name System stat table name. + * @param idx_name Index name. + * @param table_name Table name. + */ +void +vdbe_stat_space_clear(struct Parse *parse, const char *stat_table_name, + const char *idx_name, const char *table_name); + #endif /* SQLITEINT_H */ -- 2.7.4
next prev parent reply other threads:[~2018-07-04 17:18 UTC|newest] Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-07-04 17:17 [tarantool-patches] [PATCH v1 0/2] sql: get rid off sqlite3NestedParse Kirill Shcherbatov 2018-07-04 17:17 ` Kirill Shcherbatov [this message] 2018-07-05 16:11 ` [tarantool-patches] Re: [PATCH v1 1/2] sql: get rid off sqlite3NestedParse in clean stats Vladislav Shpilevoy 2018-07-06 18:13 ` Kirill Shcherbatov 2018-07-09 10:20 ` Vladislav Shpilevoy 2018-07-04 17:17 ` [tarantool-patches] [PATCH v1 2/2] sql: remove usless sqlite3NestedParse function Kirill Shcherbatov 2018-07-05 16:11 ` [tarantool-patches] " Vladislav Shpilevoy 2018-07-06 18:13 ` Kirill Shcherbatov 2018-07-09 10:20 ` [tarantool-patches] Re: [PATCH v1 0/2] sql: get rid off sqlite3NestedParse Vladislav Shpilevoy
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=bd8d0b6358200f3c3656a4c365bfe0d484b09071.1530724375.git.kshcherbatov@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [tarantool-patches] [PATCH v1 1/2] sql: get rid off sqlite3NestedParse in clean stats' \ /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