From 6b205f93b00e1ede922c680252d64d97a195c343 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Aug 2007 03:50:19 +0500 Subject: [PATCH 1/3] BUG#27040 - Incorrect FTS parser name output When a table uses two (or more) fulltext keys with different fulltext parsers, all fulltext keys (excluding those that use built-in parser) were using first parser that was mentioned in .frm. With this fix fulltext keys use proper (assigned during create table) fulltext parser. This code was contributed by Yoshinori Matsunobu ymatsunobu@mysql.com on 2007-03-12 The copyright was assigned and transferred under the terms of the MySQL Contributor License Agreement. sql/table.cc: Shift extra data segment buffer pointer by parser name length to restore next key parser name correctly. --- sql/table.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/table.cc b/sql/table.cc index e6f9b1086c7..1e8a37faaa6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -918,6 +918,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } parser_name.str= (char*) next_chunk; parser_name.length= strlen((char*) next_chunk); + next_chunk+= parser_name.length + 1; keyinfo->parser= my_plugin_lock_by_name(NULL, &parser_name, MYSQL_FTPARSER_PLUGIN); if (! keyinfo->parser) From 7e9e0efd3ae2e1db7db4139097d3e6baaa888fe4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Aug 2007 14:00:35 -0700 Subject: [PATCH 2/3] Bug#30359 "Test federated_bug_25714 issues non-existing shell command" Problem caused by missing '$' symbol in eval statement causing it to always attempt to run test even if the test was not compiled. mysql-test/include/have_bug25714.inc: bug30359 missing '$' in eval statement --- mysql-test/include/have_bug25714.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/include/have_bug25714.inc b/mysql-test/include/have_bug25714.inc index 0c995cd0d4c..0c09ae1a035 100644 --- a/mysql-test/include/have_bug25714.inc +++ b/mysql-test/include/have_bug25714.inc @@ -3,5 +3,5 @@ # --require r/have_bug25714.require disable_query_log; -eval select LENGTH("MYSQL_BUG25714") > 0 as "have_bug25714_exe"; +eval select LENGTH("$MYSQL_BUG25714") > 0 as "have_bug25714_exe"; enable_query_log; From cf5762b40262ff7a74b3dba525e81ec0d9a8211b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Sep 2007 15:39:16 +0500 Subject: [PATCH 3/3] BUG#30590 - delete from memory table with composite btree primary key DELETE query against memory table with btree index may remove not all matching rows. This happens only when DELETE uses index read method to find matching rows. E.g. for queries like DELETE FROM t1 WHERE a=1. Fixed by reverting fix for BUG9719 and applying proper solution. heap/hp_delete.c: Reverted fix for BUG9719 as it makes queries like DELETE FROM t1 WHERE a=1 to remove not all matching rows (assuming this is memory table and there is btree key over `a`). This happens because we calculate info->lastkey_len in heap_rkey(). When we enter heap_rnext(), info->lastkey_len is 0 (set by hp_rb_delete_key()). We need to preserve info->lastkey_len in this situation, otherwise tree_search_key() will always return smallest value in a tree. heap/hp_rfirst.c: If we're performing index_first on a table that was taken from table cache, info->lastkey_len is initialized to previous query. Thus we set info->lastkey_len to proper value for subsequent heap_rnext() calls. This is needed for DELETE queries only, otherwise this variable is not used. Note that the same workaround may be needed for heap_rlast(), but for now heap_rlast() is never used for DELETE queries. heap/hp_rnext.c: An optimization for DELETE queries that use index_first()/index_next(). Use faster tree_search_edge() instead of tree_search_key(). mysql-test/r/heap_btree.result: A test case for BUG#30590. mysql-test/t/heap_btree.test: A test case for BUG#30590. --- heap/hp_delete.c | 3 --- heap/hp_rfirst.c | 11 +++++++++++ heap/hp_rnext.c | 29 +++++++++++++++++++++++++++++ mysql-test/r/heap_btree.result | 7 +++++++ mysql-test/t/heap_btree.test | 9 +++++++++ 5 files changed, 56 insertions(+), 3 deletions(-) diff --git a/heap/hp_delete.c b/heap/hp_delete.c index 266a9da6ca3..90e537081d3 100644 --- a/heap/hp_delete.c +++ b/heap/hp_delete.c @@ -73,10 +73,7 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, int res; if (flag) - { info->last_pos= NULL; /* For heap_rnext/heap_rprev */ - info->lastkey_len= 0; - } custom_arg.keyseg= keyinfo->seg; custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos); diff --git a/heap/hp_rfirst.c b/heap/hp_rfirst.c index 85548fea212..6e7ee45af5f 100644 --- a/heap/hp_rfirst.c +++ b/heap/hp_rfirst.c @@ -36,6 +36,17 @@ int heap_rfirst(HP_INFO *info, byte *record, int inx) sizeof(byte*)); info->current_ptr = pos; memcpy(record, pos, (size_t)share->reclength); + /* + If we're performing index_first on a table that was taken from + table cache, info->lastkey_len is initialized to previous query. + Thus we set info->lastkey_len to proper value for subsequent + heap_rnext() calls. + This is needed for DELETE queries only, otherwise this variable is + not used. + Note that the same workaround may be needed for heap_rlast(), but + for now heap_rlast() is never used for DELETE queries. + */ + info->lastkey_len= 0; info->update = HA_STATE_AKTIV; } else diff --git a/heap/hp_rnext.c b/heap/hp_rnext.c index a1bc480333e..513e184c743 100644 --- a/heap/hp_rnext.c +++ b/heap/hp_rnext.c @@ -34,11 +34,40 @@ int heap_rnext(HP_INFO *info, byte *record) heap_rb_param custom_arg; if (info->last_pos) + { + /* + We enter this branch for non-DELETE queries after heap_rkey() + or heap_rfirst(). As last key position (info->last_pos) is available, + we only need to climb the tree using tree_search_next(). + */ pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos, offsetof(TREE_ELEMENT, left), offsetof(TREE_ELEMENT, right)); + } + else if (!info->lastkey_len) + { + /* + We enter this branch only for DELETE queries after heap_rfirst(). E.g. + DELETE FROM t1 WHERE a<10. As last key position is not available + (last key is removed by heap_delete()), we must restart search as it + is done in heap_rfirst(). + + It should be safe to handle this situation without this branch. That is + branch below should find smallest element in a tree as lastkey_len is + zero. tree_search_edge() is a kind of optimisation here as it should be + faster than tree_search_key(). + */ + pos= tree_search_edge(&keyinfo->rb_tree, info->parents, + &info->last_pos, offsetof(TREE_ELEMENT, left)); + } else { + /* + We enter this branch only for DELETE queries after heap_rkey(). E.g. + DELETE FROM t1 WHERE a=10. As last key position is not available + (last key is removed by heap_delete()), we must restart search as it + is done in heap_rkey(). + */ custom_arg.keyseg = keyinfo->seg; custom_arg.key_length = info->lastkey_len; custom_arg.search_flag = SEARCH_SAME | SEARCH_FIND; diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result index 72be6a3e400..639fe1ff897 100644 --- a/mysql-test/r/heap_btree.result +++ b/mysql-test/r/heap_btree.result @@ -307,4 +307,11 @@ UNIQUE USING BTREE(c1) ) ENGINE= MEMORY DEFAULT CHARSET= utf8; INSERT INTO t1 VALUES('1'), ('2'); DROP TABLE t1; +CREATE TABLE t1 (a INT, KEY USING BTREE(a)) ENGINE=MEMORY; +INSERT INTO t1 VALUES(1),(2),(2); +DELETE FROM t1 WHERE a=2; +SELECT * FROM t1; +a +1 +DROP TABLE t1; End of 4.1 tests diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test index f8d6afbad04..849b7e12843 100644 --- a/mysql-test/t/heap_btree.test +++ b/mysql-test/t/heap_btree.test @@ -213,4 +213,13 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES('1'), ('2'); DROP TABLE t1; +# +# BUG#30590 - delete from memory table with composite btree primary key +# +CREATE TABLE t1 (a INT, KEY USING BTREE(a)) ENGINE=MEMORY; +INSERT INTO t1 VALUES(1),(2),(2); +DELETE FROM t1 WHERE a=2; +SELECT * FROM t1; +DROP TABLE t1; + --echo End of 4.1 tests