From f68c45d343da82902bb34dd90bc31d7ff4f51195 Mon Sep 17 00:00:00 2001 From: "stewart@mysql.com" <> Date: Thu, 6 Apr 2006 21:59:13 +1000 Subject: [PATCH 01/16] BUG#18843 valgrind: cond jump on uninit in Qmgr::execAPI_REGREQ --- ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp index 97ca3f44b3a..4859ca22221 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp @@ -25,7 +25,10 @@ void Ndbcntr::initData() { - + c_start.reset(); + cmasterNodeId = 0; + cnoStartNodes = 0; + cnoWaitrep = 0; // Records with constant sizes ndbBlocksRec = new NdbBlocksRec[ZSIZE_NDB_BLOCKS_REC]; }//Ndbcntr::initData() From add2732f78dc43e9f3a507af641b43526139767d Mon Sep 17 00:00:00 2001 From: "stewart@mysql.com" <> Date: Thu, 6 Apr 2006 21:59:20 +1000 Subject: [PATCH 02/16] BUG#18833 valgrind: Mismatched free()/delete/delete[] in SimBlockList --- ndb/src/kernel/SimBlockList.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ndb/src/kernel/SimBlockList.cpp b/ndb/src/kernel/SimBlockList.cpp index 6029fc7e225..271d515dc92 100644 --- a/ndb/src/kernel/SimBlockList.cpp +++ b/ndb/src/kernel/SimBlockList.cpp @@ -111,8 +111,12 @@ SimBlockList::unload(){ if(theList != 0){ for(int i = 0; i~SimulatedBlock(); free(theList[i]); +#else + delete(theList[i]); +#endif theList[i] = 0; } } From ac54aa2aee9557746ac902fab156b12b4f84a03c Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Wed, 12 Apr 2006 23:05:38 +0400 Subject: [PATCH 03/16] Fixed bug#14169: type of group_concat() result changed to blob if tmp_table was used In a simple queries a result of the GROUP_CONCAT() function was always of varchar type. But if length of GROUP_CONCAT() result is greater than 512 chars and temporary table is used during select then the result is converted to blob, due to policy to not to store fields longer than 512 chars in tmp table as varchar fields. In order to provide consistent behaviour, result of GROUP_CONCAT() now will always be converted to blob if it is longer than 512 chars. Item_func_group_concat::field_type() is modified accordingly. --- mysql-test/r/func_gconcat.result | 16 ++++++++++++++++ mysql-test/t/func_gconcat.test | 10 ++++++++++ sql/item_func.cc | 2 +- sql/item_sum.h | 7 +++++++ sql/sql_select.cc | 6 ++++-- sql/unireg.h | 1 + 6 files changed, 39 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 3cb8da7f63f..ef46d170bda 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -604,3 +604,19 @@ count(distinct (f1+1)) 1 3 drop table t1; +create table t1 (f1 int unsigned, f2 varchar(255)); +insert into t1 values (1,repeat('a',255)),(2,repeat('b',255)); +select f2,group_concat(f1) from t1 group by f2; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 t1 f2 f2 253 255 255 Y 0 0 8 +def group_concat(f1) 252 400 1 Y 128 0 63 +f2 group_concat(f1) +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2 +select f2,group_concat(f1) from t1 group by f2 order by 2; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 t1 f2 f2 253 255 255 Y 0 0 8 +def group_concat(f1) group_concat(f1) 252 400 1 Y 144 0 63 +f2 group_concat(f1) +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2 diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index f116aa6f164..1bb49a312b8 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -390,4 +390,14 @@ insert into t1 values(1),(2),(3); select f1, group_concat(f1+1) from t1 group by f1 with rollup; select count(distinct (f1+1)) from t1 group by f1 with rollup; drop table t1; + +# +# Bug#14169 type of group_concat() result changed to blob if tmp_table was used +# +create table t1 (f1 int unsigned, f2 varchar(255)); +insert into t1 values (1,repeat('a',255)),(2,repeat('b',255)); +--enable_metadata +select f2,group_concat(f1) from t1 group by f2; +select f2,group_concat(f1) from t1 group by f2 order by 2; +--disable_metadata # End of 4.1 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index d0d2eca7233..174a8c55d01 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -307,7 +307,7 @@ Field *Item_func::tmp_table_field(TABLE *t_arg) res= new Field_double(max_length, maybe_null, name, t_arg, decimals); break; case STRING_RESULT: - if (max_length > 255) + if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB) res= new Field_blob(max_length, maybe_null, name, t_arg, collation.collation); else res= new Field_string(max_length, maybe_null, name, t_arg, collation.collation); diff --git a/sql/item_sum.h b/sql/item_sum.h index c972240fcba..0cc2a20faa3 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -729,6 +729,13 @@ class Item_func_group_concat : public Item_sum enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} const char *func_name() const { return "group_concat"; } virtual Item_result result_type () const { return STRING_RESULT; } + enum_field_types field_type() const + { + if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB) + return FIELD_TYPE_BLOB; + else + return MYSQL_TYPE_VAR_STRING; + } void clear(); bool add(); void reset_field(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d7aa617cffd..91fc808058f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4925,7 +4925,8 @@ static Field* create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, if ((type= item->field_type()) == MYSQL_TYPE_DATETIME || type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE) new_field= item->tmp_table_field_from_field_type(table); - else if (item->max_length/item->collation.collation->mbmaxlen > 255) + else if (item->max_length/item->collation.collation->mbmaxlen > + CONVERT_IF_BIGGER_TO_BLOB) { if (convert_blob_length) new_field= new Field_varstring(convert_blob_length, maybe_null, @@ -5028,7 +5029,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, return new Field_longlong(item_sum->max_length,maybe_null, item->name,table,item->unsigned_flag); case STRING_RESULT: - if (item_sum->max_length > 255) + if (item_sum->max_length/item_sum->collation.collation->mbmaxlen > + CONVERT_IF_BIGGER_TO_BLOB) { if (convert_blob_length) return new Field_varstring(convert_blob_length, maybe_null, diff --git a/sql/unireg.h b/sql/unireg.h index 70df9a89c8f..3fb30315c81 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -60,6 +60,7 @@ #define MAX_MBWIDTH 3 /* Max multibyte sequence */ #define MAX_FIELD_CHARLENGTH 255 +#define CONVERT_IF_BIGGER_TO_BLOB 255 /* Max column width +1 */ #define MAX_FIELD_WIDTH (MAX_FIELD_CHARLENGTH*MAX_MBWIDTH+1) From 3ca1ec8fdc63af5de5a7ff85be730ecdca70d247 Mon Sep 17 00:00:00 2001 From: "mleich@mysql.com" <> Date: Thu, 13 Apr 2006 20:42:48 +0200 Subject: [PATCH 04/16] Fixes for Bug#12429: Replication tests fail: "Slave_IO_Running" (?) differs related to MySQL 4.1 and Bug#16920 rpl_deadlock_innodb fails in show slave status (reported for MySQL 5.1) - backport of several fixes done in MySQL 5.0 to 4.1 - fix for new discovered instability (see comment on Bug#12429 + Bug#16920) - reenabling of testcases --- mysql-test/r/rpl_deadlock.result | 105 ++++++++++++++++++++++++++-- mysql-test/r/rpl_relayrotate.result | 7 +- mysql-test/t/disabled.def | 3 - mysql-test/t/rpl_deadlock.test | 16 +++-- mysql-test/t/rpl_relayrotate.test | 8 +-- mysql-test/t/rpl_until.test | 4 ++ 6 files changed, 119 insertions(+), 24 deletions(-) diff --git a/mysql-test/r/rpl_deadlock.result b/mysql-test/r/rpl_deadlock.result index 8eb9d64fcae..db88cf73c03 100644 --- a/mysql-test/r/rpl_deadlock.result +++ b/mysql-test/r/rpl_deadlock.result @@ -44,8 +44,39 @@ select * from t2; a 22 show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 13110 # # master-bin.000001 Yes Yes 0 0 13110 # None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 13110 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 13110 +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # stop slave; change master to master_log_pos=401; begin; @@ -62,8 +93,39 @@ select * from t2; a 22 show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 13110 # # master-bin.000001 Yes Yes 0 0 13110 # None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 13110 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running # +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 13110 +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # set global max_relay_log_size=0; stop slave; change master to master_log_pos=401; @@ -82,6 +144,37 @@ select * from t2; a 22 show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 13110 # # master-bin.000001 Yes Yes 0 0 13110 # None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 13110 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running # +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 13110 +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # drop table t1,t2,t3,t4; diff --git a/mysql-test/r/rpl_relayrotate.result b/mysql-test/r/rpl_relayrotate.result index bf9bbbb9b93..20f19973d83 100644 --- a/mysql-test/r/rpl_relayrotate.result +++ b/mysql-test/r/rpl_relayrotate.result @@ -10,10 +10,7 @@ reset slave; start slave; stop slave; start slave; -select master_pos_wait('master-bin.001',3000)>=0; -master_pos_wait('master-bin.001',3000)>=0 -1 -select * from t1 where a=8000; -a +select max(a) from t1; +max(a) 8000 drop table t1; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 3eae8d230d8..9bfe9567d83 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -10,6 +10,3 @@ # ############################################################################## -rpl_relayrotate : Unstable test case, bug#12429 -rpl_until : Unstable test case, bug#12429 -rpl_deadlock : Unstable test case, bug#12429 diff --git a/mysql-test/t/rpl_deadlock.test b/mysql-test/t/rpl_deadlock.test index d3bc31addff..e8ba6d6faec 100644 --- a/mysql-test/t/rpl_deadlock.test +++ b/mysql-test/t/rpl_deadlock.test @@ -58,7 +58,7 @@ while ($1) enable_query_log; select * from t1 for update; start slave; ---sleep 3 # hope that slave is blocked now +--real_sleep 3 # hope that slave is blocked now insert into t2 values(22); # provoke deadlock, slave should be victim commit; sync_with_master; @@ -67,7 +67,9 @@ select * from t2; # check that no error is reported --replace_column 1 # 8 # 9 # 23 # 33 # --replace_result $MASTER_MYPORT MASTER_MYPORT +--vertical_results show slave status; +--horizontal_results # 2) Test lock wait timeout @@ -76,15 +78,17 @@ change master to master_log_pos=401; # the BEGIN log event begin; select * from t2 for update; # hold lock start slave; ---sleep 10 # slave should have blocked, and be retrying +--real_sleep 10 # slave should have blocked, and be retrying commit; sync_with_master; select * from t1; # check that slave succeeded finally select * from t2; # check that no error is reported ---replace_column 1 # 8 # 9 # 23 # 33 # +--replace_column 1 # 8 # 9 # 11 # 23 # 33 # --replace_result $MASTER_MYPORT MASTER_MYPORT +--vertical_results show slave status; +--horizontal_results # Now we repeat 2), but with BEGIN in the same relay log as # COMMIT (to see if seeking into hot log is ok). @@ -97,14 +101,16 @@ change master to master_log_pos=401; begin; select * from t2 for update; start slave; ---sleep 10 +--real_sleep 10 commit; sync_with_master; select * from t1; select * from t2; ---replace_column 1 # 8 # 9 # 23 # 33 # +--replace_column 1 # 8 # 9 # 11 # 23 # 33 # --replace_result $MASTER_MYPORT MASTER_MYPORT +--vertical_results show slave status; +--horizontal_results connection master; drop table t1,t2,t3,t4; diff --git a/mysql-test/t/rpl_relayrotate.test b/mysql-test/t/rpl_relayrotate.test index 1dab8bf4ed5..04f03367e20 100644 --- a/mysql-test/t/rpl_relayrotate.test +++ b/mysql-test/t/rpl_relayrotate.test @@ -52,11 +52,9 @@ start slave; # which proves that the transaction restarted at # the right place. # We must wait for the transaction to commit before -# reading, MASTER_POS_WAIT() will do it for sure -# (the only statement with position>=3000 is COMMIT). -select master_pos_wait('master-bin.001',3000)>=0; -select * from t1 where a=8000; - +# reading: +sync_with_master; +select max(a) from t1; connection master; # The following DROP is a very important cleaning task: diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test index 57ebc67db1d..990f00fdc63 100644 --- a/mysql-test/t/rpl_until.test +++ b/mysql-test/t/rpl_until.test @@ -26,6 +26,7 @@ show binlog events; connection slave; start slave until master_log_file='master-bin.000001', master_log_pos=244; sleep 2; +wait_for_slave_to_stop; # here table should be still not deleted select * from t1; --replace_result $MASTER_MYPORT MASTER_MYPORT @@ -37,6 +38,7 @@ start slave until master_log_file='master-no-such-bin.000001', master_log_pos=29 # again this table should be still not deleted select * from t1; sleep 2; +wait_for_slave_to_stop; --replace_result $MASTER_MYPORT MASTER_MYPORT --replace_column 1 # 9 # 11 # 23 # 33 # show slave status; @@ -44,6 +46,7 @@ show slave status; # try replicate all until second insert to t2; start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=537; sleep 4; +wait_for_slave_to_stop; select * from t2; --replace_result $MASTER_MYPORT MASTER_MYPORT --replace_column 1 # 9 # 11 # 23 # 33 # @@ -61,6 +64,7 @@ stop slave; start slave until master_log_file='master-bin.000001', master_log_pos=561; # 2 is not enough when running with valgrind --real_sleep 4 +wait_for_slave_to_stop; # here the sql slave thread should be stopped --replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004 --replace_column 1 # 9 # 23 # 33 # From 950214abfcec209b1683b9f769172e5878be05c4 Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Tue, 18 Apr 2006 20:57:31 -0700 Subject: [PATCH 05/16] Fixed bug #19079. The bug caused a reported index corruption in the cases when key_cache_block_size was not a multiple of myisam_block_size, e.g. when key_cache_block_size=1536 while myisam_block_size=1024. --- mysql-test/r/key_cache.result | 42 +++++++++++++++++++++++++++++++++++ mysql-test/t/key_cache.test | 41 +++++++++++++++++++++++++++++++++- mysys/mf_keycache.c | 12 +++++----- 3 files changed, 89 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index 41aaa21eea3..15dc244693d 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -287,3 +287,45 @@ check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY); +SET GLOBAL key_cache_block_size=1536; +INSERT INTO t1 VALUES (1); +SELECT @@key_cache_block_size; +@@key_cache_block_size +1536 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int); +CREATE TABLE t2(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int); +SET GLOBAL key_cache_block_size=1536; +INSERT INTO t1 VALUES (1,0); +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +SELECT COUNT(*) FROM t1; +COUNT(*) +4181 +SELECT @@key_cache_block_size; +@@key_cache_block_size +1536 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1,t2; diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index 5d0f904a716..6e772a7a9ad 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -149,6 +149,7 @@ show status like 'key_blocks_used'; --replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED 1818 KEY_BLOCKS_UNUSED 1824 KEY_BLOCKS_UNUSED show status like 'key_blocks_unused'; + # Cleanup # We don't reset keycache2 as we want to ensure that mysqld will reset it set global keycache2.key_buffer_size=0; @@ -157,7 +158,7 @@ set global keycache2.key_buffer_size=0; set global keycache3.key_buffer_size=100; set global keycache3.key_buffer_size=0; -# Test case for buf 6447 +# Test case for bug 6447 create table t1 (mytext text, FULLTEXT (mytext)); insert t1 values ('aaabbb'); @@ -168,4 +169,42 @@ check table t1; drop table t1; +# +# Bug #19079: corrupted index when key_cache_block_size is not multiple of +# myisam_block_size + +CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY); +SET GLOBAL key_cache_block_size=1536; +INSERT INTO t1 VALUES (1); +SELECT @@key_cache_block_size; +CHECK TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int); +CREATE TABLE t2(a int NOT NULL AUTO_INCREMENT PRIMARY KEY, b int); +SET GLOBAL key_cache_block_size=1536; +INSERT INTO t1 VALUES (1,0); +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +INSERT INTO t2(b) SELECT b FROM t1; +INSERT INTO t1(b) SELECT b FROM t2; +SELECT COUNT(*) FROM t1; +SELECT @@key_cache_block_size; +CHECK TABLE t1; +DROP TABLE t1,t2; + # End of 4.1 tests diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index ca683f16415..88b5051c52b 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -1741,6 +1741,7 @@ byte *key_cache_read(KEY_CACHE *keycache, uint status; int page_st; + offset= (uint) (filepos & (keycache->key_cache_block_size-1)); /* Read data in key_cache_block_size increments */ do { @@ -1750,7 +1751,6 @@ byte *key_cache_read(KEY_CACHE *keycache, keycache_pthread_mutex_unlock(&keycache->cache_lock); goto no_key_cache; } - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); filepos-= offset; read_length= length; set_if_smaller(read_length, keycache->key_cache_block_size-offset); @@ -1826,6 +1826,7 @@ byte *key_cache_read(KEY_CACHE *keycache, #endif buff+= read_length; filepos+= read_length+offset; + offset= 0; } while ((length-= read_length)); DBUG_RETURN(start); @@ -1877,17 +1878,17 @@ int key_cache_insert(KEY_CACHE *keycache, uint read_length; int page_st; int error; + uint offset; + offset= (uint) (filepos & (keycache->key_cache_block_size-1)); do { - uint offset; keycache_pthread_mutex_lock(&keycache->cache_lock); if (!keycache->can_be_used) { keycache_pthread_mutex_unlock(&keycache->cache_lock); DBUG_RETURN(0); } - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); /* Read data into key cache from buff in key_cache_block_size incr. */ filepos-= offset; read_length= length; @@ -1945,6 +1946,7 @@ int key_cache_insert(KEY_CACHE *keycache, buff+= read_length; filepos+= read_length+offset; + offset= 0; } while ((length-= read_length)); } @@ -2011,17 +2013,17 @@ int key_cache_write(KEY_CACHE *keycache, /* Key cache is used */ uint read_length; int page_st; + uint offset; + offset= (uint) (filepos & (keycache->key_cache_block_size-1)); do { - uint offset; keycache_pthread_mutex_lock(&keycache->cache_lock); if (!keycache->can_be_used) { keycache_pthread_mutex_unlock(&keycache->cache_lock); goto no_key_cache; } - offset= (uint) (filepos & (keycache->key_cache_block_size-1)); /* Write data in key_cache_block_size increments */ filepos-= offset; read_length= length; From d7faf15ce5d86e1cabd2ad18b234a40bf9a58923 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Wed, 19 Apr 2006 16:23:35 +0200 Subject: [PATCH 06/16] Bug#19190 syntax error in mysql-test/mysql-test-run.sh script --- mysql-test/mysql-test-run.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index d7e976f9d49..e3a3e3334e4 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -631,7 +631,9 @@ fi [ -d $MYSQL_TEST_DIR/var/tmp ] || mkdir $MYSQL_TEST_DIR/var/tmp [ -d $MYSQL_TEST_DIR/var/run ] || mkdir $MYSQL_TEST_DIR/var/run [ -d $MYSQL_TEST_DIR/var/log ] || mkdir $MYSQL_TEST_DIR/var/log -if ! test -L $MYSQL_TEST_DIR/var/std_data_ln ; then + +# Use 'test', not '[' as the shell builtin might not have '-L +if test ! -L "$MYSQL_TEST_DIR/var/std_data_ln" ; then ln -s $MYSQL_TEST_DIR/std_data/ $MYSQL_TEST_DIR/var/std_data_ln fi From 806cd415292b0219100992ecf7a78e4423267936 Mon Sep 17 00:00:00 2001 From: "svoj@april.(none)" <> Date: Wed, 19 Apr 2006 22:54:25 +0500 Subject: [PATCH 07/16] Bug#18544 - LOCK TABLES timeout causes MyISAM table corruption After a locking error the open table(s) were not fully cleaned up for reuse. But they were put into the open table cache even before the lock was tried. The next statement reused the table(s) with a wrong lock type set up. This tricked MyISAM into believing that it don't need to update the table statistics. Hence CHECK TABLE reported a mismatch of record count and table size. Fortunately nothing worse has been detected yet. The effect of the test case was that the insert worked on a read locked table. (!) I added a new function that clears the lock type from all tables that were prepared for a lock. I call this function when a lock failes. No test case. One test would add 50 seconds to the test suite. Another test requires file mode modifications. I added a test script to the bug report. It contains three cases for failing locks. All could reproduce a table corruption. All are fixed by this patch. This bug was not lock timeout specific. --- sql/lock.cc | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/sql/lock.cc b/sql/lock.cc index fe59039dde3..ab4a81034ba 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -78,6 +78,7 @@ extern HASH open_cache; static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count, uint flags, TABLE **write_locked); +static void reset_lock_data(MYSQL_LOCK *sql_lock); static int lock_external(THD *thd, TABLE **table,uint count); static int unlock_external(THD *thd, TABLE **table,uint count); static void print_lock_error(int error); @@ -120,12 +121,16 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags) */ if (wait_if_global_read_lock(thd, 1, 1)) { + /* Clear the lock type of all lock data to avoid reusage. */ + reset_lock_data(sql_lock); my_free((gptr) sql_lock,MYF(0)); sql_lock=0; break; - } + } if (thd->version != refresh_version) { + /* Clear the lock type of all lock data to avoid reusage. */ + reset_lock_data(sql_lock); my_free((gptr) sql_lock,MYF(0)); goto retry; } @@ -134,6 +139,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags) thd->proc_info="System lock"; if (lock_external(thd, tables, count)) { + /* Clear the lock type of all lock data to avoid reusage. */ + reset_lock_data(sql_lock); my_free((gptr) sql_lock,MYF(0)); sql_lock=0; thd->proc_info=0; @@ -639,6 +646,9 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, if (table->db_stat & HA_READ_ONLY) { my_error(ER_OPEN_AS_READONLY,MYF(0),table->table_name); + /* Clear the lock type of the lock data that are stored already. */ + sql_lock->lock_count= locks - sql_lock->locks; + reset_lock_data(sql_lock); my_free((gptr) sql_lock,MYF(0)); DBUG_RETURN(0); } @@ -663,6 +673,48 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, } +/* + Reset lock type in lock data. + + SYNOPSIS + reset_lock_data() + sql_lock The MySQL lock. + + DESCRIPTION + + After a locking error we want to quit the locking of the table(s). + The test case in the bug report for Bug #18544 has the following + cases: 1. Locking error in lock_external() due to InnoDB timeout. + 2. Locking error in get_lock_data() due to missing write permission. + 3. Locking error in wait_if_global_read_lock() due to lock conflict. + + In all these cases we have already set the lock type into the lock + data of the open table(s). If the table(s) are in the open table + cache, they could be reused with the non-zero lock type set. This + could lead to ignoring a different lock type with the next lock. + + Clear the lock type of all lock data. This ensures that the next + lock request will set its lock type properly. + + RETURN + void +*/ + +static void reset_lock_data(MYSQL_LOCK *sql_lock) +{ + THR_LOCK_DATA **ldata; + THR_LOCK_DATA **ldata_end; + + for (ldata= sql_lock->locks, ldata_end= ldata + sql_lock->lock_count; + ldata < ldata_end; + ldata++) + { + /* Reset lock type. */ + (*ldata)->type= TL_UNLOCK; + } +} + + /***************************************************************************** Lock table based on the name. This is used when we need total access to a closed, not open table From 8b4eae6e4f2c0f8e546e36f9b287746392207842 Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Thu, 20 Apr 2006 00:27:43 +0400 Subject: [PATCH 08/16] func_gconcat.result: Corrected test case for the bug#14169 to make it pass in --ps-protocol mode. --- mysql-test/r/func_gconcat.result | 7 ------- 1 file changed, 7 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index ef46d170bda..bf3e566b7f7 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -613,10 +613,3 @@ def group_concat(f1) 252 400 1 Y 128 0 63 f2 group_concat(f1) aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2 -select f2,group_concat(f1) from t1 group by f2 order by 2; -Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def test t1 t1 f2 f2 253 255 255 Y 0 0 8 -def group_concat(f1) group_concat(f1) 252 400 1 Y 144 0 63 -f2 group_concat(f1) -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 -bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2 From 67458961cf5cf8d50ca9b2b694a84599809b46ec Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Wed, 19 Apr 2006 16:08:37 -0700 Subject: [PATCH 09/16] Temporarily commented out a query from the test case for bug 14169 to make it pass with --ps-protocol. --- mysql-test/r/func_gconcat.result | 1 + mysql-test/t/func_gconcat.test | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index bf3e566b7f7..2c79b8f8ab1 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -613,3 +613,4 @@ def group_concat(f1) 252 400 1 Y 128 0 63 f2 group_concat(f1) aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2 +drop table t1; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 1bb49a312b8..ed35c7534f6 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -398,6 +398,8 @@ create table t1 (f1 int unsigned, f2 varchar(255)); insert into t1 values (1,repeat('a',255)),(2,repeat('b',255)); --enable_metadata select f2,group_concat(f1) from t1 group by f2; -select f2,group_concat(f1) from t1 group by f2 order by 2; +# select f2,group_concat(f1) from t1 group by f2 order by 2; --disable_metadata +drop table t1; + # End of 4.1 tests From 692da273882f808a275153eab05b8f0d6cd8161c Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Thu, 20 Apr 2006 00:42:12 -0700 Subject: [PATCH 10/16] Post merge fix --- mysql-test/r/func_gconcat.result | 2 +- sql/item_func.cc | 5 +---- sql/item_sum.cc | 4 ++-- sql/item_sum.h | 4 ++-- sql/sql_select.cc | 19 ++++++------------- 5 files changed, 12 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 9ff41cc0b52..d8a539da3fe 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -616,7 +616,7 @@ insert into t1 values (1,repeat('a',255)),(2,repeat('b',255)); select f2,group_concat(f1) from t1 group by f2; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def test t1 t1 f2 f2 253 255 255 Y 0 0 8 -def group_concat(f1) 252 400 1 Y 128 0 63 +def group_concat(f1) 253 400 1 Y 128 0 63 f2 group_concat(f1) aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2 diff --git a/sql/item_func.cc b/sql/item_func.cc index 56409a329f1..4bdb62c6e7a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -380,10 +380,7 @@ Field *Item_func::tmp_table_field(TABLE *t_arg) res= new Field_double(max_length, maybe_null, name, t_arg, decimals); break; case STRING_RESULT: - if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB) - res= new Field_blob(max_length, maybe_null, name, t_arg, collation.collation); - else - res= new Field_string(max_length, maybe_null, name, t_arg, collation.collation); + res= make_string_field(t_arg); break; case DECIMAL_RESULT: res= new Field_new_decimal(my_decimal_precision_to_length(decimal_precision(), diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 8826144266e..962454e237e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -377,12 +377,12 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table, case INT_RESULT: return new Field_longlong(max_length,maybe_null,name,table,unsigned_flag); case STRING_RESULT: - if (max_length > 255 && convert_blob_length) + if (max_length/collation.collation->mbmaxlen > 255 && convert_blob_length) return new Field_varstring(convert_blob_length, maybe_null, name, table, collation.collation); return make_string_field(table); - case DECIMAL_RESULT: +case DECIMAL_RESULT: return new Field_new_decimal(max_length, maybe_null, name, table, decimals, unsigned_flag); case ROW_RESULT: diff --git a/sql/item_sum.h b/sql/item_sum.h index 77b6ac57e79..f4ff257aa4e 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1121,10 +1121,10 @@ public: virtual Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { - if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB) + if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB ) return FIELD_TYPE_BLOB; else - return MYSQL_TYPE_VAR_STRING; + return MYSQL_TYPE_VARCHAR; } void clear(); bool add(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5b796aeb4c1..0211539e784 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8245,20 +8245,13 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, if ((type= item->field_type()) == MYSQL_TYPE_DATETIME || type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE) new_field= item->tmp_table_field_from_field_type(table); - else if (item->max_length/item->collation.collation->mbmaxlen > - CONVERT_IF_BIGGER_TO_BLOB) - { - if (convert_blob_length) - new_field= new Field_varstring(convert_blob_length, maybe_null, - item->name, table, - item->collation.collation); - else - new_field= new Field_blob(item->max_length, maybe_null, item->name, - table, item->collation.collation); - } + else if (item->max_length/item->collation.collation->mbmaxlen > 255 && + convert_blob_length) + new_field= new Field_varstring(convert_blob_length, maybe_null, + item->name, table, + item->collation.collation); else - new_field= new Field_string(item->max_length, maybe_null, item->name, - table, item->collation.collation); + new_field= item->make_string_field(table); break; case DECIMAL_RESULT: new_field= new Field_new_decimal(item->max_length, maybe_null, item->name, From 4b04ce8085a9f106cfd43ac28727b3933a0b65fe Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Thu, 20 Apr 2006 12:35:33 +0400 Subject: [PATCH 11/16] func_gconcat.test: Clean up test case for bug#14169 --- mysql-test/t/func_gconcat.test | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index ed35c7534f6..8f50690dd8b 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -398,7 +398,6 @@ create table t1 (f1 int unsigned, f2 varchar(255)); insert into t1 values (1,repeat('a',255)),(2,repeat('b',255)); --enable_metadata select f2,group_concat(f1) from t1 group by f2; -# select f2,group_concat(f1) from t1 group by f2 order by 2; --disable_metadata drop table t1; From e347ec5cbef37d0b1a858404e22251d431f9e9a2 Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Thu, 20 Apr 2006 13:34:14 +0400 Subject: [PATCH 12/16] func_gconcat.result, func_gconcat.test: Remove duplicate test case for bug#14169 --- mysql-test/r/func_gconcat.result | 10 ---------- mysql-test/t/func_gconcat.test | 11 ----------- 2 files changed, 21 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index d8a539da3fe..7889f8953f4 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -611,16 +611,6 @@ count(distinct (f1+1)) 1 3 drop table t1; -create table t1 (f1 int unsigned, f2 varchar(255)); -insert into t1 values (1,repeat('a',255)),(2,repeat('b',255)); -select f2,group_concat(f1) from t1 group by f2; -Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def test t1 t1 f2 f2 253 255 255 Y 0 0 8 -def group_concat(f1) 253 400 1 Y 128 0 63 -f2 group_concat(f1) -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 -bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2 -drop table t1; set names latin1; create table t1 (a char, b char); insert into t1 values ('a', 'a'), ('a', 'b'), ('b', 'a'), ('b', 'b'); diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 5f4c199ae95..e2cc3f24d7a 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -398,17 +398,6 @@ select f1, group_concat(f1+1) from t1 group by f1 with rollup; select count(distinct (f1+1)) from t1 group by f1 with rollup; drop table t1; -# -# Bug#14169 type of group_concat() result changed to blob if tmp_table was used -# -create table t1 (f1 int unsigned, f2 varchar(255)); -insert into t1 values (1,repeat('a',255)),(2,repeat('b',255)); ---enable_metadata -select f2,group_concat(f1) from t1 group by f2; -# select f2,group_concat(f1) from t1 group by f2 order by 2; ---disable_metadata -drop table t1; - # End of 4.1 tests # From 4cbad914ca5a4978e21e424f0c68cbb3185e0073 Mon Sep 17 00:00:00 2001 From: "mleich@mysql.com" <> Date: Thu, 20 Apr 2006 19:43:02 +0200 Subject: [PATCH 13/16] Post merge correction for the Changesset Fixes for Bug#12429: Replication tests fail: "Slave_IO_Running" (?) differs related to MySQL 4.1 and Bug#16920 rpl_deadlock_innodb fails in show slave status (reported for MySQL 5.1) --- mysql-test/r/rpl_deadlock.result | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/rpl_deadlock.result b/mysql-test/r/rpl_deadlock.result index 843a10ff433..541e12b806f 100644 --- a/mysql-test/r/rpl_deadlock.result +++ b/mysql-test/r/rpl_deadlock.result @@ -50,7 +50,7 @@ Master_User root Master_Port MASTER_MYPORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 13110 +Read_Master_Log_Pos 18911 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -65,7 +65,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 13110 +Exec_Master_Log_Pos 18911 Relay_Log_Space # Until_Condition None Until_Log_File @@ -99,7 +99,7 @@ Master_User root Master_Port MASTER_MYPORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 13110 +Read_Master_Log_Pos 18911 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -114,7 +114,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 13110 +Exec_Master_Log_Pos 18911 Relay_Log_Space # Until_Condition None Until_Log_File @@ -150,7 +150,7 @@ Master_User root Master_Port MASTER_MYPORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 13110 +Read_Master_Log_Pos 18911 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -165,7 +165,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 13110 +Exec_Master_Log_Pos 18911 Relay_Log_Space # Until_Condition None Until_Log_File From fc7514151f9daf5af9df7abd7abb61574bdebc80 Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Thu, 20 Apr 2006 22:15:38 -0700 Subject: [PATCH 14/16] Fixed bug #18767. The bug caused wrong result sets for union constructs of the form (SELECT ... ORDER BY order_list1 [LIMIT n]) ORDER BY order_list2. For such queries order lists were concatenated and limit clause was completely neglected. --- mysql-test/r/order_by.result | 32 ++++++++++++++++ mysql-test/t/order_by.test | 14 +++++++ sql/sql_lex.h | 1 + sql/sql_parse.cc | 74 +++++++++++++++++++++++++++--------- sql/sql_select.cc | 2 +- sql/sql_union.cc | 2 +- sql/sql_yacc.yy | 24 ++++++++++-- 7 files changed, 127 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index ee8ca5f0328..8126e223f55 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -788,3 +788,35 @@ a 2 2 DROP TABLE t1; +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10); +(SELECT b,a FROM t1 ORDER BY a,b) ORDER BY b,a; +b a +10 1 +10 2 +20 1 +20 2 +30 1 +30 2 +(SELECT b FROM t1 ORDER BY b DESC) ORDER BY b ASC; +b +10 +10 +20 +20 +30 +30 +(SELECT b,a FROM t1 ORDER BY b,a) ORDER BY a,b; +b a +10 1 +20 1 +30 1 +10 2 +20 2 +30 2 +(SELECT b,a FROM t1 ORDER by b,a LIMIT 3) ORDER by a,b; +b a +10 1 +20 1 +10 2 +DROP TABLE t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 4b7ec84dc54..1664afc70f9 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -545,4 +545,18 @@ SELECT a FROM t1 ORDER BY a; (SELECT a FROM t1) ORDER BY a; DROP TABLE t1; +# +# Bug #18767: global ORDER BY applied to a SELECT with ORDER BY either was +# ignored or 'concatened' to the latter. + +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10); + +(SELECT b,a FROM t1 ORDER BY a,b) ORDER BY b,a; +(SELECT b FROM t1 ORDER BY b DESC) ORDER BY b ASC; +(SELECT b,a FROM t1 ORDER BY b,a) ORDER BY a,b; +(SELECT b,a FROM t1 ORDER by b,a LIMIT 3) ORDER by a,b; + +DROP TABLE t1; + # End of 4.1 tests diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 47908ba8685..bd79a194122 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -400,6 +400,7 @@ public: bool check_updateable(char *db, char *table); void print(String *str); + bool add_fake_select_lex(THD *thd); ulong init_prepare_fake_select_lex(THD *thd); int change_result(select_subselect *result, select_subselect *old_result); inline bool is_prepared() { return prepared; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 21a335637b9..e25a428aaa7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4189,23 +4189,9 @@ mysql_new_select(LEX *lex, bool move_down) else { select_lex->include_neighbour(lex->current_select); - SELECT_LEX_UNIT *unit= select_lex->master_unit(); - SELECT_LEX *fake= unit->fake_select_lex; - if (!fake) - { - /* - as far as we included SELECT_LEX for UNION unit should have - fake SELECT_LEX for UNION processing - */ - if (!(fake= unit->fake_select_lex= new(lex->thd->mem_root) SELECT_LEX())) - return 1; - fake->include_standalone(unit, - (SELECT_LEX_NODE**)&unit->fake_select_lex); - fake->select_number= INT_MAX; - fake->make_empty_select(); - fake->linkage= GLOBAL_OPTIONS_TYPE; - fake->select_limit= HA_POS_ERROR; - } + if (!select_lex->master_unit()->fake_select_lex && + select_lex->master_unit()->add_fake_select_lex(lex->thd)) + return 1; } select_lex->master_unit()->global_parameters= select_lex; @@ -4975,6 +4961,60 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type) } +/* + Create a fake SELECT_LEX for a unit + + SYNOPSIS: + add_fake_select_lex() + thd thread handle + + DESCRIPTION + The method create a fake SELECT_LEX object for a unit. + This object is created for any union construct containing a union + operation and also for any single select union construct of the form + (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ... + or of the form + (SELECT ... ORDER BY LIMIT n) ORDER BY ... + + NOTES + The object is used to retrieve rows from the temporary table + where the result on the union is obtained. + + RETURN VALUES + 1 on failure to create the object + 0 on success +*/ + +bool st_select_lex_unit::add_fake_select_lex(THD *thd) +{ + SELECT_LEX *first_sl= first_select(); + DBUG_ENTER("add_fake_select_lex"); + DBUG_ASSERT(!fake_select_lex); + + if (!(fake_select_lex= new (thd->mem_root) SELECT_LEX())) + DBUG_RETURN(1); + fake_select_lex->include_standalone(this, + (SELECT_LEX_NODE**)&fake_select_lex); + fake_select_lex->select_number= INT_MAX; + fake_select_lex->make_empty_select(); + fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE; + fake_select_lex->select_limit= HA_POS_ERROR; + + if (!first_sl->next_select()) + { + /* + This works only for + (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m], + (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m] + just before the parser starts processing order_list + */ + global_parameters= fake_select_lex; + fake_select_lex->no_table_names_allowed= 1; + thd->lex->current_select= fake_select_lex; + } + DBUG_RETURN(0); +} + void add_join_on(TABLE_LIST *b,Item *expr) { if (expr) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 91fc808058f..46dba61cfc5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -171,7 +171,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) register SELECT_LEX *select_lex = &lex->select_lex; DBUG_ENTER("handle_select"); - if (select_lex->next_select()) + if (select_lex->next_select() || select_lex->master_unit()->fake_select_lex) res=mysql_union(thd, lex, result, &lex->unit); else res= mysql_select(thd, &select_lex->ref_pointer_array, diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 8bb53f7b573..0948602bbb4 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -184,7 +184,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, thd_arg->lex->current_select= sl= first_select= first_select_in_union(); found_rows_for_union= first_select->options & OPTION_FOUND_ROWS; - is_union= test(first_select->next_select()); + is_union= test(first_select->next_select() || fake_select_lex); /* Global option */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 05d95b57abb..162b4183c84 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3790,15 +3790,33 @@ order_clause: ORDER_SYM BY { LEX *lex=Lex; - if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE && - lex->current_select->olap != - UNSPECIFIED_OLAP_TYPE) + SELECT_LEX *sel= lex->current_select; + SELECT_LEX_UNIT *unit= sel-> master_unit(); + if (sel->linkage != GLOBAL_OPTIONS_TYPE && + sel->olap != UNSPECIFIED_OLAP_TYPE) { net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", "ORDER BY"); YYABORT; } + if (lex->sql_command != SQLCOM_ALTER_TABLE && !unit->fake_select_lex) + { + /* + A query of the of the form (SELECT ...) ORDER BY order_list is + executed in the same way as the query + SELECT ... ORDER BY order_list + unless the SELECT construct contains ORDER BY or LIMIT clauses. + Otherwise we create a fake SELECT_LEX if it has not been created + yet. + */ + SELECT_LEX *first_sl= unit->first_select(); + if (!first_sl->next_select() && + (first_sl->order_list.elements || + first_sl->select_limit != HA_POS_ERROR) && + unit->add_fake_select_lex(lex->thd)) + YYABORT; + } } order_list; order_list: From 639e8750329613363ac4b3c92b55d5e2db992568 Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Fri, 21 Apr 2006 08:19:38 -0700 Subject: [PATCH 15/16] Post merge fixes --- mysql-test/r/func_gconcat.result | 10 ++++++++++ sql/sql_parse.cc | 5 +++-- sql/sql_union.cc | 2 +- sql/sql_yacc.yy | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 7889f8953f4..d8a539da3fe 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -611,6 +611,16 @@ count(distinct (f1+1)) 1 3 drop table t1; +create table t1 (f1 int unsigned, f2 varchar(255)); +insert into t1 values (1,repeat('a',255)),(2,repeat('b',255)); +select f2,group_concat(f1) from t1 group by f2; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 t1 f2 f2 253 255 255 Y 0 0 8 +def group_concat(f1) 253 400 1 Y 128 0 63 +f2 group_concat(f1) +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 +bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2 +drop table t1; set names latin1; create table t1 (a char, b char); insert into t1 values ('a', 'a'), ('a', 'b'), ('b', 'a'), ('b', 'b'); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3752fc62d02..c58628cd856 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6355,17 +6355,18 @@ bool st_select_lex_unit::add_fake_select_lex(THD *thd) SELECT_LEX *first_sl= first_select(); DBUG_ENTER("add_fake_select_lex"); DBUG_ASSERT(!fake_select_lex); - + if (!(fake_select_lex= new (thd->mem_root) SELECT_LEX())) DBUG_RETURN(1); fake_select_lex->include_standalone(this, (SELECT_LEX_NODE**)&fake_select_lex); fake_select_lex->select_number= INT_MAX; + fake_select_lex->parent_lex= thd->lex; /* Used in init_query. */ fake_select_lex->make_empty_select(); fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE; fake_select_lex->select_limit= 0; - fake_select_lex->context.outer_context= first_sl->context.outer_context; + fake_select_lex->context.outer_context=first_sl->context.outer_context; /* allow item list resolving in fake select for ORDER BY */ fake_select_lex->context.resolve_in_select_list= TRUE; fake_select_lex->context.select_lex= fake_select_lex; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 68036f76e96..c5af81ae55a 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -202,7 +202,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, thd_arg->lex->current_select= sl= first_sl; found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS; - is_union= test(first_select->next_select() || fake_select_lex); + is_union= first_sl->next_select() || fake_select_lex; /* Global option */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a911ad41cd7..f3f0990c917 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5719,7 +5719,7 @@ order_clause: SELECT_LEX *first_sl= unit->first_select(); if (!first_sl->next_select() && (first_sl->order_list.elements || - first_sl->select_limit != HA_POS_ERROR) && + first_sl->select_limit) && unit->add_fake_select_lex(lex->thd)) YYABORT; } From 806564d75440f4f9bb22aae6320822733b21fcd3 Mon Sep 17 00:00:00 2001 From: "kent@mysql.com" <> Date: Fri, 21 Apr 2006 20:24:52 +0200 Subject: [PATCH 16/16] innodb_unsafe_binlog-master.opt: Make InnoDB option "loose", as the server might be started with this option just to find out the test is to be skipped in the configuration (bug#17359) --- mysql-test/t/innodb_unsafe_binlog-master.opt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/innodb_unsafe_binlog-master.opt b/mysql-test/t/innodb_unsafe_binlog-master.opt index 503c8457b2c..5c0136b5db3 100644 --- a/mysql-test/t/innodb_unsafe_binlog-master.opt +++ b/mysql-test/t/innodb_unsafe_binlog-master.opt @@ -1 +1 @@ ---innodb_locks_unsafe_for_binlog=true +--loose-innodb_locks_unsafe_for_binlog=true