diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index eec0dcb90fe..8491d0df7b5 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -608,7 +608,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) { char *pos,buff[40]; ulong sec; - pos=strchr(status,' '); + pos= (char*) strchr(status,' '); *pos++=0; printf("%s\t\t\t",status); /* print label */ if ((status=str2int(pos,10,0,LONG_MAX,(long*) &sec))) diff --git a/innobase/configure.in b/innobase/configure.in index 652291f1f38..d83da9fdc5c 100644 --- a/innobase/configure.in +++ b/innobase/configure.in @@ -110,6 +110,9 @@ esac case "$target" in i[[4567]]86-*-*) CFLAGS="$CFLAGS -DUNIV_INTEL_X86";; + # The compiler on Linux/S390 does not seem to have inlining + s390-*-*) + CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";; esac AC_OUTPUT(Makefile os/Makefile ut/Makefile btr/Makefile dnl diff --git a/myisam/mi_test3.c b/myisam/mi_test3.c index dca04a9a64b..27d23317b5c 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 e059bbb569f..303e924118f 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/ctype_uca.result b/mysql-test/r/ctype_uca.result index 7620b18eea6..cb060ad7ee4 100644 --- a/mysql-test/r/ctype_uca.result +++ b/mysql-test/r/ctype_uca.result @@ -19,6 +19,9 @@ select 'a ' = 'a\t', 'a ' < 'a\t', 'a ' > 'a\t'; select 'a a' > 'a', 'a \t' < 'a'; 'a a' > 'a' 'a \t' < 'a' 1 1 +select 'c' like '\_' as want0; +want0 +0 CREATE TABLE t ( c char(20) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 945ec8eae99..599d49208e7 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -814,3 +814,6 @@ t2 CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t2; drop table t1; +select 'c' like '\_' as want0; +want0 +0 diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index cff43a821b3..7acc8a2d23f 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/ctype_uca.test b/mysql-test/t/ctype_uca.test index e640e6b53dc..11833ba9bc7 100644 --- a/mysql-test/t/ctype_uca.test +++ b/mysql-test/t/ctype_uca.test @@ -24,6 +24,11 @@ select 'a ' = 'a\t', 'a ' < 'a\t', 'a ' > 'a\t'; select 'a a' > 'a', 'a \t' < 'a'; +# +# Bug #6787 LIKE not working properly with _ and utf8 data +# +select 'c' like '\_' as want0; + # # Bug #5679 utf8_unicode_ci LIKE--trailing % doesn't equal zero characters # diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index c75b1dee63c..42031be8f3c 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -660,3 +660,9 @@ create table t2 select concat(a,_utf8'') as a, concat(b,_utf8'')as b from t1; show create table t2; drop table t2; drop table t1; + +# +# Bug #6787 LIKE not working properly with _ and utf8 data +# +select 'c' like '\_' as want0; + diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 41fbf3f27ac..008e965297f 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/include/Makefile.am b/ndb/include/Makefile.am index 7b3f80b5560..61f55cf9d61 100644 --- a/ndb/include/Makefile.am +++ b/ndb/include/Makefile.am @@ -29,13 +29,13 @@ ndbapi/ndberror.h mgmapiinclude_HEADERS = \ mgmapi/mgmapi.h \ -mgmapi/mgmapi_debug.h +mgmapi/mgmapi_debug.h \ +mgmapi/mgmapi_config_parameters.h \ +mgmapi/mgmapi_config_parameters_debug.h noinst_HEADERS = \ ndb_global.h \ -ndb_net.h \ -mgmapi/mgmapi_config_parameters.h \ -mgmapi/mgmapi_config_parameters_debug.h +ndb_net.h EXTRA_DIST = debugger editline kernel logger mgmcommon \ portlib transporter util diff --git a/ndb/src/common/logger/LogHandler.cpp b/ndb/src/common/logger/LogHandler.cpp index 4fab957fc50..a76cb622878 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 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 00a2fae67bc..1dc3bd43716 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 logdest; Vectorloghandlers; + DBUG_ENTER("Logger::addHandler"); logstring.split(logdest, ";"); for(i = 0; i < logdest.size(); i++) { + DBUG_PRINT("info",("adding: %s",logdest[i])); + Vector 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/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index 6c8c2bb2dae..0c63cb5fe17 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -550,6 +550,11 @@ public: UintR scanErrorCounter; UintR scanLocalFragid; UintR scanSchemaVersion; + + /** + * This is _always_ main table, even in range scan + * in which case scanTcrec->fragmentptr is different + */ Uint32 fragPtrI; UintR scanStoredProcId; ScanState scanState; diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 432bb1511aa..c106a6ddfac 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -7703,6 +7703,9 @@ void Dblqh::abort_scan(Signal* signal, Uint32 scan_ptr_i, Uint32 errcode){ jam(); scanptr.i = scan_ptr_i; c_scanRecordPool.getPtr(scanptr); + + fragptr.i = tcConnectptr.p->fragmentptr; + ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord); finishScanrec(signal); releaseScanrec(signal); tcConnectptr.p->transactionState = TcConnectionrec::IDLE; @@ -8574,7 +8577,7 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) 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) @@ -8583,10 +8586,10 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) Uint32 stop = (idx ? MAX_PARALLEL_INDEX_SCANS_PER_FRAG : MAX_PARALLEL_SCANS_PER_FRAG - 1); stop += 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; @@ -8597,16 +8600,15 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) */ scanptr.p->scanState = ScanRecord::IN_QUEUE; LocalDLFifoList queue(c_scanRecordPool, - tFragPtr.p->m_queuedScans); + fragptr.p->m_queuedScans); queue.add(scanptr); return ZOK; } - scanptr.p->scanNumber = free; tFragPtr.p->m_scanNumberMask.clear(free);// Update mask - - LocalDLList active(c_scanRecordPool, tFragPtr.p->m_activeScans); + + LocalDLList active(c_scanRecordPool, fragptr.p->m_activeScans); active.add(scanptr); if(scanptr.p->scanKeyinfoFlag){ jam(); @@ -8666,12 +8668,8 @@ void Dblqh::finishScanrec(Signal* signal) { release_acc_ptr_list(scanptr.p); - FragrecordPtr tFragPtr; - tFragPtr.i = scanptr.p->fragPtrI; - ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord); - LocalDLFifoList queue(c_scanRecordPool, - tFragPtr.p->m_queuedScans); + fragptr.p->m_queuedScans); if(scanptr.p->scanState == ScanRecord::IN_QUEUE){ jam(); @@ -8689,9 +8687,13 @@ void Dblqh::finishScanrec(Signal* signal) ndbrequire(tmp.p == scanptr.p); } - LocalDLList scans(c_scanRecordPool, tFragPtr.p->m_activeScans); + LocalDLList 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(!tFragPtr.p->m_scanNumberMask.get(scanNumber)); ScanRecordPtr restart; @@ -8718,7 +8720,7 @@ void Dblqh::finishScanrec(Signal* signal) ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec); restart.p->scanNumber = scanNumber; restart.p->scanState = ScanRecord::WAIT_ACC_SCAN; - + queue.remove(restart); scans.add(restart); if(restart.p->scanKeyinfoFlag){ diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index 31853b7a3b7..931b4da5a17 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -34,6 +34,7 @@ #include #include +#include #include "pc.hpp" #include #include @@ -454,6 +455,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ unsigned int noOfTables = 0; unsigned int noOfUniqueHashIndexes = 0; unsigned int noOfOrderedIndexes = 0; + unsigned int noOfTriggers = 0; unsigned int noOfReplicas = 0; unsigned int noOfDBNodes = 0; unsigned int noOfAPINodes = 0; @@ -478,6 +480,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ { CFG_DB_NO_TABLES, &noOfTables, false }, { CFG_DB_NO_ORDERED_INDEXES, &noOfOrderedIndexes, false }, { CFG_DB_NO_UNIQUE_HASH_INDEXES, &noOfUniqueHashIndexes, false }, + { CFG_DB_NO_TRIGGERS, &noOfTriggers, true }, { CFG_DB_NO_REPLICAS, &noOfReplicas, false }, { CFG_DB_NO_ATTRIBUTES, &noOfAttributes, false }, { CFG_DB_NO_OPS, &noOfOperations, false }, @@ -586,6 +589,18 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ ConfigValues::Iterator it2(*ownConfig, db.m_config); it2.set(CFG_DB_NO_TABLES, noOfTables); it2.set(CFG_DB_NO_ATTRIBUTES, noOfAttributes); + { + Uint32 neededNoOfTriggers = /* types: Insert/Update/Delete/Custom */ + 3 * noOfUniqueHashIndexes + /* for unique hash indexes, I/U/D */ + 3 * NDB_MAX_ACTIVE_EVENTS + /* for events in suma, I/U/D */ + 3 * noOfTables + /* for backup, I/U/D */ + noOfOrderedIndexes; /* for ordered indexes, C */ + if (noOfTriggers < neededNoOfTriggers) + { + noOfTriggers= neededNoOfTriggers; + it2.set(CFG_DB_NO_TRIGGERS, noOfTriggers); + } + } /** * Do size calculations diff --git a/ndb/src/mgmsrv/InitConfigFileParser.cpp b/ndb/src/mgmsrv/InitConfigFileParser.cpp index fdfe7823fc2..05102255eaa 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 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/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index 2b1557daaeb..f4bb000300a 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -1122,8 +1122,11 @@ NdbConnection::getNdbIndexScanOperation(const NdbIndexImpl* index, if (indexTable != 0){ NdbIndexScanOperation* tOp = getNdbScanOperation((NdbTableImpl *) indexTable); - tOp->m_currentTable = table; - if(tOp) tOp->m_cursor_type = NdbScanOperation::IndexCursor; + if(tOp) + { + tOp->m_currentTable = table; + tOp->m_cursor_type = NdbScanOperation::IndexCursor; + } return tOp; } else { setOperationErrorCodeAbort(theNdb->theError.code); diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index e08b80f2433..bc49358cc63 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -426,7 +426,8 @@ ErrorBundle ErrorCodes[] = { { 4267, IE, "Corrupted blob value" }, { 4268, IE, "Error in blob head update forced rollback of transaction" }, { 4268, IE, "Unknown blob error" }, - { 4269, IE, "No connection to ndb management server" } + { 4269, IE, "No connection to ndb management server" }, + { 4335, AE, "Only one autoincrement column allowed per table. Having a table without primary key uses an autoincremented hidden key, i.e. a table without a primary key can not have an autoincremented column" } }; static diff --git a/sql/table.cc b/sql/table.cc index 20ac714020d..cb565097c0b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -463,7 +463,26 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, /* 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= diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 8df5b3277c1..89c876ad10c 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -7288,6 +7288,7 @@ int my_wildcmp_uca(CHARSET_INFO *cs, { while (1) { + my_bool escaped= 0; if ((scan= mb_wc(cs, &w_wc, (const uchar*)wildstr, (const uchar*)wildend)) <= 0) return 1; @@ -7305,6 +7306,7 @@ int my_wildcmp_uca(CHARSET_INFO *cs, (const uchar*)wildend)) <= 0) return 1; wildstr+= scan; + escaped= 1; } if ((scan= mb_wc(cs, &s_wc, (const uchar*)str, @@ -7312,7 +7314,7 @@ int my_wildcmp_uca(CHARSET_INFO *cs, return 1; str+= scan; - if (w_wc == (my_wc_t)w_one) + if (!escaped && w_wc == (my_wc_t)w_one) { result= 1; /* Found an anchor char */ } diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index b3097649158..ce9346eb475 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1545,31 +1545,33 @@ int my_wildcmp_unicode(CHARSET_INFO *cs, { while (1) { + my_bool escaped= 0; if ((scan= mb_wc(cs, &w_wc, (const uchar*)wildstr, (const uchar*)wildend)) <= 0) return 1; - - if (w_wc == (my_wc_t)escape) - { - wildstr+= scan; - if ((scan= mb_wc(cs,&w_wc, (const uchar*)wildstr, - (const uchar*)wildend)) <= 0) - return 1; - } - + if (w_wc == (my_wc_t)w_many) { result= 1; /* Found an anchor char */ break; } - + wildstr+= scan; + if (w_wc == (my_wc_t)escape) + { + if ((scan= mb_wc(cs, &w_wc, (const uchar*)wildstr, + (const uchar*)wildend)) <= 0) + return 1; + wildstr+= scan; + escaped= 1; + } + if ((scan= mb_wc(cs, &s_wc, (const uchar*)str, - (const uchar*)str_end)) <=0) + (const uchar*)str_end)) <= 0) return 1; str+= scan; - if (w_wc == (my_wc_t)w_one) + if (!escaped && w_wc == (my_wc_t)w_one) { result= 1; /* Found an anchor char */ }