diff --git a/datatypes/mcs_string.h b/datatypes/mcs_string.h new file mode 100644 index 000000000..4d177909f --- /dev/null +++ b/datatypes/mcs_string.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2020 MariaDB Corporation. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + + +#ifndef MCS_DATATYPES_STRING_H +#define MCS_DATATYPES_STRING_H + +#include "conststring.h" + +namespace datatypes +{ + +class TCharShort +{ + int64_t mValue; +public: + TCharShort(int64_t value) + :mValue(value) + { } + explicit operator utils::ConstString() const + { + utils::ConstString res = utils::ConstString((const char *) &mValue, 8); + return res.rtrimZero(); + } +}; + + +} // namespace datatypes + + +#endif // MCS_DATATYPES_STRING_H diff --git a/primitives/primproc/filtercommand.cpp b/primitives/primproc/filtercommand.cpp index ac9f8c79c..1f7e5f377 100644 --- a/primitives/primproc/filtercommand.cpp +++ b/primitives/primproc/filtercommand.cpp @@ -28,6 +28,7 @@ #include "filtercommand.h" #include "dataconvert.h" #include "mcs_decimal.h" +#include "mcs_string.h" using namespace std; using namespace messageqcpp; @@ -566,42 +567,60 @@ void StrFilterCmd::setCompareFunc(uint32_t columns) } +// TODO: +// Move this function as a method to class Charset +// and reuse it in: +// - colCompareStr() in primitives/linux-port/column.cpp +// - compareStr() in dbcon/joblist/lbidlist.cpp +// +// Note, the COMPARE_XXX constant should be put into +// a globally visible enum first, e.g. utils/common/mcs_basic_types.h +// and all "fBOP" members in all classes should be changed to this enum. + +static inline bool compareString(const datatypes::Charset &cs, + const utils::ConstString &s0, + const utils::ConstString &s1, + uint8_t fBOP) +{ + int cmp = cs.strnncollsp(s0, s1); + switch (fBOP) + { + case COMPARE_GT: + return cmp > 0; + + case COMPARE_LT: + return cmp < 0; + + case COMPARE_EQ: + return cmp == 0; + + case COMPARE_GE: + return cmp >= 0; + + case COMPARE_LE: + return cmp <= 0; + + case COMPARE_NE: + return cmp != 0; + + default: + break; + } + return false; +} + + bool StrFilterCmd::compare_cc(uint64_t i, uint64_t j) { if (execplan::isNull(bpp->fFiltCmdValues[0][i], leftColType) || execplan::isNull(bpp->fFiltCmdValues[1][j], rightColType)) return false; - switch (fBOP) - { - case COMPARE_GT: - return uint64ToStr(bpp->fFiltCmdValues[0][i]) > uint64ToStr(bpp->fFiltCmdValues[1][j]); - break; - - case COMPARE_LT: - return uint64ToStr(bpp->fFiltCmdValues[0][i]) < uint64ToStr(bpp->fFiltCmdValues[1][j]); - break; - - case COMPARE_EQ: - return uint64ToStr(bpp->fFiltCmdValues[0][i]) == uint64ToStr(bpp->fFiltCmdValues[1][j]); - break; - - case COMPARE_GE: - return uint64ToStr(bpp->fFiltCmdValues[0][i]) >= uint64ToStr(bpp->fFiltCmdValues[1][j]); - break; - - case COMPARE_LE: - return uint64ToStr(bpp->fFiltCmdValues[0][i]) <= uint64ToStr(bpp->fFiltCmdValues[1][j]); - break; - - case COMPARE_NE: - return uint64ToStr(bpp->fFiltCmdValues[0][i]) != uint64ToStr(bpp->fFiltCmdValues[1][j]); - break; - - default: - return false; - break; - } + datatypes::Charset cs(leftColType.getCharset()); + datatypes::TCharShort s0(bpp->fFiltCmdValues[0][i]); + datatypes::TCharShort s1(bpp->fFiltCmdValues[1][j]); + return compareString(cs, static_cast(s0), + static_cast(s1), fBOP); } @@ -611,36 +630,10 @@ bool StrFilterCmd::compare_ss(uint64_t i, uint64_t j) bpp->fFiltStrValues[0][i] == joblist::CPNULLSTRMARK || bpp->fFiltStrValues[1][j] == joblist::CPNULLSTRMARK) return false; - switch (fBOP) - { - case COMPARE_GT: - return bpp->fFiltStrValues[0][i] > bpp->fFiltStrValues[1][j]; - break; - - case COMPARE_LT: - return bpp->fFiltStrValues[0][i] < bpp->fFiltStrValues[1][j]; - break; - - case COMPARE_EQ: - return bpp->fFiltStrValues[0][i] == bpp->fFiltStrValues[1][j]; - break; - - case COMPARE_GE: - return bpp->fFiltStrValues[0][i] >= bpp->fFiltStrValues[1][j]; - break; - - case COMPARE_LE: - return bpp->fFiltStrValues[0][i] <= bpp->fFiltStrValues[1][j]; - break; - - case COMPARE_NE: - return bpp->fFiltStrValues[0][i] != bpp->fFiltStrValues[1][j]; - break; - - default: - return false; - break; - } + datatypes::Charset cs(leftColType.getCharset()); + utils::ConstString s0(utils::ConstString(bpp->fFiltStrValues[0][i])); + utils::ConstString s1(utils::ConstString(bpp->fFiltStrValues[1][j])); + return compareString(cs, s0, s1, fBOP); } @@ -650,39 +643,10 @@ bool StrFilterCmd::compare_cs(uint64_t i, uint64_t j) bpp->fFiltStrValues[1][j] == "" || bpp->fFiltStrValues[1][j] == joblist::CPNULLSTRMARK) return false; - int cmp = strncmp(reinterpret_cast(&bpp->fFiltCmdValues[0][i]), - bpp->fFiltStrValues[1][j].c_str(), fCharLength); - - switch (fBOP) - { - case COMPARE_GT: - return (cmp > 0); - break; - - case COMPARE_LT: - return (cmp < 0 || (cmp == 0 && fCharLength < bpp->fFiltStrValues[1][j].length())); - break; - - case COMPARE_EQ: - return (cmp == 0 && fCharLength >= bpp->fFiltStrValues[1][j].length()); - break; - - case COMPARE_GE: - return (cmp > 0 || (cmp == 0 && fCharLength >= bpp->fFiltStrValues[1][j].length())); - break; - - case COMPARE_LE: - return (cmp <= 0); - break; - - case COMPARE_NE: - return (cmp != 0 || fCharLength < bpp->fFiltStrValues[1][j].length()); - break; - - default: - return false; - break; - } + datatypes::Charset cs(leftColType.getCharset()); + datatypes::TCharShort s0(bpp->fFiltCmdValues[0][i]); + utils::ConstString s1(bpp->fFiltStrValues[1][j]); + return compareString(cs, static_cast(s0), s1, fBOP); } @@ -692,39 +656,10 @@ bool StrFilterCmd::compare_sc(uint64_t i, uint64_t j) execplan::isNull(bpp->fFiltCmdValues[1][j], rightColType)) return false; - int cmp = strncmp(bpp->fFiltStrValues[0][i].c_str(), - reinterpret_cast(&bpp->fFiltCmdValues[1][j]), fCharLength); - - switch (fBOP) - { - case COMPARE_GT: - return (cmp > 0 || (cmp == 0 && bpp->fFiltStrValues[0][i].length() > fCharLength)); - break; - - case COMPARE_LT: - return (cmp < 0); - break; - - case COMPARE_EQ: - return (cmp == 0 && bpp->fFiltStrValues[0][i].length() <= fCharLength); - break; - - case COMPARE_GE: - return (cmp >= 0); - break; - - case COMPARE_LE: - return (cmp < 0 || (cmp == 0 && bpp->fFiltStrValues[0][i].length() <= fCharLength)); - break; - - case COMPARE_NE: - return (cmp != 0 || bpp->fFiltStrValues[0][i].length() > fCharLength); - break; - - default: - return false; - break; - } + datatypes::Charset cs(leftColType.getCharset()); + utils::ConstString s0(bpp->fFiltStrValues[0][i]); + datatypes::TCharShort s1(bpp->fFiltCmdValues[1][j]); + return compareString(cs, s0, static_cast(s1), fBOP); } diff --git a/utils/common/collation.h b/utils/common/collation.h index 88cd2821a..3b58a5644 100644 --- a/utils/common/collation.h +++ b/utils/common/collation.h @@ -117,6 +117,9 @@ protected: const struct charset_info_st * mCharset; public: Charset(CHARSET_INFO & cs) :mCharset(&cs) { } + Charset(CHARSET_INFO *cs) + :mCharset(cs ? cs : &my_charset_bin) + { } Charset(uint32_t charsetNumber); CHARSET_INFO & getCharset() const { return *mCharset; } uint32_t hash(const char *data, uint64_t len) const diff --git a/utils/common/conststring.h b/utils/common/conststring.h index 67415882a..f686690af 100644 --- a/utils/common/conststring.h +++ b/utils/common/conststring.h @@ -31,6 +31,9 @@ public: ConstString(const char *str, size_t length) :mStr(str), mLength(length) { } + explicit ConstString(const std::string &str) + :mStr(str.data()), mLength(str.length()) + { } const char *str() const { return mStr; } size_t length() const { return mLength; } ConstString & rtrimZero()