diff options
-rw-r--r-- | mysql-test/r/func_gconcat.result | 10 | ||||
-rw-r--r-- | mysql-test/r/key_cache.result | 42 | ||||
-rw-r--r-- | mysql-test/t/func_gconcat.test | 12 | ||||
-rw-r--r-- | mysql-test/t/key_cache.test | 41 | ||||
-rw-r--r-- | mysys/mf_keycache.c | 12 | ||||
-rw-r--r-- | ndb/src/kernel/SimBlockList.cpp | 4 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp | 5 | ||||
-rw-r--r-- | sql/item_func.cc | 5 | ||||
-rw-r--r-- | sql/item_sum.h | 2 | ||||
-rw-r--r-- | sql/lock.cc | 56 | ||||
-rw-r--r-- | sql/sql_select.cc | 19 |
11 files changed, 191 insertions, 17 deletions
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 7889f8953f4..9ff41cc0b52 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) 252 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/r/key_cache.result b/mysql-test/r/key_cache.result index de9a2b2c003..99f5277f817 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -289,6 +289,48 @@ 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; set @@global.key_buffer_size=0; Warnings: Warning 1438 Cannot drop default keycache diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index aa28c9d5f52..5f4c199ae95 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -397,6 +397,18 @@ 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 +drop table t1; + # End of 4.1 tests # diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index df584021af1..4001e0df4af 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'); @@ -169,6 +170,44 @@ 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; + +# # Bug#10473 - Can't set 'key_buffer_size' system variable to ZERO # (One cannot drop the default key cache.) # diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 3b5e277b56d..11e27bb19ad 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -1805,6 +1805,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 { @@ -1814,7 +1815,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); @@ -1890,6 +1890,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); @@ -1941,17 +1942,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; @@ -2009,6 +2010,7 @@ int key_cache_insert(KEY_CACHE *keycache, buff+= read_length; filepos+= read_length+offset; + offset= 0; } while ((length-= read_length)); } @@ -2075,17 +2077,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; 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<noOfBlocks; i++){ if(theList[i] != 0){ +#ifdef VM_TRACE theList[i]->~SimulatedBlock(); free(theList[i]); +#else + delete(theList[i]); +#endif theList[i] = 0; } } diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp index 564501526a8..08251348b2b 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() diff --git a/sql/item_func.cc b/sql/item_func.cc index 4bdb62c6e7a..56409a329f1 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -380,7 +380,10 @@ 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: - res= make_string_field(t_arg); + 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); break; case DECIMAL_RESULT: res= new Field_new_decimal(my_decimal_precision_to_length(decimal_precision(), diff --git a/sql/item_sum.h b/sql/item_sum.h index 328f8dd8400..77b6ac57e79 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1124,7 +1124,7 @@ public: if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB) return FIELD_TYPE_BLOB; else - return MYSQL_TYPE_VARCHAR; + return MYSQL_TYPE_VAR_STRING; } void clear(); bool add(); diff --git a/sql/lock.cc b/sql/lock.cc index a584b063a0b..8ea13b2117c 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, const char *); @@ -135,12 +136,16 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, */ 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; } @@ -149,6 +154,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, 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; break; @@ -699,7 +706,10 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, *write_lock_used=table; if (table->db_stat & HA_READ_ONLY) { - my_error(ER_OPEN_AS_READONLY, MYF(0), table->alias); + my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias); + /* 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); } @@ -724,6 +734,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 diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0211539e784..5b796aeb4c1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8245,13 +8245,20 @@ 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 && - convert_blob_length) - new_field= new Field_varstring(convert_blob_length, maybe_null, - item->name, table, - item->collation.collation); + 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 - new_field= item->make_string_field(table); + new_field= new Field_string(item->max_length, maybe_null, item->name, + table, item->collation.collation); break; case DECIMAL_RESULT: new_field= new Field_new_decimal(item->max_length, maybe_null, item->name, |