diff --git a/myisam/mi_test3.c b/myisam/mi_test3.c index dca04a9a64baf2d1d8bed4e1eb55867bd8f5923a..27d23317b5c7e60708752bef75bbdc1462a7787b 100644 --- a/myisam/mi_test3.c +++ b/myisam/mi_test3.c @@ -40,7 +40,7 @@ #endif -const char *filename= "test3.MSI"; +const char *filename= "test3"; uint tests=10,forks=10,key_cacheing=0,use_log=0; static void get_options(int argc, char *argv[]); @@ -363,7 +363,7 @@ int test_write(MI_INFO *file,int id,int lock_type) } sprintf(record.id,"%7d",getpid()); - strmov(record.text,"Testing..."); + strnmov(record.text,"Testing...", sizeof(record.text)); tries=(uint) rnd(100)+10; for (i=count=0 ; i < tries ; i++) diff --git a/myisam/mi_write.c b/myisam/mi_write.c index e059bbb569f2ca7517f04ae2f2f505c557ac322e..303e924118fed07c502f9f339013892c94b17b02 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -165,12 +165,7 @@ err: { uint j; for (j=0 ; j < share->base.keys ; j++) - { - if (is_tree_inited(&info->bulk_insert[j])) - { - reset_tree(&info->bulk_insert[j]); - } - } + mi_flush_bulk_insert(info, j); } info->errkey= (int) i; while ( i-- > 0) @@ -329,7 +324,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *temp_buff,*keypos; uchar keybuff[MI_MAX_KEY_BUFF]; my_bool was_last_key; - my_off_t next_page; + my_off_t next_page, dupp_key_pos; DBUG_ENTER("w_search"); DBUG_PRINT("enter",("page: %ld",page)); @@ -349,9 +344,9 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, /* get position to record with duplicated key */ tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,keybuff); if (tmp_key_length) - info->dupp_key_pos=_mi_dpos(info,0,keybuff+tmp_key_length); + dupp_key_pos=_mi_dpos(info,0,keybuff+tmp_key_length); else - info->dupp_key_pos= HA_OFFSET_ERROR; + dupp_key_pos= HA_OFFSET_ERROR; if (keyinfo->flag & HA_FULLTEXT) { uint off; @@ -370,7 +365,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, else { /* popular word. two-level tree. going down */ - my_off_t root=info->dupp_key_pos; + my_off_t root=dupp_key_pos; keyinfo=&info->s->ft2_keyinfo; get_key_full_length_rdonly(off, key); key+=off; @@ -389,6 +384,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, } else /* not HA_FULLTEXT, normal HA_NOSAME key */ { + info->dupp_key_pos= dupp_key_pos; my_afree((byte*) temp_buff); my_errno=HA_ERR_FOUND_DUPP_KEY; DBUG_RETURN(-1); diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 1951f68e82299952c9d0f19b1ac2ddbf8a14e0f0..a85cfd4181ce656afbbbcb442b655338936704f9 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -399,3 +399,9 @@ select count(*) from t1; count(*) 1 drop table t1; +create table t1 (a int primary key, b text, fulltext(b)); +create table t2 (a int, b text); +insert t1 values (1, "aaaa"), (2, "bbbb"); +insert t2 values (10, "aaaa"), (2, "cccc"); +replace t1 select * from t2; +drop table t1, t2; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 41fbf3f27ac092d868a181f0d0fac7272213e094..008e965297f83b5ecbc2eb658354107594e1986b 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -308,3 +308,16 @@ REPAIR TABLE t1; select count(*) from t1; drop table t1; +# +# bug#6784 +# mi_flush_bulk_insert (on dup key error in mi_write) +# was mangling info->dupp_key_pos +# + +create table t1 (a int primary key, b text, fulltext(b)); +create table t2 (a int, b text); +insert t1 values (1, "aaaa"), (2, "bbbb"); +insert t2 values (10, "aaaa"), (2, "cccc"); +replace t1 select * from t2; +drop table t1, t2; + diff --git a/ndb/src/common/logger/LogHandler.cpp b/ndb/src/common/logger/LogHandler.cpp index 4fab957fc504ecd693153e8676efc49c488f5b3e..a76cb622878452b55bbdc7762fd8d31f483a81f7 100644 --- a/ndb/src/common/logger/LogHandler.cpp +++ b/ndb/src/common/logger/LogHandler.cpp @@ -117,10 +117,9 @@ LogHandler::parseParams(const BaseString &_params) { _params.split(v_args, ","); for(size_t i=0; i < v_args.size(); i++) { Vector<BaseString> v_param_value; - - v_args[i].split(v_param_value, "=", 2); - if(v_param_value.size() == 2 && - !setParam(v_param_value[0], v_param_value[1])) + if(v_args[i].split(v_param_value, "=", 2) != 2) + ret = false; + else if (!setParam(v_param_value[0], v_param_value[1])) ret = false; } diff --git a/ndb/src/common/logger/Logger.cpp b/ndb/src/common/logger/Logger.cpp index 00a2fae67bcc2f87d305ab3b91fe6b039b9bd5b0..1dc3bd43716db5f94296cf458aba330ae18ee668 100644 --- a/ndb/src/common/logger/Logger.cpp +++ b/ndb/src/common/logger/Logger.cpp @@ -169,10 +169,13 @@ Logger::addHandler(const BaseString &logstring) { size_t i; Vector<BaseString> logdest; Vector<LogHandler *>loghandlers; + DBUG_ENTER("Logger::addHandler"); logstring.split(logdest, ";"); for(i = 0; i < logdest.size(); i++) { + DBUG_PRINT("info",("adding: %s",logdest[i])); + Vector<BaseString> v_type_args; logdest[i].split(v_type_args, ":", 2); @@ -191,16 +194,16 @@ Logger::addHandler(const BaseString &logstring) { handler = new ConsoleLogHandler(); if(handler == NULL) - return false; + DBUG_RETURN(false); if(!handler->parseParams(params)) - return false; + DBUG_RETURN(false); loghandlers.push_back(handler); } for(i = 0; i < loghandlers.size(); i++) addHandler(loghandlers[i]); - return true; /* @todo handle errors */ + DBUG_RETURN(true); /* @todo handle errors */ } bool diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 88e8f25b004681b222c0e1cff9ac4079625f8e3d..c106a6ddfac9a42a734622bad5c933a2f0e7d5ac 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -8573,13 +8573,11 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) /** * Used for scan take over */ - { - FragrecordPtr tFragPtr; - tFragPtr.i = fragptr.p->tableFragptr; - ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord); - scanptr.p->fragPtrI = fragptr.p->tableFragptr; - } - + FragrecordPtr tFragPtr; + tFragPtr.i = fragptr.p->tableFragptr; + ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord); + scanptr.p->fragPtrI = fragptr.p->tableFragptr; + /** * !idx uses 1 - (MAX_PARALLEL_SCANS_PER_FRAG - 1) = 1-11 * idx uses from MAX_PARALLEL_SCANS_PER_FRAG - MAX = 12-42) @@ -8587,11 +8585,11 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) Uint32 start = (idx ? MAX_PARALLEL_SCANS_PER_FRAG : 1 ); Uint32 stop = (idx ? MAX_PARALLEL_INDEX_SCANS_PER_FRAG : MAX_PARALLEL_SCANS_PER_FRAG - 1); stop += start; - Uint32 free = fragptr.p->m_scanNumberMask.find(start); - + Uint32 free = tFragPtr.p->m_scanNumberMask.find(start); + if(free == Fragrecord::ScanNumberMask::NotFound || free >= stop){ jam(); - + if(scanPrio == 0){ jam(); return ScanFragRef::ZTOO_MANY_ACTIVE_SCAN_ERROR; @@ -8607,10 +8605,9 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) return ZOK; } - scanptr.p->scanNumber = free; - fragptr.p->m_scanNumberMask.clear(free);// Update mask - + tFragPtr.p->m_scanNumberMask.clear(free);// Update mask + LocalDLList<ScanRecord> active(c_scanRecordPool, fragptr.p->m_activeScans); active.add(scanptr); if(scanptr.p->scanKeyinfoFlag){ @@ -8693,8 +8690,12 @@ void Dblqh::finishScanrec(Signal* signal) LocalDLList<ScanRecord> scans(c_scanRecordPool, fragptr.p->m_activeScans); scans.release(scanptr); + FragrecordPtr tFragPtr; + tFragPtr.i = scanptr.p->fragPtrI; + ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord); + const Uint32 scanNumber = scanptr.p->scanNumber; - ndbrequire(!fragptr.p->m_scanNumberMask.get(scanNumber)); + ndbrequire(!tFragPtr.p->m_scanNumberMask.get(scanNumber)); ScanRecordPtr restart; /** @@ -8702,13 +8703,13 @@ void Dblqh::finishScanrec(Signal* signal) */ if(scanNumber == NR_ScanNo || !queue.first(restart)){ jam(); - fragptr.p->m_scanNumberMask.set(scanNumber); + tFragPtr.p->m_scanNumberMask.set(scanNumber); return; } if(ERROR_INSERTED(5034)){ jam(); - fragptr.p->m_scanNumberMask.set(scanNumber); + tFragPtr.p->m_scanNumberMask.set(scanNumber); return; } diff --git a/ndb/src/mgmsrv/InitConfigFileParser.cpp b/ndb/src/mgmsrv/InitConfigFileParser.cpp index fdfe7823fc21782fc58bbd76b34caae457e18b6a..05102255eaa411cbbeb03af0578bd093c03b58a5 100644 --- a/ndb/src/mgmsrv/InitConfigFileParser.cpp +++ b/ndb/src/mgmsrv/InitConfigFileParser.cpp @@ -213,48 +213,41 @@ InitConfigFileParser::parseConfig(FILE * file) { // Parse Name-Value Pair //**************************************************************************** -bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { - - char tmpLine[MAX_LINE_LENGTH]; - char fname[MAX_LINE_LENGTH], rest[MAX_LINE_LENGTH]; - char* t; - const char *separator_list[]= {":", "=", 0}; - const char *separator= 0; - +bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) +{ if (ctx.m_currentSection == NULL){ ctx.reportError("Value specified outside section"); return false; } - strncpy(tmpLine, line, MAX_LINE_LENGTH); - // ************************************* - // Check if a separator exists in line + // Split string at first occurrence of + // '=' or ':' // ************************************* - for(int i= 0; separator_list[i] != 0; i++) { - if(strchr(tmpLine, separator_list[i][0])) { - separator= separator_list[i]; - break; - } - } - if (separator == 0) { + Vector<BaseString> tmp_string_split; + if (BaseString(line).split(tmp_string_split, + BaseString("=:"), + 2) != 2) + { ctx.reportError("Parse error"); return false; } - // ******************************************* - // Get pointer to substring before separator - // ******************************************* - t = strtok(tmpLine, separator); - - // ***************************************** - // Count number of tokens before separator - // ***************************************** - if (sscanf(t, "%120s%120s", fname, rest) != 1) { - ctx.reportError("Multiple names before \'%c\'", separator[0]); - return false; + // ************************************* + // Remove leading and trailing chars + // ************************************* + { + for (int i = 0; i < 2; i++) + tmp_string_split[i].trim("\r\n \t"); } + + // ************************************* + // First in split is fname + // ************************************* + + const char *fname= tmp_string_split[0].c_str(); + if (!ctx.m_currentInfo->contains(fname)) { ctx.reportError("[%s] Unknown parameter: %s", ctx.fname, fname); return false; @@ -273,24 +266,11 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { } } - // ****************************************** - // Get pointer to substring after separator - // ****************************************** - t = strtok(NULL, "\0"); - if (t == NULL) { - ctx.reportError("No value for parameter"); - return false; - } - - // ****************************************** - // Remove prefix and postfix spaces and tabs - // ******************************************* - trim(t); - // *********************** // Store name-value pair // *********************** - return storeNameValuePair(ctx, fname, t); + + return storeNameValuePair(ctx, fname, tmp_string_split[1].c_str()); } diff --git a/sql/item_func.cc b/sql/item_func.cc index 269bd38ffa6033038416472605bff4c4132e4860..01866a786a6c5861e707b443f88f1a9e5a5f78b8 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1684,18 +1684,21 @@ longlong Item_func_bit_count::val_int() udf_handler::~udf_handler() { - if (initialized) + if (!not_original) { - if (u_d->func_deinit != NULL) + if (initialized) { - void (*deinit)(UDF_INIT *) = (void (*)(UDF_INIT*)) - u_d->func_deinit; - (*deinit)(&initid); + if (u_d->func_deinit != NULL) + { + void (*deinit)(UDF_INIT *) = (void (*)(UDF_INIT*)) + u_d->func_deinit; + (*deinit)(&initid); + } + free_udf(u_d); } - free_udf(u_d); + if (buffers) // Because of bug in ecc + delete [] buffers; } - if (buffers) // Because of bug in ecc - delete [] buffers; } diff --git a/sql/item_sum.h b/sql/item_sum.h index 278695b57bbe403fffa52f37d60ddec90b5b347c..c1352f7ae7ddd6689fee54c75bd3cefce990227c 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -571,7 +571,7 @@ public: :Item_sum( list ), udf(udf_arg) { quick_group=0;} Item_udf_sum(THD *thd, Item_udf_sum *item) - :Item_sum(thd, item), udf(item->udf) {} + :Item_sum(thd, item), udf(item->udf) { udf.not_original= TRUE; } const char *func_name() const { return udf.name(); } bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { diff --git a/sql/sql_udf.h b/sql/sql_udf.h index 7b10b80f148b26d2305bf4c923cc2156b628fe41..d1f99a6d2329f45c6688f2dcc69c089bbf34d43f 100644 --- a/sql/sql_udf.h +++ b/sql/sql_udf.h @@ -56,8 +56,9 @@ class udf_handler :public Sql_alloc public: table_map used_tables_cache; bool const_item_cache; + bool not_original; udf_handler(udf_func *udf_arg) :u_d(udf_arg), buffers(0), error(0), - is_null(0), initialized(0) + is_null(0), initialized(0), not_original(0) {} ~udf_handler(); const char *name() const { return u_d ? u_d->name.str : "?"; } diff --git a/sql/table.cc b/sql/table.cc index 625f04846a8098fe675627ab255559606a7b43c8..63575f3032645031f01166ce3c78be20c6f8846f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -486,7 +486,26 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, /* old frm file */ field_type= (enum_field_types) f_packtype(pack_flag); - charset=f_is_binary(pack_flag) ? &my_charset_bin : outparam->table_charset; + if (f_is_binary(pack_flag)) + { + /* + Try to choose the best 4.1 type: + - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY" + try to find a binary collation for character set. + - for other types (e.g. BLOB) just use my_charset_bin. + */ + if (!f_is_blob(pack_flag)) + { + // 3.23 or 4.0 string + if (!(charset= get_charset_by_csname(outparam->table_charset->csname, + MY_CS_BINSORT, MYF(0)))) + charset= &my_charset_bin; + } + else + charset= &my_charset_bin; + } + else + charset= outparam->table_charset; bzero((char*) &comment, sizeof(comment)); } *field_ptr=reg_field=