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 3020B220A9 for ; Sat, 15 Dec 2018 08:39:11 -0500 (EST) 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 bmC7WYFgU-sB for ; Sat, 15 Dec 2018 08:39:11 -0500 (EST) Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (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 A0651215C3 for ; Sat, 15 Dec 2018 08:39:10 -0500 (EST) From: imeevma@tarantool.org Subject: [tarantool-patches] [PATCH v1 1/1] sql: do not analyze incorrect statistics Date: Sat, 15 Dec 2018 16:39:05 +0300 Message-Id: <5bcf80f0f9675871a39fb14cff5f216af7857759.1544880511.git.imeevma@gmail.com> 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: v.shpilevoy@tarantool.org, tarantool-patches@freelists.org After this patch, the analysis of statistics in "_sql_stat1" and "_sql_stat4" with the wrong table name or table index will not be executed. Closes #3866 --- https://github.com/tarantool/tarantool/issues/3866 https://github.com/tarantool/tarantool/tree/imeevma/gh-3866-ignore-wrong-data-in-_sql_stat src/box/sql/analyze.c | 71 +++++++++++++++++++++--------------------- test/sql-tap/analyze1.test.lua | 27 +++++++++++++++- 2 files changed, 62 insertions(+), 36 deletions(-) diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c index 3f49280..9865407 100644 --- a/src/box/sql/analyze.c +++ b/src/box/sql/analyze.c @@ -1222,27 +1222,26 @@ analysis_loader(void *data, int argc, char **argv, char **unused) UNUSED_PARAMETER2(unused, argc); if (argv == 0 || argv[0] == 0 || argv[2] == 0) return 0; - struct analysis_index_info *info = (struct analysis_index_info *) data; - assert(info->stats != NULL); - struct index_stat *stat = &info->stats[info->index_count++]; struct space *space = space_by_name(argv[0]); if (space == NULL) - return -1; - struct index *index; + return 0; 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. */ - if (iid != BOX_ID_NIL) { - index = space_index(space, iid); - } else { + if (iid == BOX_ID_NIL) { if (sqlite3_stricmp(argv[0], argv[1]) != 0) - return -1; - index = space_index(space, 0); + return 0; + iid = 0; } - assert(index != NULL); + struct index *index = space_index(space, iid); + if (index == NULL) + return 0; + struct analysis_index_info *info = (struct analysis_index_info *) data; + assert(info->stats != NULL); + struct index_stat *stat = &info->stats[info->index_count++]; /* * Additional field is used to describe total * count of tuples in index. Although now all @@ -1395,16 +1394,18 @@ load_stat_from_space(struct sqlite3 *db, const char *sql_select_prepare, continue; uint32_t sample_count = sqlite3_column_int(stmt, 2); struct space *space = space_by_name(space_name); - assert(space != NULL); - struct index *index; + if (space == NULL) + continue; 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) - index = space_index(space, 0); - else - index = space_index(space, iid); - assert(index != NULL); + if (iid == BOX_ID_NIL) { + if (sqlite3_stricmp(space_name, index_name) != 0) + continue; + iid = 0; + } + struct index *index = space_index(space, iid); + if (index == NULL) + continue; uint32_t column_count = index->def->key_def->part_count; struct index_stat *stat = &stats[current_idx_count]; stat->sample_field_count = column_count; @@ -1463,18 +1464,18 @@ load_stat_from_space(struct sqlite3 *db, const char *sql_select_prepare, if (index_name == NULL) continue; struct space *space = space_by_name(space_name); - assert(space != NULL); - struct index *index; + if (space == NULL) + continue; 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); - } else { + if (iid == BOX_ID_NIL) { if (sqlite3_stricmp(space_name, index_name) != 0) - return -1; - index = space_index(space, 0); + continue; + iid = 0; } - assert(index != NULL); + struct index *index = space_index(space, iid); + if (index == NULL) + continue; uint32_t column_count = index->def->key_def->part_count; if (index != prev_index) { if (prev_index != NULL) { @@ -1544,18 +1545,18 @@ load_stat_to_index(struct sqlite3 *db, const char *sql_select_load, if (index_name == NULL) continue; struct space *space = space_by_name(space_name); - assert(space != NULL); - struct index *index; + if (space == NULL) + continue; 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); - } else { + if (iid == BOX_ID_NIL) { if (sqlite3_stricmp(space_name, index_name) != 0) - return -1; - index = space_index(space, 0); + continue; + iid = 0; } - assert(index != NULL); + struct index *index = space_index(space, iid); + if (index == NULL) + continue; free(index->def->opts.stat); index->def->opts.stat = stats[current_idx_count++]; } diff --git a/test/sql-tap/analyze1.test.lua b/test/sql-tap/analyze1.test.lua index ea414e9..df5aaf8 100755 --- a/test/sql-tap/analyze1.test.lua +++ b/test/sql-tap/analyze1.test.lua @@ -1,6 +1,6 @@ #!/usr/bin/env tarantool test = require("sqltester") -test:plan(38) +test:plan(40) --!./tcltestrunner.lua -- 2005 July 22 @@ -346,6 +346,31 @@ test:do_execsql_test( -- }) +-- +-- gh-3866 Wrong data in _sql_stat* tables leads to SEGMENTATION +-- FAULT +-- +test:do_execsql_test( + "analyze-4.3", + [[ + DELETE FROM "_sql_stat1"; + DELETE FROM "_sql_stat4"; + INSERT INTO "_sql_stat1" VALUES('abc', 'bca', 'cab'); + ANALYZE t4; + ]], { + -- + -- + }) + +test:do_execsql_test( + "analyze-4.4", + [[ + INSERT INTO "_sql_stat4" VALUES('abc', 'bca', 'cab', 'acb', 'bac', 'cba'); + ANALYZE t4; + ]], { + -- + -- + }) -- Verify that DROP TABLE and DROP INDEX remove entries from the -- 2.7.4