From 765858bc5b2aa4aafb77357d8b14f3432739146e Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 26 Feb 2021 16:16:00 +0400 Subject: [PATCH] MCOL-4498 LIKE is not collation aware --- dbcon/execplan/constantcolumn.cpp | 29 -- dbcon/execplan/constantcolumn.h | 4 - dbcon/execplan/predicateoperator.cpp | 43 +-- dbcon/execplan/simplefilter.cpp | 13 - dbcon/execplan/treenode.cpp | 1 - dbcon/execplan/treenode.h | 11 - dbcon/joblist/primitivemsg.h | 54 +++ .../ctype_cmp_char4_latin1_swedish_ci.result | 42 +++ .../ctype_cmp_char5_latin1_swedish_ci.result | 42 +++ .../r/ctype_cmp_varchar32_latin1_bin.result | 38 +++ ...type_cmp_varchar32_latin1_nopad_bin.result | 38 +++ ...ype_cmp_varchar32_latin1_swedish_ci.result | 42 +++ ...p_varchar32_latin1_swedish_nopad_ci.result | 42 +++ .../r/ctype_cmp_varchar32_utf8_bin.result | 38 +++ ...ctype_cmp_varchar32_utf8_general_ci.result | 42 +++ ...cmp_varchar32_utf8_general_nopad_ci.result | 42 +++ .../ctype_cmp_varchar32_utf8_nopad_bin.result | 38 +++ ...ctype_cmp_varchar32_utf8_unicode_ci.result | 42 +++ ...cmp_varchar32_utf8_unicode_nopad_ci.result | 42 +++ .../r/ctype_cmp_varchar4_latin1_bin.result | 38 +++ ...ctype_cmp_varchar4_latin1_nopad_bin.result | 38 +++ ...type_cmp_varchar4_latin1_swedish_ci.result | 42 +++ ...mp_varchar4_latin1_swedish_nopad_ci.result | 42 +++ .../r/ctype_cmp_varchar4_utf8_bin.result | 38 +++ .../ctype_cmp_varchar4_utf8_general_ci.result | 42 +++ ..._cmp_varchar4_utf8_general_nopad_ci.result | 42 +++ .../ctype_cmp_varchar4_utf8_nopad_bin.result | 38 +++ .../ctype_cmp_varchar4_utf8_unicode_ci.result | 42 +++ ..._cmp_varchar4_utf8_unicode_nopad_ci.result | 42 +++ .../t/ctype_cmp_char4_latin1_swedish_ci.test | 2 + .../t/ctype_cmp_char5_latin1_swedish_ci.test | 2 + mtr/basic/t/ctype_cmp_create.inc | 15 + mtr/basic/t/ctype_cmp_drop.inc | 1 + .../t/ctype_cmp_varchar32_latin1_bin.test | 2 + .../ctype_cmp_varchar32_latin1_nopad_bin.test | 2 + ...ctype_cmp_varchar32_latin1_swedish_ci.test | 2 + ...cmp_varchar32_latin1_swedish_nopad_ci.test | 2 + mtr/basic/t/ctype_cmp_varchar32_utf8_bin.test | 2 + .../ctype_cmp_varchar32_utf8_general_ci.test | 2 + ...e_cmp_varchar32_utf8_general_nopad_ci.test | 2 + .../t/ctype_cmp_varchar32_utf8_nopad_bin.test | 2 + .../ctype_cmp_varchar32_utf8_unicode_ci.test | 2 + ...e_cmp_varchar32_utf8_unicode_nopad_ci.test | 2 + .../t/ctype_cmp_varchar4_latin1_bin.test | 2 + .../ctype_cmp_varchar4_latin1_nopad_bin.test | 2 + .../ctype_cmp_varchar4_latin1_swedish_ci.test | 2 + ..._cmp_varchar4_latin1_swedish_nopad_ci.test | 2 + mtr/basic/t/ctype_cmp_varchar4_utf8_bin.test | 2 + .../t/ctype_cmp_varchar4_utf8_general_ci.test | 2 + ...pe_cmp_varchar4_utf8_general_nopad_ci.test | 2 + .../t/ctype_cmp_varchar4_utf8_nopad_bin.test | 2 + .../t/ctype_cmp_varchar4_utf8_unicode_ci.test | 2 + ...pe_cmp_varchar4_utf8_unicode_nopad_ci.test | 2 + primitives/linux-port/column.cpp | 321 ++---------------- primitives/linux-port/dictionary.cpp | 305 ++--------------- primitives/linux-port/primitiveprocessor.cpp | 2 +- primitives/linux-port/primitiveprocessor.h | 38 +-- primitives/primproc/dictstep.cpp | 3 - primitives/primproc/dictstep.h | 1 - utils/common/collation.h | 20 ++ utils/dataconvert/dataconvert.h | 86 ----- 61 files changed, 1094 insertions(+), 789 deletions(-) diff --git a/dbcon/execplan/constantcolumn.cpp b/dbcon/execplan/constantcolumn.cpp index 8579f2fe0..22be5bee8 100644 --- a/dbcon/execplan/constantcolumn.cpp +++ b/dbcon/execplan/constantcolumn.cpp @@ -208,17 +208,6 @@ ConstantColumn::ConstantColumn( const ConstantColumn& rhs): fAlias = rhs.alias(); fResult = rhs.fResult; fResultType = rhs.fResultType; - - if (fRegex.get() != NULL) - { - fRegex.reset(new CNX_Regex()); -#ifdef POSIX_REGEX - string str = dataconvert::DataConvert::constructRegexp(fResult.strVal); - regcomp(fRegex.get(), str.c_str(), REG_NOSUB | REG_EXTENDED); -#else - *fRegex = dataconvert::DataConvert::constructRegexp(fResult.strVal); -#endif - } } ConstantColumn::ConstantColumn(const int64_t val, TYPE type) : @@ -268,12 +257,6 @@ ConstantColumn::ConstantColumn(const uint64_t val, TYPE type, ConstantColumn::~ConstantColumn() { -#ifdef POSIX_REGEX - - if (fRegex.get() != NULL) - regfree(fRegex.get()); - -#endif } const string ConstantColumn::toString() const @@ -409,17 +392,5 @@ bool ConstantColumn::operator!=(const TreeNode* t) const return (!(*this == t)); } -void ConstantColumn::constructRegex() -{ - //fRegex = new regex_t(); - fRegex.reset(new CNX_Regex()); -#ifdef POSIX_REGEX - string str = dataconvert::DataConvert::constructRegexp(fResult.strVal); - regcomp(fRegex.get(), str.c_str(), REG_NOSUB | REG_EXTENDED); -#else - *fRegex = dataconvert::DataConvert::constructRegexp(fResult.strVal); -#endif -} - } // vim:ts=4 sw=4: diff --git a/dbcon/execplan/constantcolumn.h b/dbcon/execplan/constantcolumn.h index 334247c47..5be0051ef 100644 --- a/dbcon/execplan/constantcolumn.h +++ b/dbcon/execplan/constantcolumn.h @@ -242,10 +242,6 @@ public: */ using ReturnedColumn::evaluate; virtual void evaluate(rowgroup::Row& row) {} - /** - * F&E - */ - virtual void constructRegex(); /** * F&E */ diff --git a/dbcon/execplan/predicateoperator.cpp b/dbcon/execplan/predicateoperator.cpp index b132a5a25..cb79a5895 100644 --- a/dbcon/execplan/predicateoperator.cpp +++ b/dbcon/execplan/predicateoperator.cpp @@ -386,40 +386,15 @@ bool PredicateOperator::getBoolVal(rowgroup::Row& row, bool& isNull, ReturnedCol // like operator. both sides are string. if (fOp == OP_LIKE || fOp == OP_NOTLIKE) { - SP_CNX_Regex regex = rop->regex(); - - // Ugh. The strings returned by getStrVal have null padding out to the col width. boost::regex - // considers these nulls significant, but they're not in the pattern, so we need to strip - // them off... - const std::string& v = lop->getStrVal(row, isNull); -// char* c = (char*)alloca(v.length() + 1); -// memcpy(c, v.c_str(), v.length()); -// c[v.length()] = 0; -// std::string vv(c); - - if (regex) - { -#ifdef POSIX_REGEX - bool ret = regexec(regex.get(), v.c_str(), 0, NULL, 0) == 0; -#else - bool ret = boost::regex_match(v.c_str(), *regex); -#endif - return (((fOp == OP_LIKE) ? ret : !ret) && !isNull); - } - else - { -#ifdef POSIX_REGEX - regex_t regex; - std::string str = dataconvert::DataConvert::constructRegexp(rop->getStrVal(row, isNull)); - regcomp(®ex, str.c_str(), REG_NOSUB | REG_EXTENDED); - bool ret = regexec(®ex, v.c_str(), 0, NULL, 0) == 0; - regfree(®ex); -#else - boost::regex regex(dataconvert::DataConvert::constructRegexp(rop->getStrVal(row, isNull))); - bool ret = boost::regex_match(v.c_str(), regex); -#endif - return (((fOp == OP_LIKE) ? ret : !ret) && !isNull); - } + const std::string & subject = lop->getStrVal(row, isNull); + if (isNull) + return false; + const std::string & pattern = rop->getStrVal(row, isNull); + if (isNull) + return false; + return datatypes::Charset(cs).like(fOp == OP_NOTLIKE, + utils::ConstString(subject), + utils::ConstString(pattern)); } // fOpType should have already been set on the connector during parsing diff --git a/dbcon/execplan/simplefilter.cpp b/dbcon/execplan/simplefilter.cpp index 3fcc8fcd6..37ebc3f38 100644 --- a/dbcon/execplan/simplefilter.cpp +++ b/dbcon/execplan/simplefilter.cpp @@ -416,19 +416,6 @@ void SimpleFilter::unserialize(messageqcpp::ByteStream& b) fWindowFunctionColumnList.push_back(raf); } - // construct regex constant for like operator - if (fOp->op() == OP_LIKE || fOp->op() == OP_NOTLIKE) - { - ConstantColumn* rcc = dynamic_cast(fRhs); - - if (rcc) - rcc->constructRegex(); - - ConstantColumn* lcc = dynamic_cast(fLhs); - - if (lcc) - lcc->constructRegex(); - } } bool SimpleFilter::operator==(const SimpleFilter& t) const diff --git a/dbcon/execplan/treenode.cpp b/dbcon/execplan/treenode.cpp index 39c57840c..d25343ca4 100644 --- a/dbcon/execplan/treenode.cpp +++ b/dbcon/execplan/treenode.cpp @@ -50,7 +50,6 @@ TreeNode::TreeNode(const TreeNode& rhs): fResult(rhs.fResult), fResultType(rhs.resultType()), fOperationType(rhs.operationType()), - fRegex (rhs.regex()), fDerivedTable (rhs.derivedTable()), fRefCount(rhs.refCount()), fDerivedRefCol(rhs.derivedRefCol()) diff --git a/dbcon/execplan/treenode.h b/dbcon/execplan/treenode.h index e319c95ba..ab7cf1bce 100644 --- a/dbcon/execplan/treenode.h +++ b/dbcon/execplan/treenode.h @@ -356,16 +356,6 @@ public: return fResult; } - // regex mutator and accessor - virtual void regex(SP_IDB_Regex regex) - { - fRegex = regex; - } - virtual SP_IDB_Regex regex() const - { - return fRegex; - } - uint32_t charsetNumber() const { return fResultType.charsetNumber; @@ -380,7 +370,6 @@ protected: Result fResult; execplan::CalpontSystemCatalog::ColType fResultType; // mapped from mysql data type execplan::CalpontSystemCatalog::ColType fOperationType; // operator type, could be different from the result type - SP_IDB_Regex fRegex; // double's range is +/-1.7E308 with at least 15 digits of precision char tmp[312]; // for conversion use diff --git a/dbcon/joblist/primitivemsg.h b/dbcon/joblist/primitivemsg.h index 9aa0ae8d9..1ede5ecad 100644 --- a/dbcon/joblist/primitivemsg.h +++ b/dbcon/joblist/primitivemsg.h @@ -62,6 +62,60 @@ const int8_t COMPARE_NGE = (COMPARE_GE | COMPARE_NOT); //0x0e const int8_t COMPARE_LIKE = 0x10; const int8_t COMPARE_NLIKE = (COMPARE_LIKE | COMPARE_NOT); //0x18 + +namespace primitives +{ + +using utils::ConstString; + +class StringComparator: public datatypes::Charset +{ +public: + StringComparator(const Charset &cs) + :Charset(cs) + { } + bool op(int * error, uint8_t COP, + const ConstString &str1, + const ConstString &str2) const + { + if (COP & COMPARE_LIKE) + return like(COP & COMPARE_NOT, str1, str2); + + int cmp = strnncollsp(str1, str2); + + switch (COP) + { + case COMPARE_NIL: + return false; + + case COMPARE_LT: + return cmp < 0; + + case COMPARE_EQ: + return cmp == 0; + + case COMPARE_LE: + return cmp <= 0; + + case COMPARE_GT: + return cmp > 0; + + case COMPARE_NE: + return cmp != 0; + + case COMPARE_GE: + return cmp >= 0; + + default: + *error |= 1; + return false; + } + + } +}; + +} // namespace primities + // BOP (Binary Operation) values // used to tell if the operations are all be true or // any to be true. diff --git a/mtr/basic/r/ctype_cmp_char4_latin1_swedish_ci.result b/mtr/basic/r/ctype_cmp_char4_latin1_swedish_ci.result index 859c59df2..2a3c753f4 100644 --- a/mtr/basic/r/ctype_cmp_char4_latin1_swedish_ci.result +++ b/mtr/basic/r/ctype_cmp_char4_latin1_swedish_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='CHAR(4) CHARACTER SET latin1 COLLATE latin1_swedish_ci'; CREATE TABLE t1 (c1 CHAR(4) CHARACTER SET latin1 COLLATE latin1_swedish_ci); @@ -1655,6 +1667,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4, @datatype); + +CREATE TABLE t1 (c1 CHAR(4) CHARACTER SET latin1 COLLATE latin1_swedish_ci) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1668,6 +1709,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_char5_latin1_swedish_ci.result b/mtr/basic/r/ctype_cmp_char5_latin1_swedish_ci.result index 196f4a49e..aaf0f96d4 100644 --- a/mtr/basic/r/ctype_cmp_char5_latin1_swedish_ci.result +++ b/mtr/basic/r/ctype_cmp_char5_latin1_swedish_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='CHAR(5) CHARACTER SET latin1 COLLATE latin1_swedish_ci'; CREATE TABLE t1 (c1 CHAR(5) CHARACTER SET latin1 COLLATE latin1_swedish_ci); @@ -1943,6 +1955,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hello hello Hello hello +DROP TABLE t1 +CALL test04_like(5, @datatype); + +CREATE TABLE t1 (c1 CHAR(5) CHARACTER SET latin1 COLLATE latin1_swedish_ci) + +INSERT INTO t1 VALUES (REPEAT('a',5)) + +INSERT INTO t1 VALUES (REPEAT('A',5)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAAA +aaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAA +aaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaa%' ORDER BY BINARY c1 +c1 +AAAAA +aaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAA%' ORDER BY BINARY c1 +c1 +AAAAA +aaaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1956,6 +1997,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar32_latin1_bin.result b/mtr/basic/r/ctype_cmp_varchar32_latin1_bin.result index 5fa44758c..6ceca1e13 100644 --- a/mtr/basic/r/ctype_cmp_varchar32_latin1_bin.result +++ b/mtr/basic/r/ctype_cmp_varchar32_latin1_bin.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin'; CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin); @@ -1529,6 +1541,31 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hellooooooooooooooooooo hellooooooooooooooooooo Hellooooooooooooooooooo hellooooooooooooooooooo +DROP TABLE t1 +CALL test04_like(32,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin) + +INSERT INTO t1 VALUES (REPEAT('a',32)) + +INSERT INTO t1 VALUES (REPEAT('A',32)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' ORDER BY BINARY c1 +c1 +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1542,6 +1579,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar32_latin1_nopad_bin.result b/mtr/basic/r/ctype_cmp_varchar32_latin1_nopad_bin.result index d23878882..d5c00d145 100644 --- a/mtr/basic/r/ctype_cmp_varchar32_latin1_nopad_bin.result +++ b/mtr/basic/r/ctype_cmp_varchar32_latin1_nopad_bin.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_nopad_bin'; CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_nopad_bin); @@ -1505,6 +1517,31 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hellooooooooooooooooooo hellooooooooooooooooooo Hellooooooooooooooooooo hellooooooooooooooooooo +DROP TABLE t1 +CALL test04_like(32,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_nopad_bin) + +INSERT INTO t1 VALUES (REPEAT('a',32)) + +INSERT INTO t1 VALUES (REPEAT('A',32)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' ORDER BY BINARY c1 +c1 +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1518,6 +1555,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar32_latin1_swedish_ci.result b/mtr/basic/r/ctype_cmp_varchar32_latin1_swedish_ci.result index a2f83e6ee..8d0a028a0 100644 --- a/mtr/basic/r/ctype_cmp_varchar32_latin1_swedish_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar32_latin1_swedish_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_swedish_ci'; CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_swedish_ci); @@ -1655,6 +1667,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hellooooooooooooooooooo hellooooooooooooooooooo Hellooooooooooooooooooo hellooooooooooooooooooo +DROP TABLE t1 +CALL test04_like(32,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_swedish_ci) + +INSERT INTO t1 VALUES (REPEAT('a',32)) + +INSERT INTO t1 VALUES (REPEAT('A',32)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1668,6 +1709,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar32_latin1_swedish_nopad_ci.result b/mtr/basic/r/ctype_cmp_varchar32_latin1_swedish_nopad_ci.result index 9576187fc..c5726597d 100644 --- a/mtr/basic/r/ctype_cmp_varchar32_latin1_swedish_nopad_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar32_latin1_swedish_nopad_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_swedish_nopad_ci'; CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_swedish_nopad_ci); @@ -1539,6 +1551,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hellooooooooooooooooooo hellooooooooooooooooooo Hellooooooooooooooooooo hellooooooooooooooooooo +DROP TABLE t1 +CALL test04_like(32,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_swedish_nopad_ci) + +INSERT INTO t1 VALUES (REPEAT('a',32)) + +INSERT INTO t1 VALUES (REPEAT('A',32)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1552,6 +1593,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar32_utf8_bin.result b/mtr/basic/r/ctype_cmp_varchar32_utf8_bin.result index c9c92f564..6a7063f3e 100644 --- a/mtr/basic/r/ctype_cmp_varchar32_utf8_bin.result +++ b/mtr/basic/r/ctype_cmp_varchar32_utf8_bin.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin'; CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin); @@ -1529,6 +1541,31 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hellooooooooooooooooooo hellooooooooooooooooooo Hellooooooooooooooooooo hellooooooooooooooooooo +DROP TABLE t1 +CALL test04_like(32,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin) + +INSERT INTO t1 VALUES (REPEAT('a',32)) + +INSERT INTO t1 VALUES (REPEAT('A',32)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' ORDER BY BINARY c1 +c1 +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1542,6 +1579,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar32_utf8_general_ci.result b/mtr/basic/r/ctype_cmp_varchar32_utf8_general_ci.result index 7282fc579..0bdc90747 100644 --- a/mtr/basic/r/ctype_cmp_varchar32_utf8_general_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar32_utf8_general_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_general_ci'; CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_general_ci); @@ -1655,6 +1667,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hellooooooooooooooooooo hellooooooooooooooooooo Hellooooooooooooooooooo hellooooooooooooooooooo +DROP TABLE t1 +CALL test04_like(32,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_general_ci) + +INSERT INTO t1 VALUES (REPEAT('a',32)) + +INSERT INTO t1 VALUES (REPEAT('A',32)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1668,6 +1709,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar32_utf8_general_nopad_ci.result b/mtr/basic/r/ctype_cmp_varchar32_utf8_general_nopad_ci.result index b35b40e48..41845f1c5 100644 --- a/mtr/basic/r/ctype_cmp_varchar32_utf8_general_nopad_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar32_utf8_general_nopad_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_general_nopad_ci'; CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_general_nopad_ci); @@ -1251,6 +1263,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hellooooooooooooooooooo hellooooooooooooooooooo Hellooooooooooooooooooo hellooooooooooooooooooo +DROP TABLE t1 +CALL test04_like(32,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_general_nopad_ci) + +INSERT INTO t1 VALUES (REPEAT('a',32)) + +INSERT INTO t1 VALUES (REPEAT('A',32)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1264,6 +1305,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar32_utf8_nopad_bin.result b/mtr/basic/r/ctype_cmp_varchar32_utf8_nopad_bin.result index 8ba360524..aafcb6f06 100644 --- a/mtr/basic/r/ctype_cmp_varchar32_utf8_nopad_bin.result +++ b/mtr/basic/r/ctype_cmp_varchar32_utf8_nopad_bin.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_nopad_bin'; CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_nopad_bin); @@ -1505,6 +1517,31 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hellooooooooooooooooooo hellooooooooooooooooooo Hellooooooooooooooooooo hellooooooooooooooooooo +DROP TABLE t1 +CALL test04_like(32,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_nopad_bin) + +INSERT INTO t1 VALUES (REPEAT('a',32)) + +INSERT INTO t1 VALUES (REPEAT('A',32)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' ORDER BY BINARY c1 +c1 +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1518,6 +1555,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar32_utf8_unicode_ci.result b/mtr/basic/r/ctype_cmp_varchar32_utf8_unicode_ci.result index a4dc90e96..b99d0bf58 100644 --- a/mtr/basic/r/ctype_cmp_varchar32_utf8_unicode_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar32_utf8_unicode_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci'; CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci); @@ -1655,6 +1667,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hellooooooooooooooooooo hellooooooooooooooooooo Hellooooooooooooooooooo hellooooooooooooooooooo +DROP TABLE t1 +CALL test04_like(32,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci) + +INSERT INTO t1 VALUES (REPEAT('a',32)) + +INSERT INTO t1 VALUES (REPEAT('A',32)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1668,6 +1709,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar32_utf8_unicode_nopad_ci.result b/mtr/basic/r/ctype_cmp_varchar32_utf8_unicode_nopad_ci.result index ce7476101..2d9fbe274 100644 --- a/mtr/basic/r/ctype_cmp_varchar32_utf8_unicode_nopad_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar32_utf8_unicode_nopad_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci'; CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci); @@ -1251,6 +1263,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hellooooooooooooooooooo hellooooooooooooooooooo Hellooooooooooooooooooo hellooooooooooooooooooo +DROP TABLE t1 +CALL test04_like(32,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci) + +INSERT INTO t1 VALUES (REPEAT('a',32)) + +INSERT INTO t1 VALUES (REPEAT('A',32)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%' ORDER BY BINARY c1 +c1 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1264,6 +1305,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar4_latin1_bin.result b/mtr/basic/r/ctype_cmp_varchar4_latin1_bin.result index 8036e5b30..5906d4969 100644 --- a/mtr/basic/r/ctype_cmp_varchar4_latin1_bin.result +++ b/mtr/basic/r/ctype_cmp_varchar4_latin1_bin.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_bin'; CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_bin); @@ -1529,6 +1541,31 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_bin) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1542,6 +1579,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar4_latin1_nopad_bin.result b/mtr/basic/r/ctype_cmp_varchar4_latin1_nopad_bin.result index 061d3ce28..e8fb70330 100644 --- a/mtr/basic/r/ctype_cmp_varchar4_latin1_nopad_bin.result +++ b/mtr/basic/r/ctype_cmp_varchar4_latin1_nopad_bin.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_nopad_bin'; CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_nopad_bin); @@ -1505,6 +1517,31 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_nopad_bin) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1518,6 +1555,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar4_latin1_swedish_ci.result b/mtr/basic/r/ctype_cmp_varchar4_latin1_swedish_ci.result index a785bb5f9..558edd802 100644 --- a/mtr/basic/r/ctype_cmp_varchar4_latin1_swedish_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar4_latin1_swedish_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_swedish_ci'; CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_swedish_ci); @@ -1655,6 +1667,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_swedish_ci) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1668,6 +1709,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar4_latin1_swedish_nopad_ci.result b/mtr/basic/r/ctype_cmp_varchar4_latin1_swedish_nopad_ci.result index 921c212ec..3829439b8 100644 --- a/mtr/basic/r/ctype_cmp_varchar4_latin1_swedish_nopad_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar4_latin1_swedish_nopad_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_swedish_nopad_ci'; CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_swedish_nopad_ci); @@ -1539,6 +1551,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET latin1 COLLATE latin1_swedish_nopad_ci) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1552,6 +1593,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar4_utf8_bin.result b/mtr/basic/r/ctype_cmp_varchar4_utf8_bin.result index a21787bab..0534f7792 100644 --- a/mtr/basic/r/ctype_cmp_varchar4_utf8_bin.result +++ b/mtr/basic/r/ctype_cmp_varchar4_utf8_bin.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_bin'; CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_bin); @@ -1529,6 +1541,31 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_bin) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1542,6 +1579,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar4_utf8_general_ci.result b/mtr/basic/r/ctype_cmp_varchar4_utf8_general_ci.result index 33671d047..d727aa611 100644 --- a/mtr/basic/r/ctype_cmp_varchar4_utf8_general_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar4_utf8_general_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_general_ci'; CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_general_ci); @@ -1655,6 +1667,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_general_ci) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1668,6 +1709,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar4_utf8_general_nopad_ci.result b/mtr/basic/r/ctype_cmp_varchar4_utf8_general_nopad_ci.result index 520a0a4c9..eb876d6fd 100644 --- a/mtr/basic/r/ctype_cmp_varchar4_utf8_general_nopad_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar4_utf8_general_nopad_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_general_nopad_ci'; CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_general_nopad_ci); @@ -1251,6 +1263,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_general_nopad_ci) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1264,6 +1305,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar4_utf8_nopad_bin.result b/mtr/basic/r/ctype_cmp_varchar4_utf8_nopad_bin.result index a285dcb74..3ae90794b 100644 --- a/mtr/basic/r/ctype_cmp_varchar4_utf8_nopad_bin.result +++ b/mtr/basic/r/ctype_cmp_varchar4_utf8_nopad_bin.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_nopad_bin'; CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_nopad_bin); @@ -1505,6 +1517,31 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_nopad_bin) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1518,6 +1555,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar4_utf8_unicode_ci.result b/mtr/basic/r/ctype_cmp_varchar4_utf8_unicode_ci.result index 03228b93c..5451c2d6b 100644 --- a/mtr/basic/r/ctype_cmp_varchar4_utf8_unicode_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar4_utf8_unicode_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci'; CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci); @@ -1655,6 +1667,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1668,6 +1709,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/r/ctype_cmp_varchar4_utf8_unicode_nopad_ci.result b/mtr/basic/r/ctype_cmp_varchar4_utf8_unicode_nopad_ci.result index ce871b3b9..4def5914b 100644 --- a/mtr/basic/r/ctype_cmp_varchar4_utf8_unicode_nopad_ci.result +++ b/mtr/basic/r/ctype_cmp_varchar4_utf8_unicode_nopad_ci.result @@ -140,6 +140,18 @@ CALL exec('SELECT * FROM t1, t2 WHERE t1.c2=t2.c2'); CALL exec('DROP TABLE t1'); END; $$ +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN +CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); +CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); +CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); +CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); +CALL exec('DROP TABLE t1'); +END; +$$ SET NAMES utf8; SET @datatype='VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci'; CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci); @@ -1251,6 +1263,35 @@ SELECT * FROM t1, t2 WHERE t1.c2=t2.c2 c1 c2 c1 c2 Hell hell Hell hell +DROP TABLE t1 +CALL test04_like(4,@datatype); + +CREATE TABLE t1 (c1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_nopad_ci) + +INSERT INTO t1 VALUES (REPEAT('a',4)) + +INSERT INTO t1 VALUES (REPEAT('A',4)) + +SELECT * FROM t1 WHERE c1 LIKE 'a%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'A%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'aaaa%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + +SELECT * FROM t1 WHERE c1 LIKE 'AAAA%' ORDER BY BINARY c1 +c1 +AAAA +aaaa + DROP TABLE t1 DROP PROCEDURE exec; DROP PROCEDURE test01_execval; @@ -1264,6 +1305,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/t/ctype_cmp_char4_latin1_swedish_ci.test b/mtr/basic/t/ctype_cmp_char4_latin1_swedish_ci.test index 447e9f9d7..4cfc4ff6c 100644 --- a/mtr/basic/t/ctype_cmp_char4_latin1_swedish_ci.test +++ b/mtr/basic/t/ctype_cmp_char4_latin1_swedish_ci.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(4, @datatype); +CALL test04_like(4, @datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_char5_latin1_swedish_ci.test b/mtr/basic/t/ctype_cmp_char5_latin1_swedish_ci.test index 10553dd29..2b4a24b62 100644 --- a/mtr/basic/t/ctype_cmp_char5_latin1_swedish_ci.test +++ b/mtr/basic/t/ctype_cmp_char5_latin1_swedish_ci.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(5, @datatype); +CALL test04_like(5, @datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_create.inc b/mtr/basic/t/ctype_cmp_create.inc index 09690b00a..389dfcd87 100644 --- a/mtr/basic/t/ctype_cmp_create.inc +++ b/mtr/basic/t/ctype_cmp_create.inc @@ -212,3 +212,18 @@ BEGIN END; $$ DELIMITER ;$$ + +DELIMITER $$; +CREATE PROCEDURE test04_like(len INT, datatype TEXT) +BEGIN + CALL exec(REPLACE('CREATE TABLE t1 (c1 DATATYPE)', 'DATATYPE', datatype)); + CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''a'',LEN))','LEN',len)); + CALL exec(REPLACE('INSERT INTO t1 VALUES (REPEAT(''A'',LEN))','LEN',len)); + CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''a%'' ORDER BY BINARY c1'); + CALL exec('SELECT * FROM t1 WHERE c1 LIKE ''A%'' ORDER BY BINARY c1'); + CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('a',len))); + CALL exec(REPLACE('SELECT * FROM t1 WHERE c1 LIKE ''VAL%'' ORDER BY BINARY c1','VAL',REPEAT('A',len))); + CALL exec('DROP TABLE t1'); +END; +$$ +DELIMITER ;$$ diff --git a/mtr/basic/t/ctype_cmp_drop.inc b/mtr/basic/t/ctype_cmp_drop.inc index 09df0f453..59ad5b3a2 100644 --- a/mtr/basic/t/ctype_cmp_drop.inc +++ b/mtr/basic/t/ctype_cmp_drop.inc @@ -10,6 +10,7 @@ DROP PROCEDURE test02_same_table_populate; DROP PROCEDURE test02_same_table_cmp_field_field_op; DROP PROCEDURE test02_same_table_cmp_field_field; DROP PROCEDURE test03; +DROP PROCEDURE test04_like; EXECUTE IMMEDIATE CONCAT('DROP DATABASE ', @database); USE test; SET @@default_storage_engine=DEFAULT; diff --git a/mtr/basic/t/ctype_cmp_varchar32_latin1_bin.test b/mtr/basic/t/ctype_cmp_varchar32_latin1_bin.test index c6eb46435..107458fe0 100644 --- a/mtr/basic/t/ctype_cmp_varchar32_latin1_bin.test +++ b/mtr/basic/t/ctype_cmp_varchar32_latin1_bin.test @@ -22,4 +22,6 @@ DROP TABLE t1; CALL test03(32,@datatype); +CALL test04_like(32,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar32_latin1_nopad_bin.test b/mtr/basic/t/ctype_cmp_varchar32_latin1_nopad_bin.test index 8ae107467..bd138bd75 100644 --- a/mtr/basic/t/ctype_cmp_varchar32_latin1_nopad_bin.test +++ b/mtr/basic/t/ctype_cmp_varchar32_latin1_nopad_bin.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(32,@datatype); +CALL test04_like(32,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar32_latin1_swedish_ci.test b/mtr/basic/t/ctype_cmp_varchar32_latin1_swedish_ci.test index 4b10d3070..d3754d147 100644 --- a/mtr/basic/t/ctype_cmp_varchar32_latin1_swedish_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar32_latin1_swedish_ci.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(32,@datatype); +CALL test04_like(32,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar32_latin1_swedish_nopad_ci.test b/mtr/basic/t/ctype_cmp_varchar32_latin1_swedish_nopad_ci.test index b4470da69..33387efb4 100644 --- a/mtr/basic/t/ctype_cmp_varchar32_latin1_swedish_nopad_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar32_latin1_swedish_nopad_ci.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(32,@datatype); +CALL test04_like(32,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar32_utf8_bin.test b/mtr/basic/t/ctype_cmp_varchar32_utf8_bin.test index f4ed967ef..e297d41a1 100644 --- a/mtr/basic/t/ctype_cmp_varchar32_utf8_bin.test +++ b/mtr/basic/t/ctype_cmp_varchar32_utf8_bin.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(32,@datatype); +CALL test04_like(32,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar32_utf8_general_ci.test b/mtr/basic/t/ctype_cmp_varchar32_utf8_general_ci.test index 482a23f7d..e4a65d24f 100644 --- a/mtr/basic/t/ctype_cmp_varchar32_utf8_general_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar32_utf8_general_ci.test @@ -20,4 +20,6 @@ DROP TABLE t1; CALL test03(32,@datatype); +CALL test04_like(32,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar32_utf8_general_nopad_ci.test b/mtr/basic/t/ctype_cmp_varchar32_utf8_general_nopad_ci.test index de3ecbda7..c9bfb4a49 100644 --- a/mtr/basic/t/ctype_cmp_varchar32_utf8_general_nopad_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar32_utf8_general_nopad_ci.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(32,@datatype); +CALL test04_like(32,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar32_utf8_nopad_bin.test b/mtr/basic/t/ctype_cmp_varchar32_utf8_nopad_bin.test index 138ecd4a1..ac048d047 100644 --- a/mtr/basic/t/ctype_cmp_varchar32_utf8_nopad_bin.test +++ b/mtr/basic/t/ctype_cmp_varchar32_utf8_nopad_bin.test @@ -20,4 +20,6 @@ DROP TABLE t1; CALL test03(32,@datatype); +CALL test04_like(32,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar32_utf8_unicode_ci.test b/mtr/basic/t/ctype_cmp_varchar32_utf8_unicode_ci.test index 94e2e4050..f6693df1d 100644 --- a/mtr/basic/t/ctype_cmp_varchar32_utf8_unicode_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar32_utf8_unicode_ci.test @@ -20,4 +20,6 @@ DROP TABLE t1; CALL test03(32,@datatype); +CALL test04_like(32,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar32_utf8_unicode_nopad_ci.test b/mtr/basic/t/ctype_cmp_varchar32_utf8_unicode_nopad_ci.test index d8986cce7..4667bf6c8 100644 --- a/mtr/basic/t/ctype_cmp_varchar32_utf8_unicode_nopad_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar32_utf8_unicode_nopad_ci.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(32,@datatype); +CALL test04_like(32,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar4_latin1_bin.test b/mtr/basic/t/ctype_cmp_varchar4_latin1_bin.test index ed200bdaa..a4b06e663 100644 --- a/mtr/basic/t/ctype_cmp_varchar4_latin1_bin.test +++ b/mtr/basic/t/ctype_cmp_varchar4_latin1_bin.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(4,@datatype); +CALL test04_like(4,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar4_latin1_nopad_bin.test b/mtr/basic/t/ctype_cmp_varchar4_latin1_nopad_bin.test index 3b7f5a549..645ca7667 100644 --- a/mtr/basic/t/ctype_cmp_varchar4_latin1_nopad_bin.test +++ b/mtr/basic/t/ctype_cmp_varchar4_latin1_nopad_bin.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(4,@datatype); +CALL test04_like(4,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar4_latin1_swedish_ci.test b/mtr/basic/t/ctype_cmp_varchar4_latin1_swedish_ci.test index 5b76c6889..e778dd05e 100644 --- a/mtr/basic/t/ctype_cmp_varchar4_latin1_swedish_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar4_latin1_swedish_ci.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(4,@datatype); +CALL test04_like(4,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar4_latin1_swedish_nopad_ci.test b/mtr/basic/t/ctype_cmp_varchar4_latin1_swedish_nopad_ci.test index 11ca0afb6..f996b6802 100644 --- a/mtr/basic/t/ctype_cmp_varchar4_latin1_swedish_nopad_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar4_latin1_swedish_nopad_ci.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(4,@datatype); +CALL test04_like(4,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar4_utf8_bin.test b/mtr/basic/t/ctype_cmp_varchar4_utf8_bin.test index 5e87b85d8..cfad6811b 100644 --- a/mtr/basic/t/ctype_cmp_varchar4_utf8_bin.test +++ b/mtr/basic/t/ctype_cmp_varchar4_utf8_bin.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(4,@datatype); +CALL test04_like(4,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar4_utf8_general_ci.test b/mtr/basic/t/ctype_cmp_varchar4_utf8_general_ci.test index 671d94a97..38f688896 100644 --- a/mtr/basic/t/ctype_cmp_varchar4_utf8_general_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar4_utf8_general_ci.test @@ -20,4 +20,6 @@ DROP TABLE t1; CALL test03(4,@datatype); +CALL test04_like(4,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar4_utf8_general_nopad_ci.test b/mtr/basic/t/ctype_cmp_varchar4_utf8_general_nopad_ci.test index c46703699..32dc3511d 100644 --- a/mtr/basic/t/ctype_cmp_varchar4_utf8_general_nopad_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar4_utf8_general_nopad_ci.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(4,@datatype); +CALL test04_like(4,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar4_utf8_nopad_bin.test b/mtr/basic/t/ctype_cmp_varchar4_utf8_nopad_bin.test index 8c4044556..805b2484e 100644 --- a/mtr/basic/t/ctype_cmp_varchar4_utf8_nopad_bin.test +++ b/mtr/basic/t/ctype_cmp_varchar4_utf8_nopad_bin.test @@ -20,4 +20,6 @@ DROP TABLE t1; CALL test03(4,@datatype); +CALL test04_like(4,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar4_utf8_unicode_ci.test b/mtr/basic/t/ctype_cmp_varchar4_utf8_unicode_ci.test index 9f406c784..d7ae694c9 100644 --- a/mtr/basic/t/ctype_cmp_varchar4_utf8_unicode_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar4_utf8_unicode_ci.test @@ -20,4 +20,6 @@ DROP TABLE t1; CALL test03(4,@datatype); +CALL test04_like(4,@datatype); + --source ctype_cmp_drop.inc diff --git a/mtr/basic/t/ctype_cmp_varchar4_utf8_unicode_nopad_ci.test b/mtr/basic/t/ctype_cmp_varchar4_utf8_unicode_nopad_ci.test index 80e59d427..93a4c9ff7 100644 --- a/mtr/basic/t/ctype_cmp_varchar4_utf8_unicode_nopad_ci.test +++ b/mtr/basic/t/ctype_cmp_varchar4_utf8_unicode_nopad_ci.test @@ -21,4 +21,6 @@ DROP TABLE t1; CALL test03(4,@datatype); +CALL test04_like(4,@datatype); + --source ctype_cmp_drop.inc diff --git a/primitives/linux-port/column.cpp b/primitives/linux-port/column.cpp index 7f42e1655..7dea1bb4e 100644 --- a/primitives/linux-port/column.cpp +++ b/primitives/linux-port/column.cpp @@ -65,9 +65,6 @@ inline uint64_t order_swap(uint64_t x) return ret; } -template -inline string fixChar(int64_t intval); - template inline int compareBlock( const void* a, const void* b ) { @@ -90,23 +87,6 @@ void logIt(int mid, int arg1, const string& arg2 = string()) logger.logErrorMessage(msg); } -//FIXME: what are we trying to accomplish here? It looks like we just want to count -// the chars in a string arg? -p_DataValue convertToPDataValue(const void* val, int W) -{ - p_DataValue dv; - string str; - - if (8 == W) - str = fixChar<8>(*reinterpret_cast(val)); - else - str = reinterpret_cast(val); - - dv.len = static_cast(str.length()); - dv.data = reinterpret_cast(val); - return dv; -} - template inline bool colCompare_(const T& val1, const T& val2, uint8_t COP) @@ -146,35 +126,14 @@ inline bool colCompareStr(const ColRequestHeaderDataType &type, const utils::ConstString &val1, const utils::ConstString &val2) { - int res = type.strnncollsp(val1, val2); - - switch (COP) + int error = 0; + bool rc = primitives::StringComparator(type).op(&error, COP, val1, val2); + if (error) { - case COMPARE_NIL: - return false; - - case COMPARE_LT: - return res < 0; - - case COMPARE_EQ: - return res == 0; - - case COMPARE_LE: - return res <= 0; - - case COMPARE_GT: - return res > 0; - - case COMPARE_NE: - return res != 0; - - case COMPARE_GE: - return res >= 0; - - default: - logIt(34, COP, "colCompareStr"); - return false; // throw an exception here? + logIt(34, COP, "colCompareStr"); + return false; // throw an exception here? } + return rc; } @@ -210,20 +169,9 @@ inline bool colCompare_(const T& val1, const T& val2, uint8_t COP, uint8_t rf) } } -bool isLike(const char* val, const idb_regex_t* regex) -{ - if (!regex) - throw runtime_error("PrimitiveProcessor::isLike: Missing regular expression for LIKE operator"); - -#ifdef POSIX_REGEX - return (regexec(®ex->regex, val, 0, NULL, 0) == 0); -#else - return regex_match(val, regex->regex); -#endif -} //@bug 1828 Like must be a string compare. -inline bool colStrCompare_(uint64_t val1, uint64_t val2, uint8_t COP, uint8_t rf, const idb_regex_t* regex) +inline bool colStrCompare_(uint64_t val1, uint64_t val2, uint8_t COP, uint8_t rf) { switch (COP) { @@ -250,66 +198,12 @@ inline bool colStrCompare_(uint64_t val1, uint64_t val2, uint8_t COP, uint8_t rf case COMPARE_LIKE: case COMPARE_NLIKE: - { - /* LIKE comparisons are string comparisons so we reverse the order again. - Switching the order twice is probably as efficient as evaluating a guard. */ - char tmp[9]; - val1 = order_swap(val1); - memcpy(tmp, &val1, 8); - tmp[8] = '\0'; - return (COP & COMPARE_NOT ? !isLike(tmp, regex) : isLike(tmp, regex)); - } - default: logIt(34, COP, "colCompare_l"); return false; // throw an exception here? } } -#if 0 -inline bool colStrCompare_(uint64_t val1, uint64_t val2, uint8_t COP, const idb_regex_t* regex) -{ - switch (COP) - { - case COMPARE_NIL: - return false; - - case COMPARE_LT: - return val1 < val2; - - case COMPARE_LE: - return val1 <= val2; - - case COMPARE_EQ: - return val1 == val2; - - case COMPARE_NE: - return val1 != val2; - - case COMPARE_GE: - return val1 >= val2; - - case COMPARE_GT: - return val1 > val2; - - case COMPARE_LIKE: - case COMPARE_NOT | COMPARE_LIKE: - { - /* LIKE comparisons are string comparisons so we reverse the order again. - Switching the order twice is probably as efficient as evaluating a guard. */ - char tmp[9]; - val1 = order_swap(val1); - memcpy(tmp, &val1, 8); - tmp[8] = '\0'; - return (COP & COMPARE_NOT ? !isLike(tmp, regex) : isLike(tmp, regex)); - } - - default: - logIt(34, COP, "colCompare"); - return false; // throw an exception here? - } -} -#endif template inline bool isEmptyVal(uint8_t type, const uint8_t* val8); @@ -663,20 +557,10 @@ inline bool isMinMaxValid(const NewColRequestHeader* in) } } -//char(8) values lose their null terminator -template -inline string fixChar(int64_t intval) -{ - char chval[W + 1]; - memcpy(chval, &intval, W); - chval[W] = '\0'; - - return string(chval); -} inline bool colCompare(int64_t val1, int64_t val2, uint8_t COP, uint8_t rf, const ColRequestHeaderDataType &typeHolder, uint8_t width, - const idb_regex_t& regex, bool isNull = false) + bool isNull = false) { uint8_t type = typeHolder.DataType; // cout << "comparing " << hex << val1 << " to " << val2 << endl; @@ -705,7 +589,15 @@ inline bool colCompare(int64_t val1, int64_t val2, uint8_t COP, uint8_t rf, else if ( (type == CalpontSystemCatalog::CHAR || type == CalpontSystemCatalog::VARCHAR || type == CalpontSystemCatalog::TEXT) && !isNull ) { - if (!regex.used && !rf) + if (COP & COMPARE_LIKE) // LIKE and NOT LIKE + { + utils::ConstString subject = {reinterpret_cast(&val1), width}; + utils::ConstString pattern = {reinterpret_cast(&val2), width}; + return typeHolder.like(COP & COMPARE_NOT, subject.rtrimZero(), + pattern.rtrimZero()); + } + + if (!rf) { // A temporary hack for xxx_nopad_bin collations // TODO: MCOL-4534 Improve comparison performance in 8bit nopad_bin collations @@ -717,7 +609,7 @@ inline bool colCompare(int64_t val1, int64_t val2, uint8_t COP, uint8_t rf, return colCompareStr(typeHolder, COP, s1.rtrimZero(), s2.rtrimZero()); } else - return colStrCompare_(order_swap(val1), order_swap(val2), COP, rf, ®ex); + return colStrCompare_(order_swap(val1), order_swap(val2), COP, rf); } /* isNullVal should work on the normalized value on little endian machines */ @@ -745,7 +637,7 @@ inline bool colCompare(int128_t val1, int128_t val2, uint8_t COP, uint8_t rf, in return false; } -inline bool colCompareUnsigned(uint64_t val1, uint64_t val2, uint8_t COP, uint8_t rf, int type, uint8_t width, const idb_regex_t& regex, bool isNull = false) +inline bool colCompareUnsigned(uint64_t val1, uint64_t val2, uint8_t COP, uint8_t rf, int type, uint8_t width, bool isNull = false) { // cout << "comparing unsigned" << hex << val1 << " to " << val2 << endl; @@ -1159,113 +1051,8 @@ inline int64_t nextColValueHelper(int type, /*NOTREACHED*/ return 0; } -#if 0 -inline void p_Col_noprid(const NewColRequestHeader* in, NewColResultHeader* out, - unsigned outSize, unsigned* written, int* block) -{ - int argIndex, argOffset; - uint16_t rid; - const ColArgs* args; - const uint8_t* in8 = reinterpret_cast(in); - int64_t argVal, colVal; - uint64_t uargVal, ucolVal; - int8_t* val8 = reinterpret_cast(block); - int16_t* val16 = reinterpret_cast(block); - int32_t* val32 = reinterpret_cast(block); - int64_t* val64 = reinterpret_cast(block); - uint8_t* uval8 = reinterpret_cast(block); - uint16_t* uval16 = reinterpret_cast(block); - uint32_t* uval32 = reinterpret_cast(block); - uint64_t* uval64 = reinterpret_cast(block); - - placeholderRegex.used = false; - - //cout << "NOPRID" << endl; - - for (argIndex = 0; argIndex < in->NVALS; argIndex++) - { - argOffset = sizeof(NewColRequestHeader) + (argIndex * (sizeof(ColArgs) + - sizeof(int16_t) + in->DataSize)); - args = reinterpret_cast(&in8[argOffset]); - - rid = *reinterpret_cast(&in8[argOffset + sizeof(ColArgs) + - in->DataSize]); - - if (isUnsigned((CalpontSystemCatalog::ColDataType)in->colType.DataType)) - { - switch (in->DataSize) - { - case 1: - uargVal = *reinterpret_cast(args->val[0]); - ucolVal = uval8[rid]; - break; - - case 2: - uargVal = *reinterpret_cast(args->val); - ucolVal = uval16[rid]; - break; - - case 4: - uargVal = *reinterpret_cast(args->val); - ucolVal = uval32[rid]; - break; - - case 8: - uargVal = *reinterpret_cast(args->val); - ucolVal = uval64[rid]; - break; - - default: - logIt(33, in->DataSize); -#ifdef PRIM_DEBUG - throw logic_error("PrimitiveProcessor::p_Col_noprid(): bad width"); -#endif - return; - } - - if (colCompare(ucolVal, uargVal, args->COP, args->rf, in->colType.DataType, in->DataSize, placeholderRegex)) - store(in, out, outSize, written, rid, reinterpret_cast(block)); - } - else - { - switch (in->DataSize) - { - case 1: - argVal = args->val[0]; - colVal = val8[rid]; - break; - - case 2: - argVal = *reinterpret_cast(args->val); - colVal = val16[rid]; - break; - - case 4: - argVal = *reinterpret_cast(args->val); - colVal = val32[rid]; - break; - - case 8: - argVal = *reinterpret_cast(args->val); - colVal = val64[rid]; - break; - - default: - logIt(33, in->DataSize); -#ifdef PRIM_DEBUG - throw logic_error("PrimitiveProcessor::p_Col_noprid(): bad width"); -#endif - return; - } - - if (colCompare(colVal, argVal, args->COP, args->rf, in->colType.DataType, in->DataSize, placeholderRegex)) - store(in, out, outSize, written, rid, reinterpret_cast(block)); - } - } -} -#endif template inline void p_Col_ridArray(NewColRequestHeader* in, NewColResultHeader* out, @@ -1276,9 +1063,6 @@ inline void p_Col_ridArray(NewColRequestHeader* in, uint16_t* ridArray = 0; uint8_t* in8 = reinterpret_cast(in); const uint8_t filterSize = sizeof(uint8_t) + sizeof(uint8_t) + W; - idb_regex_t placeholderRegex; - - placeholderRegex.used = false; if (in->NVALS > 0) ridArray = reinterpret_cast(&in8[sizeof(NewColRequestHeader) + @@ -1335,16 +1119,9 @@ inline void p_Col_ridArray(NewColRequestHeader* in, uint8_t* cops = NULL; uint8_t* rfs = NULL; - scoped_array std_regex; - idb_regex_t* regex = NULL; - uint8_t likeOps = 0; - // no pre-parsed column filter is set, parse the filter in the message if (parsedColumnFilter.get() == NULL) { - std_regex.reset(new idb_regex_t[in->NOPS]); - regex = &(std_regex[0]); - if (isUnsigned((CalpontSystemCatalog::ColDataType)in->colType.DataType)) { uargVals = reinterpret_cast(std_argVals); @@ -1376,8 +1153,6 @@ inline void p_Col_ridArray(NewColRequestHeader* in, uargVals[argIndex] = *reinterpret_cast(args->val); break; } - - regex[argIndex].used = false; } } else @@ -1424,21 +1199,6 @@ inline void p_Col_ridArray(NewColRequestHeader* in, argVals[argIndex] = *reinterpret_cast(args->val); break; } - - if (COMPARE_LIKE & args->COP) - { - p_DataValue dv = convertToPDataValue(&argVals[argIndex], W); - int err = PrimitiveProcessor::convertToRegexp(®ex[argIndex], &dv); - - if (err) - { - throw runtime_error("PrimitiveProcessor::p_Col_ridarray(): Could not create regular expression for LIKE operator"); - } - - ++likeOps; - } - else - regex[argIndex].used = false; } } } @@ -1449,9 +1209,6 @@ inline void p_Col_ridArray(NewColRequestHeader* in, uargVals = reinterpret_cast(parsedColumnFilter->prestored_argVals.get()); cops = parsedColumnFilter->prestored_cops.get(); rfs = parsedColumnFilter->prestored_rfs.get(); - regex = parsedColumnFilter->prestored_regex.get(); - likeOps = parsedColumnFilter->likeOps; - } // else we have a pre-parsed filter, and it's an unordered set for quick == comparisons @@ -1508,12 +1265,12 @@ inline void p_Col_ridArray(NewColRequestHeader* in, if (isUnsigned((CalpontSystemCatalog::ColDataType)in->colType.DataType)) { cmp = colCompareUnsigned(uval, uargVals[argIndex], cops[argIndex], - rfs[argIndex], in->colType.DataType, W, regex[argIndex], isNull); + rfs[argIndex], in->colType.DataType, W, isNull); } else { cmp = colCompare(val, argVals[argIndex], cops[argIndex], - rfs[argIndex], in->colType, W, regex[argIndex], isNull); + rfs[argIndex], in->colType, W, isNull); } if (in->NOPS == 1) @@ -1551,10 +1308,10 @@ inline void p_Col_ridArray(NewColRequestHeader* in, in->colType.DataType == CalpontSystemCatalog::BLOB || in->colType.DataType == CalpontSystemCatalog::TEXT ) && 1 < W) { - if (colCompare(out->Min, val, COMPARE_GT, false, in->colType, W, placeholderRegex)) + if (colCompare(out->Min, val, COMPARE_GT, false, in->colType, W)) out->Min = val; - if (colCompare(out->Max, val, COMPARE_LT, false, in->colType, W, placeholderRegex)) + if (colCompare(out->Max, val, COMPARE_LT, false, in->colType, W)) out->Max = val; } else if (isUnsigned((CalpontSystemCatalog::ColDataType)in->colType.DataType)) @@ -1612,8 +1369,6 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in, uint16_t* ridArray = 0; uint8_t* in8 = reinterpret_cast(in); const uint8_t filterSize = sizeof(uint8_t) + sizeof(uint8_t) + W; - idb_regex_t placeholderRegex; - placeholderRegex.used = false; if (in->NVALS > 0) ridArray = reinterpret_cast(&in8[sizeof(NewColRequestHeader) + @@ -1670,13 +1425,8 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in, uint8_t* cops = NULL; uint8_t* rfs = NULL; - scoped_array std_regex; - idb_regex_t* regex = NULL; - // no pre-parsed column filter is set, parse the filter in the message if (parsedColumnFilter.get() == NULL) { - std_regex.reset(new idb_regex_t[in->NOPS]); - regex = &(std_regex[0]); cops = std_cops; rfs = std_rfs; @@ -1688,7 +1438,6 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in, rfs[argIndex] = args->rf; memcpy(argVals[argIndex],args->val, W); - regex[argIndex].used = false; } } // we have a pre-parsed filter, and it's in the form of op and value arrays @@ -1697,7 +1446,6 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in, argVals = (binWtype*) parsedColumnFilter->prestored_argVals128.get(); cops = parsedColumnFilter->prestored_cops.get(); rfs = parsedColumnFilter->prestored_rfs.get(); - regex = parsedColumnFilter->prestored_regex.get(); } // else we have a pre-parsed filter, and it's an unordered set for quick == comparisons @@ -1780,12 +1528,12 @@ inline void p_Col_bin_ridArray(NewColRequestHeader* in, in->colType.DataType == CalpontSystemCatalog::VARCHAR) { // !!! colCompare is overloaded with int128_t only yet. - if (colCompare(out->Min, val, COMPARE_GT, false, in->colType, W, placeholderRegex)) + if (colCompare(out->Min, val, COMPARE_GT, false, in->colType, W)) { out->Min = val; } - if (colCompare(out->Max, val, COMPARE_LT, false, in->colType, W, placeholderRegex)) + if (colCompare(out->Max, val, COMPARE_LT, false, in->colType, W)) { out->Max = val; } @@ -1928,7 +1676,6 @@ boost::shared_ptr parseColumnFilter ret->prestored_argVals.reset(new int64_t[filterCount]); ret->prestored_cops.reset(new uint8_t[filterCount]); ret->prestored_rfs.reset(new uint8_t[filterCount]); - ret->prestored_regex.reset(new idb_regex_t[filterCount]); /* for (unsigned ii = 0; ii < filterCount; ii++) @@ -1936,7 +1683,6 @@ boost::shared_ptr parseColumnFilter ret->prestored_argVals[ii] = 0; ret->prestored_cops[ii] = 0; ret->prestored_rfs[ii] = 0; - ret->prestored_regex[ii].used = 0; } */ @@ -2031,23 +1777,6 @@ boost::shared_ptr parseColumnFilter // cout << "inserted* " << hex << ret->prestored_argVals[argIndex] << dec << // " COP = " << (int) ret->prestored_cops[argIndex] << endl; - if (COMPARE_LIKE & args->COP) - { - p_DataValue dv = convertToPDataValue(&ret->prestored_argVals[argIndex], colWidth); - int err = PrimitiveProcessor::convertToRegexp(&ret->prestored_regex[argIndex], &dv); - - if (err) - { - throw runtime_error("PrimitiveProcessor::parseColumnFilter(): Could not create regular expression for LIKE operator"); - } - - ++ret->likeOps; - } - else - { - ret->prestored_regex[argIndex].used = false; - } - } if (convertToSet) diff --git a/primitives/linux-port/dictionary.cpp b/primitives/linux-port/dictionary.cpp index decb4f6c7..c50154625 100644 --- a/primitives/linux-port/dictionary.cpp +++ b/primitives/linux-port/dictionary.cpp @@ -49,49 +49,27 @@ const char* signatureNotFound = joblist::CPSTRNOTFOUND.c_str(); namespace primitives { -inline bool PrimitiveProcessor::compare(int cmp, uint8_t COP, int len1, int len2) throw() +inline bool PrimitiveProcessor::compare(const datatypes::Charset &cs, uint8_t COP, + const char *str1, size_t length1, + const char *str2, size_t length2) throw() { - - switch (COP) + int error = 0; + bool rc = primitives::StringComparator(cs).op(&error, COP, + ConstString(str1, length1), + ConstString(str2, length2)); + if (error) { - case COMPARE_NIL: - return false; + MessageLog logger(LoggingID(28)); + logging::Message::Args colWidth; + Message msg(34); - case COMPARE_LT: - return cmp < 0; - - case COMPARE_EQ: - return cmp == 0; - - case COMPARE_LE: - return cmp <= 0; - - case COMPARE_GT: - return cmp > 0; - - case COMPARE_NE: - return cmp != 0; - - case COMPARE_GE: - return cmp >= 0; - - case COMPARE_LIKE: - return cmp; // is done elsewhere; shouldn't get here. Exception? - - case COMPARE_NOT: - return false; // throw an exception here? - - default: - MessageLog logger(LoggingID(28)); - logging::Message::Args colWidth; - Message msg(34); - - colWidth.add(COP); - colWidth.add("compare"); - msg.format(colWidth); - logger.logErrorMessage(msg); - return false; // throw an exception here? + colWidth.add(COP); + colWidth.add("compare"); + msg.format(colWidth); + logger.logErrorMessage(msg); + return false; // throw an exception here? } + return rc; } /* @@ -109,7 +87,7 @@ void PrimitiveProcessor::p_TokenByScan(const TokenByScanRequestHeader* h, const uint16_t* offsets; int offsetIndex, argIndex, argsOffset; bool cmpResult = false; - int tmp, i, err; + int i; const char* sig; uint16_t siglen; @@ -118,8 +96,6 @@ void PrimitiveProcessor::p_TokenByScan(const TokenByScanRequestHeader* h, int rdvOffset; uint8_t* niceRet; // ret cast to a byte-indexed type - boost::scoped_array regex; - // set up pointers to fields within each structure // either retTokens or retDataValues will be used but not both. @@ -144,36 +120,8 @@ void PrimitiveProcessor::p_TokenByScan(const TokenByScanRequestHeader* h, niceBlock = reinterpret_cast(block); offsets = reinterpret_cast(&niceBlock[10]); niceInput = reinterpret_cast(h); - - const CHARSET_INFO* cs = & datatypes::Charset(h->charsetNumber).getCharset(); - // if LIKE is an operator, compile regexp's in advance. - if ((h->NVALS > 0 && h->COP1 & COMPARE_LIKE) || - (h->NVALS == 2 && h->COP2 & COMPARE_LIKE)) - { - regex.reset(new idb_regex_t[h->NVALS]); - - for (i = 0, argsOffset = sizeof(TokenByScanRequestHeader); i < h->NVALS; i++) - { - p_DataValue pdvTmp; - - args = reinterpret_cast(&niceInput[argsOffset]); - pdvTmp.len = args->len; - pdvTmp.data = (const uint8_t*) args->data; - err = convertToRegexp(®ex[i], &pdvTmp); - - if (err != 0) - { - MessageLog logger(LoggingID(28)); - Message msg(37); - logger.logErrorMessage(msg); - - return; - } - - argsOffset += sizeof(uint16_t) + args->len; - } - } + const datatypes::Charset cs(h->charsetNumber); for (offsetIndex = 1; offsets[offsetIndex] != 0xffff; offsetIndex++) { @@ -186,7 +134,7 @@ void PrimitiveProcessor::p_TokenByScan(const TokenByScanRequestHeader* h, if (eqFilter) { - if (cs != & eqFilter->getCharset()) + if (& cs.getCharset() != & eqFilter->getCharset()) { //throw runtime_error("Collations mismatch: TokenByScanRequestHeader and DicEqualityFilter"); } @@ -200,22 +148,7 @@ void PrimitiveProcessor::p_TokenByScan(const TokenByScanRequestHeader* h, goto no_store; } - if (h->COP1 & COMPARE_LIKE) - { - p_DataValue dv; - - dv.len = siglen; - dv.data = (uint8_t*) sig; - cmpResult = isLike(&dv, ®ex[argIndex]); - - if (h->COP1 & COMPARE_NOT) - cmpResult = !cmpResult; - } - else - { - tmp = cs->strnncollsp(sig, siglen, args->data, args->len); - cmpResult = compare(tmp, h->COP1, siglen, args->len); - } + cmpResult = compare(cs, h->COP1, sig, siglen, args->data, args->len); switch (h->NVALS) { @@ -240,23 +173,7 @@ void PrimitiveProcessor::p_TokenByScan(const TokenByScanRequestHeader* h, argIndex++; args = (DataValue*) &niceInput[argsOffset]; - if (h->COP2 & COMPARE_LIKE) - { - p_DataValue dv; - - dv.len = siglen; - dv.data = (uint8_t*) sig; - cmpResult = isLike(&dv, ®ex[argIndex]); - - if (h->COP2 & COMPARE_NOT) - cmpResult = !cmpResult; - } - - else - { - tmp = cs->strnncollsp(sig, siglen, args->data, args->len); - cmpResult = compare(tmp, h->COP2, siglen, args->len); - } + cmpResult = compare(cs, h->COP2, sig, siglen, args->data, args->len); if (cmpResult) goto store; @@ -266,25 +183,10 @@ void PrimitiveProcessor::p_TokenByScan(const TokenByScanRequestHeader* h, default: { + idbassert(0); for (i = 0, cmpResult = true; i < h->NVALS; i++) { - if (h->COP1 & COMPARE_LIKE) - { - p_DataValue dv; - - dv.len = siglen; - dv.data = (uint8_t*) sig; - cmpResult = isLike(&dv, ®ex[argIndex]); - - if (h->COP1 & COMPARE_NOT) - cmpResult = !cmpResult; - } - - else - { - tmp = cs->strnncollsp(sig, siglen, args->data, args->len); - cmpResult = compare(tmp, h->COP2, siglen, args->len); - } + cmpResult = compare(cs, h->COP1, sig, siglen, args->data, args->len); if (!cmpResult && h->BOP == BOP_AND) goto no_store; @@ -507,144 +409,6 @@ again: } const char backslash = '\\'; -inline bool PrimitiveProcessor::isEscapedChar(char c) -{ - return ('%' == c || '_' == c); -} - -//FIXME: copy/pasted to dataconvert.h: refactor -int PrimitiveProcessor::convertToRegexp(idb_regex_t* regex, const p_DataValue* str) -{ - //In the worst case, every char is quadrupled, plus some leading/trailing cruft... - char* cBuf = new char[(4 * str->len) + 3]; - char c; - int i, cBufIdx = 0; - // translate to regexp symbols - cBuf[cBufIdx++] = '^'; // implicit leading anchor - - for (i = 0; i < str->len; i++) - { - c = (char) str->data[i]; - - switch (c) - { - - // chars to substitute - case '%': - cBuf[cBufIdx++] = '.'; - cBuf[cBufIdx++] = '*'; - break; - - case '_': - cBuf[cBufIdx++] = '.'; - break; - - // escape the chars that are special in regexp's but not in SQL - // default special characters in perl: .[{}()\*+?|^$ - case '.': - case '*': - case '^': - case '$': - case '?': - case '+': - case '|': - case '[': - case ']': - case '{': - case '}': - case '(': - case ')': - cBuf[cBufIdx++] = backslash; - cBuf[cBufIdx++] = c; - break; - - case backslash: //this is the sql escape char - if ( i + 1 < str->len) - { - if (isEscapedChar(str->data[i + 1])) - { - cBuf[cBufIdx++] = str->data[++i]; - break; - } - else if (backslash == str->data[i + 1]) - { - cBuf[cBufIdx++] = c; - cBuf[cBufIdx++] = str->data[++i]; - break; - } - - } //single slash - - cBuf[cBufIdx++] = backslash; - cBuf[cBufIdx++] = c; - break; - - default: - cBuf[cBufIdx++] = c; - } - } - - cBuf[cBufIdx++] = '$'; // implicit trailing anchor - cBuf[cBufIdx++] = '\0'; - -#ifdef VERBOSE - cerr << "regexified string is " << cBuf << endl; -#endif - -#ifdef POSIX_REGEX - regcomp(®ex->regex, cBuf, REG_NOSUB | REG_EXTENDED); -#else - regex->regex = cBuf; -#endif - regex->used = true; - delete [] cBuf; - return 0; -} - -bool PrimitiveProcessor::isLike(const p_DataValue* dict, const idb_regex_t* regex) throw() -{ -#ifdef POSIX_REGEX - char* cBuf = new char[dict->len + 1]; - memcpy(cBuf, dict->data, dict->len); - cBuf[dict->len] = '\0'; - - bool ret = (regexec(®ex->regex, cBuf, 0, NULL, 0) == 0); - delete [] cBuf; - return ret; -#else - /* Note, the passed-in pointers are effectively begin() and end() iterators */ - return regex_match(dict->data, dict->data + dict->len, regex->regex); -#endif -} - -boost::shared_array -PrimitiveProcessor::makeLikeFilter (const DictFilterElement* filterString, uint32_t count) -{ - boost::shared_array ret; - uint32_t filterIndex, filterOffset; - uint8_t* in8 = (uint8_t*) filterString; - const DictFilterElement* filter; - p_DataValue filterptr = {0, NULL}; - - for (filterIndex = 0, filterOffset = 0; filterIndex < count; filterIndex++) - { - filter = reinterpret_cast(&in8[filterOffset]); - - if (filter->COP & COMPARE_LIKE) - { - if (!ret) - ret.reset(new idb_regex_t[count]); - - filterptr.len = filter->len; - filterptr.data = filter->data; - convertToRegexp(&ret[filterIndex], &filterptr); - } - - filterOffset += sizeof(DictFilterElement) + filter->len; - } - - return ret; -} void PrimitiveProcessor::p_Dictionary(const DictInput* in, vector* out, @@ -662,7 +426,7 @@ void PrimitiveProcessor::p_Dictionary(const DictInput* in, uint16_t aggCount; bool cmpResult; DictOutput header; - const CHARSET_INFO* cs = & datatypes::Charset(charsetNumber).getCharset(); + const datatypes::Charset &cs(charsetNumber); // default size of the ouput to something sufficiently large to prevent // excessive reallocation and copy when resizing @@ -704,7 +468,7 @@ void PrimitiveProcessor::p_Dictionary(const DictInput* in, // len == 0 indicates this is the first pass if (max.len != 0) { - tmp = cs->strnncollsp(sigptr.data, sigptr.len, max.data, max.len); + tmp = cs.strnncollsp(sigptr.data, sigptr.len, max.data, max.len); if (tmp > 0) max = sigptr; @@ -714,7 +478,7 @@ void PrimitiveProcessor::p_Dictionary(const DictInput* in, if (min.len != 0) { - tmp = cs->strnncollsp(sigptr.data, sigptr.len, min.data, min.len); + tmp = cs.strnncollsp(sigptr.data, sigptr.len, min.data, min.len); if (tmp < 0) min = sigptr; @@ -748,18 +512,9 @@ void PrimitiveProcessor::p_Dictionary(const DictInput* in, { filter = reinterpret_cast(&in8[filterOffset]); - if (filter->COP & COMPARE_LIKE) - { - cmpResult = isLike(&sigptr, &parsedLikeFilter[filterIndex]); - - if (filter->COP & COMPARE_NOT) - cmpResult = !cmpResult; - } - else - { - tmp = cs->strnncollsp(sigptr.data, sigptr.len, filter->data, filter->len); - cmpResult = compare(tmp, filter->COP, sigptr.len, filter->len); - } + cmpResult = compare(cs, filter->COP, + (const char *) sigptr.data, sigptr.len, + (const char *) filter->data, filter->len); if (!cmpResult && in->BOP != BOP_OR) goto no_store; diff --git a/primitives/linux-port/primitiveprocessor.cpp b/primitives/linux-port/primitiveprocessor.cpp index 93caba3a0..3a8adaa4f 100644 --- a/primitives/linux-port/primitiveprocessor.cpp +++ b/primitives/linux-port/primitiveprocessor.cpp @@ -58,7 +58,7 @@ void PrimitiveProcessor::setParsedColumnFilter(boost::shared_ptr prestored_rfs; boost::shared_ptr prestored_set; boost::shared_ptr prestored_set_128; - boost::shared_array prestored_regex; - uint8_t likeOps; ParsedColumnFilter(); ~ParsedColumnFilter(); @@ -316,23 +294,15 @@ public: logicalBlockMode = b; } - - - static int convertToRegexp(idb_regex_t* regex, const p_DataValue* str); - inline static bool isEscapedChar(char c); - boost::shared_array makeLikeFilter(const DictFilterElement* inputMsg, uint32_t count); - void setLikeFilter(boost::shared_array filter) - { - parsedLikeFilter = filter; - } - private: PrimitiveProcessor(const PrimitiveProcessor& rhs); PrimitiveProcessor& operator=(const PrimitiveProcessor& rhs); int* block; - bool compare(int cmpResult, uint8_t COP, int len1, int len2) throw(); + bool compare(const datatypes::Charset &cs, uint8_t COP, + const char *str1, size_t length1, + const char *str2, size_t length2) throw(); int compare(int val1, int val2, uint8_t COP, bool lastStage) throw(); void indexWalk_1(const IndexWalkHeader* in, std::vector* out) throw(); void indexWalk_2(const IndexWalkHeader* in, std::vector* out) throw(); @@ -341,7 +311,6 @@ private: void nextSig(int NVALS, const PrimToken* tokens, p_DataValue* ret, uint8_t outputFlags = 0, bool oldGetSigBehavior = false, bool skipNulls = false) throw(); - bool isLike(const p_DataValue* dict, const idb_regex_t* arg) throw(); // void do_sum8(NewColAggResultHeader *out, int64_t val); // void do_unsignedsum8(NewColAggResultHeader *out, int64_t val); @@ -354,7 +323,6 @@ private: bool logicalBlockMode; boost::shared_ptr parsedColumnFilter; - boost::shared_array parsedLikeFilter; friend class ::PrimTest; }; diff --git a/primitives/primproc/dictstep.cpp b/primitives/primproc/dictstep.cpp index 8d509b006..fd8c3013d 100644 --- a/primitives/primproc/dictstep.cpp +++ b/primitives/primproc/dictstep.cpp @@ -145,8 +145,6 @@ void DictStep::prep(int8_t outputType, bool makeAbsRids) ? OT_RID : OT_RID | OT_DATAVALUE); primMsg->NOPS = (eqFilter ? 0 : filterCount); primMsg->NVALS = 0; - - likeFilter = bpp->pp.makeLikeFilter((DictFilterElement*) filterString.buf(), primMsg->NOPS); } void DictStep::issuePrimitive(bool isFilter) @@ -174,7 +172,6 @@ void DictStep::issuePrimitive(bool isFilter) bpp->touchedBlocks++; } - bpp->pp.setLikeFilter(likeFilter); bpp->pp.p_Dictionary(primMsg, &result, isFilter, charsetNumber, eqFilter, eqOp); } diff --git a/primitives/primproc/dictstep.h b/primitives/primproc/dictstep.h index 581a4cd14..6af6d2a95 100644 --- a/primitives/primproc/dictstep.h +++ b/primitives/primproc/dictstep.h @@ -146,7 +146,6 @@ private: bool hasEqFilter; boost::shared_ptr eqFilter; - boost::shared_array likeFilter; uint8_t eqOp; // COMPARE_EQ or COMPARE_NE friend class RTSCommand; diff --git a/utils/common/collation.h b/utils/common/collation.h index 3b58a5644..b7f8815d4 100644 --- a/utils/common/collation.h +++ b/utils/common/collation.h @@ -137,6 +137,17 @@ public: return mCharset->strnncollsp(str1.str(), str1.length(), str2.str(), str2.length()); } + int strnncollsp(const char *str1, size_t length1, + const char *str2, size_t length2) const + { + return mCharset->strnncollsp(str1, length1, str2, length2); + } + int strnncollsp(const unsigned char *str1, size_t length1, + const unsigned char *str2, size_t length2) const + { + return mCharset->strnncollsp((const char *) str1, length1, + (const char *) str2, length2); + } bool test_if_important_data(const char *str, const char *end) const { if (mCharset->state & MY_CS_NOPAD) @@ -144,6 +155,15 @@ public: return str + mCharset->scan(str, end, MY_SEQ_SPACES) < end; } + bool like(bool neg, + const utils::ConstString &subject, + const utils::ConstString &pattern) const + { + bool res= !mCharset->wildcmp(subject.str(), subject.end(), + pattern.str(), pattern.end(), + '\\','_','%'); + return neg ? !res : res; + } }; diff --git a/utils/dataconvert/dataconvert.h b/utils/dataconvert/dataconvert.h index cd06707c8..a1b413dbc 100644 --- a/utils/dataconvert/dataconvert.h +++ b/utils/dataconvert/dataconvert.h @@ -1037,12 +1037,7 @@ public: EXPORT static bool isColumnTimeValid( int64_t time ); EXPORT static bool isColumnTimeStampValid( int64_t timeStamp ); - static inline std::string constructRegexp(const std::string& str); static inline void trimWhitespace(int64_t& charData); - static inline bool isEscapedChar(char c) - { - return ('%' == c || '_' == c); - } // convert string to date EXPORT static int64_t stringToDate(const std::string& data); @@ -1303,87 +1298,6 @@ inline void DataConvert::trimWhitespace(int64_t& charData) } } -//FIXME: copy/pasted from dictionary.cpp: refactor -inline std::string DataConvert::constructRegexp(const std::string& str) -{ - //In the worst case, every char is quadrupled, plus some leading/trailing cruft... - char* cBuf = new char[(4 * str.length()) + 3]; - char c; - uint32_t i, cBufIdx = 0; - // translate to regexp symbols - cBuf[cBufIdx++] = '^'; // implicit leading anchor - - for (i = 0; i < str.length(); i++) - { - c = (char) str.c_str()[i]; - - switch (c) - { - - // chars to substitute - case '%': - cBuf[cBufIdx++] = '.'; - cBuf[cBufIdx++] = '*'; - break; - - case '_': - cBuf[cBufIdx++] = '.'; - break; - - // escape the chars that are special in regexp's but not in SQL - // default special characters in perl: .[{}()\*+?|^$ - case '.': - case '*': - case '^': - case '$': - case '?': - case '+': - case '|': - case '[': - case '{': - case '}': - case '(': - case ')': - cBuf[cBufIdx++] = '\\'; - cBuf[cBufIdx++] = c; - break; - - case '\\': //this is the sql escape char - if ( i + 1 < str.length()) - { - if (isEscapedChar(str.c_str()[i + 1])) - { - cBuf[cBufIdx++] = str.c_str()[++i]; - break; - } - else if ('\\' == str.c_str()[i + 1]) - { - cBuf[cBufIdx++] = c; - cBuf[cBufIdx++] = str.c_str()[++i]; - break; - } - - } //single slash - - cBuf[cBufIdx++] = '\\'; - cBuf[cBufIdx++] = c; - break; - - default: - cBuf[cBufIdx++] = c; - } - } - - cBuf[cBufIdx++] = '$'; // implicit trailing anchor - cBuf[cBufIdx++] = '\0'; - -#ifdef VERBOSE - cerr << "regexified string is " << cBuf << endl; -#endif - std::string ret(cBuf); - delete [] cBuf; - return ret; -} inline int128_t add128(int128_t a, int128_t b) {