diff --git a/mysql-test/include/have_gbk.inc b/mysql-test/include/have_gbk.inc new file mode 100644 index 00000000000..55805da0495 --- /dev/null +++ b/mysql-test/include/have_gbk.inc @@ -0,0 +1,4 @@ +-- require r/have_gbk.require +disable_query_log; +show collation like "gbk_chinese_ci"; +enable_query_log; diff --git a/mysql-test/r/ctype_gbk.result b/mysql-test/r/ctype_gbk.result new file mode 100644 index 00000000000..1a9dea28429 --- /dev/null +++ b/mysql-test/r/ctype_gbk.result @@ -0,0 +1,131 @@ +drop table if exists t1; +SET @test_character_set= 'gbk'; +SET @test_collation= 'gbk_chinese_ci'; +SET @safe_character_set_server= @@character_set_server; +SET @safe_collation_server= @@collation_server; +SET character_set_server= @test_character_set; +SET collation_server= @test_collation; +CREATE DATABASE d1; +USE d1; +CREATE TABLE t1 (c CHAR(10), KEY(c)); +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +c char(10) gbk_chinese_ci YES MUL NULL +INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa'); +SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%'; +want3results +aaa +aaaa +aaaaa +DROP TABLE t1; +CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2))); +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +c1 varchar(15) gbk_chinese_ci YES MUL NULL +INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab'); +SELECT c1 as want3results from t1 where c1 like 'l%'; +want3results +location +loberge +lotre +SELECT c1 as want3results from t1 where c1 like 'lo%'; +want3results +location +loberge +lotre +SELECT c1 as want1result from t1 where c1 like 'loc%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'loca%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locat%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locati%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locatio%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'location%'; +want1result +location +DROP TABLE t1; +DROP DATABASE d1; +USE test; +SET character_set_server= @safe_character_set_server; +SET collation_server= @safe_collation_server; +SET NAMES gbk; +SET collation_connection='gbk_chinese_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +gbk_chinese_ci 6109 +gbk_chinese_ci 61 +gbk_chinese_ci 6120 +drop table t1; +create table t1 engine=innodb select repeat('a',50) as c1; +alter table t1 add index(c1(5)); +insert into t1 values ('abcdefg'),('abcde100'),('abcde110'),('abcde111'); +select collation(c1) from t1 limit 1; +collation(c1) +gbk_chinese_ci +select c1 from t1 where c1 like 'abcdef%' order by c1; +c1 +abcdefg +select c1 from t1 where c1 like 'abcde1%' order by c1; +c1 +abcde100 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde11%' order by c1; +c1 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde111%' order by c1; +c1 +abcde111 +drop table t1; +SET collation_connection='gbk_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +gbk_bin 6109 +gbk_bin 61 +gbk_bin 6120 +drop table t1; +create table t1 engine=innodb select repeat('a',50) as c1; +alter table t1 add index(c1(5)); +insert into t1 values ('abcdefg'),('abcde100'),('abcde110'),('abcde111'); +select collation(c1) from t1 limit 1; +collation(c1) +gbk_bin +select c1 from t1 where c1 like 'abcdef%' order by c1; +c1 +abcdefg +select c1 from t1 where c1 like 'abcde1%' order by c1; +c1 +abcde100 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde11%' order by c1; +c1 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde111%' order by c1; +c1 +abcde111 +drop table t1; +SET NAMES gbk; +CREATE TABLE t1 (a text) character set gbk; +INSERT INTO t1 VALUES (0xA3A0),(0xA1A1); +SELECT hex(a) FROM t1 ORDER BY a; +hex(a) +A1A1 +A3A0 +DROP TABLE t1; diff --git a/mysql-test/r/have_gbk.require b/mysql-test/r/have_gbk.require new file mode 100644 index 00000000000..e19fead153a --- /dev/null +++ b/mysql-test/r/have_gbk.require @@ -0,0 +1,2 @@ +Collation Charset Id Default Compiled Sortlen +gbk_chinese_ci gbk 28 Yes Yes 1 diff --git a/mysql-test/t/ctype_gbk.test b/mysql-test/t/ctype_gbk.test new file mode 100644 index 00000000000..82a2e61879e --- /dev/null +++ b/mysql-test/t/ctype_gbk.test @@ -0,0 +1,30 @@ +-- source include/have_gbk.inc + +# +# Tests with the gbk character set +# +--disable_warnings +drop table if exists t1; +--enable_warnings + +SET @test_character_set= 'gbk'; +SET @test_collation= 'gbk_chinese_ci'; +-- source include/ctype_common.inc + +SET NAMES gbk; +SET collation_connection='gbk_chinese_ci'; +-- source include/ctype_filesort.inc +-- source include/ctype_innodb_like.inc +SET collation_connection='gbk_bin'; +-- source include/ctype_filesort.inc +-- source include/ctype_innodb_like.inc + +# +# Bug#11987 mysql will truncate the text when +# the text contain GBK char:"0xA3A0" and "0xA1" +# +SET NAMES gbk; +CREATE TABLE t1 (a text) character set gbk; +INSERT INTO t1 VALUES (0xA3A0),(0xA1A1); +SELECT hex(a) FROM t1 ORDER BY a; +DROP TABLE t1; diff --git a/storage/ndb/test/include/UtilTransactions.hpp b/storage/ndb/test/include/UtilTransactions.hpp index afdbc5c3445..333f5d98328 100644 --- a/storage/ndb/test/include/UtilTransactions.hpp +++ b/storage/ndb/test/include/UtilTransactions.hpp @@ -28,6 +28,8 @@ public: UtilTransactions(Ndb* ndb, const char * tableName, const char * indexName = 0); + int closeTransaction(Ndb*); + int clearTable(Ndb*, int records = 0, int parallelism = 0); diff --git a/storage/ndb/test/src/HugoOperations.cpp b/storage/ndb/test/src/HugoOperations.cpp index a1cf623a6ca..f2e54971766 100644 --- a/storage/ndb/test/src/HugoOperations.cpp +++ b/storage/ndb/test/src/HugoOperations.cpp @@ -53,11 +53,7 @@ HugoOperations::setTransactionId(Uint64 id){ int HugoOperations::closeTransaction(Ndb* pNdb){ - if (pTrans != NULL){ - pNdb->closeTransaction(pTrans); - pTrans = NULL; - } - pTrans = NULL; + UtilTransactions::closeTransaction(pNdb); m_result_sets.clear(); m_executed_result_sets.clear(); diff --git a/storage/ndb/test/src/UtilTransactions.cpp b/storage/ndb/test/src/UtilTransactions.cpp index 65c1a7ded31..31c323045ed 100644 --- a/storage/ndb/test/src/UtilTransactions.cpp +++ b/storage/ndb/test/src/UtilTransactions.cpp @@ -109,7 +109,7 @@ UtilTransactions::clearTable3(Ndb* pNdb, err = pTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); par = 1; goto restart; @@ -126,7 +126,7 @@ UtilTransactions::clearTable3(Ndb* pNdb, err = pTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); continue; } @@ -150,7 +150,7 @@ UtilTransactions::clearTable3(Ndb* pNdb, if(check == -1){ if(err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); par = 1; goto restart; @@ -162,20 +162,20 @@ UtilTransactions::clearTable3(Ndb* pNdb, err = pTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); par = 1; goto restart; } goto failed; } - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_OK; } return NDBT_FAILED; failed: - if(pTrans != 0) pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); ERR(err); return (err.code != 0 ? err.code : NDBT_FAILED); } @@ -219,20 +219,20 @@ UtilTransactions::copyTableData(Ndb* pNdb, pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } if( pOp->readTuples(NdbScanOperation::LM_Read, parallelism) ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -241,7 +241,7 @@ UtilTransactions::copyTableData(Ndb* pNdb, if ((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } } @@ -249,7 +249,7 @@ UtilTransactions::copyTableData(Ndb* pNdb, check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -258,7 +258,7 @@ UtilTransactions::copyTableData(Ndb* pNdb, do { insertedRows++; if (addRowToInsert(pNdb, pTrans, row, destName) != 0){ - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } } while((eof = pOp->nextResult(false)) == 0); @@ -268,7 +268,7 @@ UtilTransactions::copyTableData(Ndb* pNdb, if( check == -1 ) { const NdbError err = pTrans->getNdbError(); ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } } @@ -277,7 +277,7 @@ UtilTransactions::copyTableData(Ndb* pNdb, if (err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); // If error = 488 there should be no limit on number of retry attempts if (err.code != 488) @@ -285,11 +285,11 @@ UtilTransactions::copyTableData(Ndb* pNdb, continue; } ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); g_info << insertedRows << " rows copied" << endl; @@ -375,7 +375,7 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, pOp = getScanOperation(pTrans); if (pOp == NULL) { const NdbError err = pNdb->getNdbError(); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); if (err.status == NdbError::TemporaryError){ ERR(err); @@ -389,14 +389,14 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, if( pOp->readTuples(lm, 0, parallelism) ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -408,7 +408,7 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, if ((row.attributeStore(attrib_list[a]) = pOp->getValue(tab.getColumn(attrib_list[a])->getName())) == 0) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } } @@ -421,13 +421,13 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, if (err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -447,17 +447,17 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, if (err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); g_info << rows << " rows have been read" << endl; if (records != 0 && rows != records){ g_info << "Check expected number of records failed" << endl @@ -496,13 +496,13 @@ UtilTransactions::selectCount(Ndb* pNdb, pOp = getScanOperation(pTrans); if (pOp == NULL) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } if( pOp->readTuples(lm) ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -515,7 +515,7 @@ UtilTransactions::selectCount(Ndb* pNdb, check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } } @@ -524,7 +524,7 @@ UtilTransactions::selectCount(Ndb* pNdb, check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -539,17 +539,17 @@ UtilTransactions::selectCount(Ndb* pNdb, const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); if (count_rows != NULL){ *count_rows = rows; @@ -653,7 +653,7 @@ restart: pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { const NdbError err = pNdb->getNdbError(); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); ERR(err); if (err.status == NdbError::TemporaryError){ @@ -673,14 +673,14 @@ restart: if( rs != 0 ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -689,7 +689,7 @@ restart: if ((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } } @@ -700,13 +700,13 @@ restart: if (err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -733,13 +733,13 @@ restart: if (err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; goto restart; } } - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } } @@ -748,17 +748,17 @@ restart: if (err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_OK; } @@ -1057,20 +1057,20 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb, pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } check = pOp->interpret_exit_ok(); if( check == -1 ) { ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -1085,13 +1085,13 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb, if (err.status == NdbError::TemporaryError){ ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; continue; } ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -1146,7 +1146,7 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb, g_err << "Error when comapring records" << endl; g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl; g_err << " pkRow: \n" << pkRow.c_str().c_str() << endl; - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -1156,7 +1156,7 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb, if((res= iop->nextResult()) != 0){ g_err << "Failed to find row using index: " << res << endl; ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } @@ -1164,14 +1164,14 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb, g_err << "Error when comapring records" << endl; g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl; g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl; - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } if(iop->nextResult() == 0){ g_err << "Found extra row!!" << endl; g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl; - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } } @@ -1184,18 +1184,18 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb, if (err.status == NdbError::TemporaryError){ ERR(err); iop = 0; - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); NdbSleep_MilliSleep(50); retryAttempt++; rows--; continue; } ERR(err); - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_FAILED; } - pNdb->closeTransaction(pTrans); + closeTransaction(pNdb); return NDBT_OK; } @@ -1303,6 +1303,16 @@ UtilTransactions::getOperation(NdbConnection* pTrans, #include +int +UtilTransactions::closeTransaction(Ndb* pNdb) +{ + if (pTrans != NULL){ + pNdb->closeTransaction(pTrans); + pTrans = NULL; + } + return 0; +} + int UtilTransactions::compare(Ndb* pNdb, const char* tab_name2, int flags){ @@ -1313,7 +1323,6 @@ UtilTransactions::compare(Ndb* pNdb, const char* tab_name2, int flags){ HugoCalculator calc(tab); NDBT_ResultRow row(tab); - NdbTransaction* pTrans= 0; const NdbDictionary::Table* tmp= pNdb->getDictionary()->getTable(tab_name2); if(tmp == 0) { diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index f941aabaf69..a4bcce19432 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9938,6 +9938,43 @@ my_mb_wc_gbk(CHARSET_INFO *cs __attribute__((unused)), } +/* + Returns well formed length of a GBK string. +*/ +static +uint my_well_formed_len_gbk(CHARSET_INFO *cs __attribute__((unused)), + const char *b, const char *e, + uint pos, int *error) +{ + const char *b0= b; + const char *emb= e - 1; /* Last possible end of an MB character */ + + *error= 0; + while (pos-- && b < e) + { + if ((uchar) b[0] < 128) + { + /* Single byte ascii character */ + b++; + } + else if ((b < emb) && isgbkcode((uchar)*b, (uchar)b[1])) + { + /* Double byte character */ + b+= 2; + } + else + { + /* Wrong byte sequence */ + *error= 1; + break; + } + } + return b - b0; +} + + + + static MY_COLLATION_HANDLER my_collation_ci_handler = { NULL, /* init */ @@ -9960,7 +9997,7 @@ static MY_CHARSET_HANDLER my_charset_handler= mbcharlen_gbk, my_numchars_mb, my_charpos_mb, - my_well_formed_len_mb, + my_well_formed_len_gbk, my_lengthsp_8bit, my_numcells_8bit, my_mb_wc_gbk,