Tarantool development patches archive
 help / color / mirror / Atom feed
From: imeevma@tarantool.org
To: v.shpilevoy@tarantool.org, tarantool-patches@freelists.org
Subject: [tarantool-patches] [PATCH v1 1/1] sql: do not analyze incorrect statistics
Date: Sat, 15 Dec 2018 16:39:05 +0300	[thread overview]
Message-ID: <5bcf80f0f9675871a39fb14cff5f216af7857759.1544880511.git.imeevma@gmail.com> (raw)

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(
         -- </analyze-4.2>
     })
 
+--
+-- 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;
+    ]], {
+        -- <analyze-4.3>
+        -- </analyze-4.3>
+    })
+
+test:do_execsql_test(
+    "analyze-4.4",
+    [[
+        INSERT INTO "_sql_stat4" VALUES('abc', 'bca', 'cab', 'acb', 'bac', 'cba');
+        ANALYZE t4;
+    ]], {
+        -- <analyze-4.4>
+        -- </analyze-4.4>
+    })
 
 
 -- Verify that DROP TABLE and DROP INDEX remove entries from the 
-- 
2.7.4

             reply	other threads:[~2018-12-15 13:39 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-15 13:39 imeevma [this message]
2018-12-17 17:35 ` [tarantool-patches] " n.pettik

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=5bcf80f0f9675871a39fb14cff5f216af7857759.1544880511.git.imeevma@gmail.com \
    --to=imeevma@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [tarantool-patches] [PATCH v1 1/1] sql: do not analyze incorrect statistics' \
    /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