1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-29 08:21:15 +03:00

Merge branch 'mariadb-corporation:develop' into develop

This commit is contained in:
Mu He
2023-04-05 18:22:52 +02:00
committed by GitHub
478 changed files with 13140 additions and 5637 deletions

View File

@ -166,7 +166,11 @@ class Charset
}
int strnncollsp(const utils::ConstString& str1, const utils::ConstString& str2) const
{
return mCharset->strnncollsp(str1.str(), str1.length(), str2.str(), str2.length());
// nullptr handling below should return values as if nulls are substituted with empty string.
// please note that ConstString has an assertion so that nullptr data has zero length.
const char* s1 = str1.str();
const char* s2 = str2.str();
return mCharset->strnncollsp(s1 ? s1 : "", str1.length(), s2 ? s2 : "" , str2.length());
}
int strnncollsp(const char* str1, size_t length1, const char* str2, size_t length2) const
{

View File

@ -21,8 +21,16 @@
namespace utils
{
const uint8_t MAXLEGACYWIDTH = 8ULL;
const uint8_t MAXCOLUMNWIDTH = 16ULL;
constexpr uint8_t MAXLEGACYWIDTH = 8ULL;
constexpr uint8_t MAXCOLUMNWIDTH = 16ULL;
struct AlignedDeleter
{
void operator()(uint8_t* ptr)
{
operator delete[](ptr, std::align_val_t(utils::MAXCOLUMNWIDTH));
};
};
inline bool isWide(uint8_t width)
{

View File

@ -38,12 +38,31 @@ class ConstString
explicit ConstString(const std::string& str) : mStr(str.data()), mLength(str.length())
{
}
template <typename T>
ConstString(const T* value, T nullValue, int colWidth)
{
if (*value == nullValue)
{
mStr = nullptr;
mLength = 0;
}
else
{
mStr = reinterpret_cast<const char*>(value);
mLength = colWidth;
}
}
const char* str() const
{
return mStr;
}
const char* end() const
{
// end() should be computed for non-nullptr mStrs, otherwise it is undefined behavior.
if (!mStr)
{
return nullptr;
}
return mStr + mLength;
}
size_t length() const
@ -61,6 +80,10 @@ class ConstString
}
bool eq(const ConstString& rhs) const
{
if (!mStr)
{
return mStr == rhs.mStr;
}
return mLength == rhs.mLength && !memcmp(mStr, rhs.mStr, mLength);
}
ConstString& rtrimZero()

217
utils/common/nullstring.h Normal file
View File

@ -0,0 +1,217 @@
/* Copyright (C) 2022, 2023 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. */
// nullstring.h
//
// A class that can reprpesent string-with-NULL (special value not representable by a string value).
#pragma once
#include <iostream>
#include <memory>
#include "exceptclasses.h"
#include "conststring.h"
namespace utils
{
// A class for striings that can hold NULL values - a value that is separate from all possible string.
class NullString
{
protected:
std::shared_ptr<std::string> mStrPtr;
public:
NullString() : mStrPtr(nullptr)
{
}
NullString(const char* str, size_t length)
{
idbassert(str != nullptr || length == 0);
if (str) {
mStrPtr.reset(new std::string((const char*)str, length));
}
}
// XXX: this constructor is used to construct NullString from char*. Please be
// aware of that - std::string(nullptr) throws exception and you should check
// for nullptr.
explicit NullString(const std::string& str) : mStrPtr(new std::string(str))
{
}
explicit NullString(const ConstString& str) : mStrPtr()
{
assign((const uint8_t*)str.str(), str.length());
}
ConstString toConstString() const
{
if (isNull())
{
return ConstString(nullptr, 0);
}
return ConstString(mStrPtr->c_str(), mStrPtr->length());
}
const char* str() const
{
if (!mStrPtr)
{
return nullptr;
}
return mStrPtr->c_str();
}
const char* end() const
{
if (!mStrPtr)
{
return nullptr;
}
return str() + length();
}
size_t length() const
{
if (!mStrPtr)
{
return 0;
}
return mStrPtr->length();
}
std::string toString() const
{
idbassert(mStrPtr);
return std::string(*mStrPtr);
}
// "unsafe" means we do not check for NULL.
// it should be used after we know there is data in NullString.
const std::string& unsafeStringRef() const
{
idbassert(mStrPtr);
return (*mStrPtr);
}
bool eq(char ch) const
{
return length() == 1 && str()[0] == ch;
}
// this is SQL-like NULL handling equality. NULL will not be equal to anything, including NULL.
bool eq(const NullString& rhs) const
{
if (!rhs.mStrPtr)
{
return false;
}
if (!mStrPtr)
{
return false;
}
return *mStrPtr == *(rhs.mStrPtr);
}
NullString& rtrimZero()
{
return *this; // TODO
}
// this can be used to safely get a string value, with default value for NULL substitution.
// it does not raise anything and provides some nonsensical default value for you that will be
// easy to find.
std::string safeString(const char* defaultValue = "<<<no default value for null provided>>>") const
{
if (!mStrPtr)
{
return std::string(defaultValue);
}
return std::string(*mStrPtr);
}
bool isNull() const
{
return !mStrPtr;
}
void resize(size_t newSize, char pad)
{
if (mStrPtr)
{
mStrPtr->resize(newSize, pad);
}
}
NullString& dropString()
{
mStrPtr.reset();
return (*this);
}
void assign(const uint8_t* p, size_t len)
{
if (!p)
{
mStrPtr.reset();
return;
}
mStrPtr.reset(new std::string((const char*)p, len));
}
void assign(const std::string& newVal)
{
mStrPtr.reset(new std::string(newVal));
}
// XXX: here we implement what Row::equals expects.
// It is not SQL-NULL-handling compatible, please beware.
bool operator ==(const NullString& a) const
{
if (!mStrPtr && !a.mStrPtr)
{
return true;
}
if (!mStrPtr)
{
return false;
}
if (!a.mStrPtr)
{
return false;
}
// fall to std::string equality.
return (*mStrPtr) == (*a.mStrPtr);
}
bool operator ==(const std::string& a) const
{
if (!mStrPtr)
{
return false;
}
// fall to std::string equality.
return (*mStrPtr) == a;
}
bool operator <(const NullString& a) const
{
// order NULLs first.
if (isNull() > a.isNull())
{
return true;
}
if (isNull() < a.isNull())
{
return false;
}
if (!isNull())
{
// fall to std::string equality.
return (*mStrPtr) < (*a.mStrPtr);
}
return false; // both are NULLs.
}
bool operator >(const NullString& a) const
{
return a < (*this);
}
};
} // namespace utils.

View File

@ -69,15 +69,17 @@ const fs::path defaultConfigFilePath(configDefaultFileName);
namespace config
{
Config* globConfigInstancePtr = nullptr;
Config::configMap_t Config::fInstanceMap;
boost::mutex Config::fInstanceMapMutex;
Config::configMap_t Config::fInstanceMap;
// duplicate to that in the Config class
boost::mutex Config::fXmlLock;
// duplicate to that in the Config class
boost::mutex Config::fWriteXmlLock;
std::atomic_bool globHasConfig;
ConfigUniqPtr globConfigInstancePtr;
void Config::checkAndReloadConfig()
{
struct stat statbuf;
@ -105,20 +107,20 @@ Config* Config::makeConfig(const string& cf)
if (globConfigInstancePtr)
{
globConfigInstancePtr->checkAndReloadConfig();
return globConfigInstancePtr;
return globConfigInstancePtr.get();
}
// Make this configurable at least at compile-time.
std::string configFilePath =
std::string(MCSSYSCONFDIR) + std::string("/columnstore/") + configDefaultFileName;
globConfigInstancePtr = new Config(configFilePath);
globConfigInstancePtr.reset(new Config(configFilePath));
globHasConfig.store(true, std::memory_order_relaxed);
return globConfigInstancePtr;
return globConfigInstancePtr.get();
}
boost::mutex::scoped_lock lk(fInstanceMapMutex);
globConfigInstancePtr->checkAndReloadConfig();
return globConfigInstancePtr;
return globConfigInstancePtr.get();
}
boost::mutex::scoped_lock lk(fInstanceMapMutex);
@ -526,21 +528,6 @@ void Config::writeConfigFile(messageqcpp::ByteStream msg) const
/* static */
void Config::deleteInstanceMap()
{
boost::mutex::scoped_lock lk(fInstanceMapMutex);
for (Config::configMap_t::iterator iter = fInstanceMap.begin(); iter != fInstanceMap.end(); ++iter)
{
Config* instance = iter->second;
delete instance;
}
fInstanceMap.clear();
if (globConfigInstancePtr)
{
delete globConfigInstancePtr;
globConfigInstancePtr = nullptr;
}
}
/* static */
@ -643,4 +630,18 @@ std::string Config::getTempFileDir(Config::TempDirPurpose what)
return {};
}
void Config::ConfigDeleter::operator()(Config* config)
{
boost::mutex::scoped_lock lk(fInstanceMapMutex);
for (Config::configMap_t::iterator iter = fInstanceMap.begin(); iter != fInstanceMap.end(); ++iter)
{
Config* instance = iter->second;
delete instance;
}
fInstanceMap.clear();
delete config;
}
} // namespace config

View File

@ -56,6 +56,11 @@ namespace config
class Config
{
public:
struct ConfigDeleter
{
void operator()(Config* config);
};
/** @brief Config factory method
*
* Creates a singleton Config object
@ -249,8 +254,14 @@ class Config
*
*/
void checkAndReloadConfig();
};
using ConfigUniqPtr = std::unique_ptr<Config, Config::ConfigDeleter>;
} // namespace config
#undef EXPORT

View File

@ -1,102 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,6,0,0
PRODUCTVERSION 4,6,0,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "InfiniDB, Inc."
VALUE "FileDescription", "InfiniDB Config API"
VALUE "FileVersion", "4.6.0-0"
VALUE "InternalName", "libconfigcpp"
VALUE "LegalCopyright", "Copyright (C) 2014"
VALUE "OriginalFilename", "libconfigcpp.dll"
VALUE "ProductName", "InfiniDB"
VALUE "ProductVersion", "4.6.0.0 Beta"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -150,6 +150,7 @@ void XMLParser::setConfig(xmlDocPtr doc, const string& section, const string& na
{
xmlAddChild(cur2, xmlNewText((const xmlChar*)"\t"));
cur3 = cur2->xmlChildrenNode;
xmlFree(cur3->content);
}
else
{

View File

@ -48,26 +48,6 @@ using namespace logging;
namespace
{
const int64_t columnstore_precision[19] = {0,
9,
99,
999,
9999,
99999,
999999,
9999999,
99999999,
999999999,
9999999999LL,
99999999999LL,
999999999999LL,
9999999999999LL,
99999999999999LL,
999999999999999LL,
9999999999999999LL,
99999999999999999LL,
999999999999999999LL};
template <class T>
bool from_string(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&))
{
@ -475,25 +455,16 @@ void number_int_value(const string& data, cscDataType typeCode,
if ((typeCode == datatypes::SystemCatalog::DECIMAL) || (typeCode == datatypes::SystemCatalog::UDECIMAL) ||
(ct.scale > 0))
{
T rangeUp, rangeLow;
if (ct.precision < 19)
auto precision =
ct.precision == rowgroup::MagicPrecisionForCountAgg ? datatypes::INT128MAXPRECISION : ct.precision;
if (precision > datatypes::INT128MAXPRECISION || precision < 0)
{
rangeUp = (T)columnstore_precision[ct.precision];
}
else
{
auto precision =
ct.precision == rowgroup::MagicPrecisionForCountAgg ? datatypes::INT128MAXPRECISION : ct.precision;
if (precision > datatypes::INT128MAXPRECISION || precision < 0)
{
throw QueryDataExcept("Unsupported precision " + std::to_string(precision) + " converting DECIMAL ",
dataTypeErr);
}
rangeUp = datatypes::ConversionRangeMaxValue[ct.precision - 19];
throw QueryDataExcept("Unsupported precision " + std::to_string(precision) + " converting DECIMAL ",
dataTypeErr);
}
rangeLow = -rangeUp;
T rangeUp = dataconvert::decimalRangeUp<T>(precision);
T rangeLow = -rangeUp;
if (intVal > rangeUp)
{
@ -2330,11 +2301,21 @@ int64_t DataConvert::dateToInt(const string& date)
return stringToDate(date);
}
int64_t DataConvert::dateToInt(const utils::NullString& date)
{
return stringToDate(date);
}
int64_t DataConvert::datetimeToInt(const string& datetime)
{
return stringToDatetime(datetime);
}
int64_t DataConvert::datetimeToInt(const utils::NullString& datetime)
{
return stringToDatetime(datetime);
}
int64_t DataConvert::timestampToInt(const string& timestamp, long timeZone)
{
return stringToTimestamp(timestamp, timeZone);
@ -2357,6 +2338,15 @@ int64_t DataConvert::stringToDate(const string& data)
else
return -1;
}
int64_t DataConvert::stringToDate(const utils::NullString& data)
{
if (data.isNull())
{
return -1;
}
return stringToDate(data.unsafeStringRef());
}
int64_t DataConvert::stringToDatetime(const string& data, bool* date)
{
@ -2368,6 +2358,20 @@ int64_t DataConvert::stringToDatetime(const string& data, bool* date)
return -1;
}
int64_t DataConvert::stringToDatetime(const utils::NullString& data, bool* date)
{
if (data.isNull())
{
if (date)
{
*date = false;
}
return -1;
}
return stringToDatetime(data.unsafeStringRef(), date);
}
int64_t DataConvert::stringToTimestamp(const string& data, long timeZone)
{
TimeStamp aTimestamp;
@ -2378,6 +2382,15 @@ int64_t DataConvert::stringToTimestamp(const string& data, long timeZone)
return -1;
}
int64_t DataConvert::stringToTimestamp(const utils::NullString& data, long timeZone)
{
if (data.isNull())
{
return -1;
}
return stringToTimestamp(data.unsafeStringRef(), timeZone);
}
/* This is really painful and expensive b/c it seems the input is not normalized or
sanitized. That should really be done on ingestion. */
int64_t DataConvert::intToDate(int64_t data)
@ -2770,6 +2783,11 @@ int64_t DataConvert::intToTime(int64_t data, bool fromString)
return getSInt64LE((const char*)&atime);
}
int64_t DataConvert::stringToTime(const utils::NullString& data)
{
return stringToTime(data.safeString(""));
}
int64_t DataConvert::stringToTime(const string& data)
{
// MySQL supported time value format 'D HHH:MM:SS.fraction'
@ -2802,7 +2820,8 @@ int64_t DataConvert::stringToTime(const string& data)
{
if (!hasDate)
{
day = strtol(data.substr(0, pos).c_str(), &end, 10);
std::string tmpDataSegment = data.substr(0, pos);
day = strtol(tmpDataSegment.c_str(), &end, 10);
if (*end != '\0')
return -1;

View File

@ -47,6 +47,8 @@
#include "bytestream.h"
#include "errorids.h"
#include "nullstring.h"
// remove this block if the htonll is defined in library
#include <endian.h>
#if __BYTE_ORDER == __BIG_ENDIAN // 4312
@ -102,6 +104,7 @@ const int64_t IDB_pow[19] = {1,
100000000000000000LL,
1000000000000000000LL};
const int32_t SECS_PER_MIN = 60;
const int32_t MINS_PER_HOUR = 60;
const int32_t HOURS_PER_DAY = 24;
@ -1239,10 +1242,13 @@ class DataConvert
// convert string to date
EXPORT static int64_t stringToDate(const std::string& data);
EXPORT static int64_t stringToDate(const utils::NullString& data);
// convert string to datetime
EXPORT static int64_t stringToDatetime(const std::string& data, bool* isDate = NULL);
EXPORT static int64_t stringToDatetime(const utils::NullString& data, bool* isDate = NULL);
// convert string to timestamp
EXPORT static int64_t stringToTimestamp(const std::string& data, long timeZone);
EXPORT static int64_t stringToTimestamp(const utils::NullString& data, long timeZone);
// convert integer to date
EXPORT static int64_t intToDate(int64_t data);
// convert integer to datetime
@ -1251,11 +1257,14 @@ class DataConvert
EXPORT static int64_t intToTime(int64_t data, bool fromString = false);
// convert string to date. alias to stringToDate
EXPORT static int64_t dateToInt(const std::string& date);
EXPORT static int64_t dateToInt(const utils::NullString& date);
// convert string to datetime. alias to datetimeToInt
EXPORT static int64_t datetimeToInt(const std::string& datetime);
EXPORT static int64_t datetimeToInt(const utils::NullString& datetime);
EXPORT static int64_t timestampToInt(const std::string& timestamp, long timeZone);
EXPORT static int64_t timeToInt(const std::string& time);
EXPORT static int64_t stringToTime(const std::string& data);
EXPORT static int64_t stringToTime(const utils::NullString& data);
// bug4388, union type conversion
EXPORT static void joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd& unionedType,
const datatypes::SystemCatalog::TypeHolderStd& type,
@ -1545,6 +1554,20 @@ inline int128_t strtoll128(const char* data, bool& saturate, char** ep)
return res;
}
template <class T>
T decimalRangeUp(int32_t precision)
{
if (precision < 19)
{
return (T)datatypes::columnstore_precision[precision];
}
else
{
return datatypes::ConversionRangeMaxValue[precision - 19];
}
}
template <>
inline int128_t string_to_ll<int128_t>(const std::string& data, bool& bSaturate)
{

View File

@ -87,7 +87,13 @@ int64_t Func_add_time::getDatetimeIntVal(rowgroup::Row& row, FunctionParm& parm,
return -1;
}
const string& val2 = parm[1]->data()->getStrVal(row, isNull);
const auto& val2 = parm[1]->data()->getStrVal(row, isNull);
if (val2.isNull())
{
isNull = true;
return -1;
}
int sign = parm[2]->data()->getIntVal(row, isNull);
DateTime dt1;
dt1.year = (val1 >> 48) & 0xffff;
@ -98,7 +104,7 @@ int64_t Func_add_time::getDatetimeIntVal(rowgroup::Row& row, FunctionParm& parm,
dt1.second = (val1 >> 20) & 0x3f;
dt1.msecond = val1 & 0xfffff;
int64_t time = DataConvert::stringToTime(val2);
int64_t time = DataConvert::stringToTime(val2.unsafeStringRef());
if (time == -1)
{
@ -165,7 +171,12 @@ int64_t Func_add_time::getTimestampIntVal(rowgroup::Row& row, FunctionParm& parm
return -1;
}
const string& val2 = parm[1]->data()->getStrVal(row, isNull);
const auto& val2 = parm[1]->data()->getStrVal(row, isNull);
if (val2.isNull())
{
isNull = true;
return -1;
}
int sign = parm[2]->data()->getIntVal(row, isNull);
DateTime dt1;
TimeStamp timestamp(val1);
@ -180,7 +191,7 @@ int64_t Func_add_time::getTimestampIntVal(rowgroup::Row& row, FunctionParm& parm
dt1.second = m_time.second;
dt1.msecond = timestamp.msecond;
int64_t time = DataConvert::stringToTime(val2);
int64_t time = DataConvert::stringToTime(val2.unsafeStringRef());
if (time == -1)
{
@ -240,7 +251,12 @@ int64_t Func_add_time::getTimeIntVal(rowgroup::Row& row, FunctionParm& parm, boo
if (isNull)
return -1;
const string& val2 = parm[1]->data()->getStrVal(row, isNull);
const auto& val2 = parm[1]->data()->getStrVal(row, isNull);
if (val2.isNull())
{
isNull = true;
return -1;
}
int sign = parm[2]->data()->getIntVal(row, isNull);
Time dt1;
dt1.day = 0;
@ -250,7 +266,7 @@ int64_t Func_add_time::getTimeIntVal(rowgroup::Row& row, FunctionParm& parm, boo
dt1.second = (val1 >> 24) & 0xff;
dt1.msecond = val1 & 0xffffff;
int64_t time = DataConvert::stringToTime(val2);
int64_t time = DataConvert::stringToTime(val2.unsafeStringRef());
if (time == -1)
{

View File

@ -47,12 +47,12 @@ CalpontSystemCatalog::ColType Func_ascii::operationType(FunctionParm& fp,
int64_t Func_ascii::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (str.empty())
if (str.isNull() || str.length() < 1)
return 0;
return (unsigned char)str[0];
return (unsigned char)(str.str())[0];
}
} // namespace funcexp

View File

@ -242,21 +242,22 @@ inline bool getBool(rowgroup::Row& row, funcexp::FunctionParm& pm, bool& isNull,
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& val = pm[0]->data()->getStrVal(row, isNull);
const string& val = pm[0]->data()->getStrVal(row, isNull).safeString("");
CHARSET_INFO& cs = datatypes::Charset(ct.charsetNumber).getCharset();
if (notBetween)
{
if (!strGE(cs, val, pm[1]->data()->getStrVal(row, isNull)) && !isNull)
if (!strGE(cs, val, pm[1]->data()->getStrVal(row, isNull).safeString("")) && !isNull)
return true;
isNull = false;
return (!strLE(cs, val, pm[2]->data()->getStrVal(row, isNull)) && !isNull);
return (!strLE(cs, val, pm[2]->data()->getStrVal(row, isNull).safeString("")) && !isNull);
}
return !isNull && strGE(cs, val, pm[1]->data()->getStrVal(row, isNull)) &&
strLE(cs, val, pm[2]->data()->getStrVal(row, isNull));
return !isNull && strGE(cs, val, pm[1]->data()->getStrVal(row, isNull).safeString("")) &&
strLE(cs, val, pm[2]->data()->getStrVal(row, isNull).safeString(""));
}
break; // XXX: gcc falsely complains here.
default:
{
@ -312,7 +313,7 @@ CalpontSystemCatalog::ColType Func_between::operationType(FunctionParm& fp,
if (cc)
{
Result result = cc->result();
result.intVal = dataconvert::DataConvert::datetimeToInt(result.strVal);
result.intVal = dataconvert::DataConvert::datetimeToInt(result.strVal.safeString(""));
cc->result(result);
}
}
@ -328,7 +329,7 @@ CalpontSystemCatalog::ColType Func_between::operationType(FunctionParm& fp,
if (cc)
{
Result result = cc->result();
result.intVal = dataconvert::DataConvert::timestampToInt(result.strVal, resultType.getTimeZone());
result.intVal = dataconvert::DataConvert::timestampToInt(result.strVal.safeString(""), resultType.getTimeZone());
cc->result(result);
}
}
@ -344,7 +345,7 @@ CalpontSystemCatalog::ColType Func_between::operationType(FunctionParm& fp,
if (cc)
{
Result result = cc->result();
result.intVal = dataconvert::DataConvert::timeToInt(result.strVal);
result.intVal = dataconvert::DataConvert::timeToInt(result.strVal.safeString(""));
cc->result(result);
}
}

View File

@ -140,7 +140,7 @@ datatypes::TUInt64Null GenericToBitOperand(Row& row, const execplan::SPTP& parm,
case execplan::CalpontSystemCatalog::TEXT:
{
bool tmpIsNull = false;
const string& str = parm->data()->getStrVal(row, tmpIsNull);
const auto& str = parm->data()->getStrVal(row, tmpIsNull).safeString("");
if (tmpIsNull)
return datatypes::TUInt64Null();

View File

@ -175,7 +175,7 @@ inline uint64_t simple_case_cmp(Row& row, FunctionParm& parm, bool& isNull,
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
const string& ev = parm[n]->data()->getStrVal(row, isNull);
const string& ev = parm[n]->data()->getStrVal(row, isNull).safeString("");
if (isNull)
break;
CHARSET_INFO* cs = parm[n]->data()->resultType().getCharset();
@ -183,7 +183,7 @@ inline uint64_t simple_case_cmp(Row& row, FunctionParm& parm, bool& isNull,
for (i = 1; i <= whereCount; i++)
{
// BUG 5362
const string& p1 = parm[i]->data()->getStrVal(row, isNull);
const string& p1 = parm[i]->data()->getStrVal(row, isNull).safeString("");
if (isNull)
break;
if (cs->strnncoll(ev.c_str(), ev.length(), p1.c_str(), p1.length()) == 0)
@ -503,7 +503,7 @@ string Func_simple_case::getStrVal(Row& row, FunctionParm& parm, bool& isNull,
if (isNull)
return string("");
return parm[i]->data()->getStrVal(row, isNull);
return parm[i]->data()->getStrVal(row, isNull).safeString("");
}
IDB_Decimal Func_simple_case::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull,
@ -642,7 +642,7 @@ string Func_searched_case::getStrVal(Row& row, FunctionParm& parm, bool& isNull,
if (isNull)
return string("");
return parm[i]->data()->getStrVal(row, isNull);
return parm[i]->data()->getStrVal(row, isNull).safeString("");
}
IDB_Decimal Func_searched_case::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull,

View File

@ -143,7 +143,7 @@ int64_t Func_cast_signed::getIntVal(Row& row, FunctionParm& parm, bool& isNull,
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& value = parm[0]->data()->getStrVal(row, isNull);
const auto& value = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
{
@ -151,7 +151,7 @@ int64_t Func_cast_signed::getIntVal(Row& row, FunctionParm& parm, bool& isNull,
return 0;
}
return atoll(value.c_str());
return atoll(value.str());
}
break;
@ -259,7 +259,7 @@ uint64_t Func_cast_unsigned::getUintVal(Row& row, FunctionParm& parm, bool& isNu
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& value = parm[0]->data()->getStrVal(row, isNull);
const auto& value = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
{
@ -267,7 +267,7 @@ uint64_t Func_cast_unsigned::getUintVal(Row& row, FunctionParm& parm, bool& isNu
return 0;
}
uint64_t ret = strtoul(value.c_str(), 0, 0);
uint64_t ret = strtoul(value.str(), 0, 0);
return ret;
}
break;
@ -336,14 +336,14 @@ string Func_cast_char::getStrVal(Row& row, FunctionParm& parm, bool& isNull,
{
// check for convert with 1 arg, return the argument
if (parm.size() == 1)
return parm[0]->data()->getStrVal(row, isNull);
return parm[0]->data()->getStrVal(row, isNull).safeString("");
;
int64_t length = parm[1]->data()->getIntVal(row, isNull);
// @bug3488, a dummy parm is appended even the optional N is not present.
if (length < 0)
return parm[0]->data()->getStrVal(row, isNull);
return parm[0]->data()->getStrVal(row, isNull).safeString("");
;
switch (parm[0]->data()->resultType().colDataType)
@ -392,15 +392,15 @@ string Func_cast_char::getStrVal(Row& row, FunctionParm& parm, bool& isNull,
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& value = parm[0]->data()->getStrVal(row, isNull);
const utils::NullString& value = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
{
isNull = true;
return value;
return string("");
}
return value.substr(0, length);
return value.safeString("").substr(0, length);
}
break;
@ -549,7 +549,7 @@ int32_t Func_cast_date::getDateIntVal(rowgroup::Row& row, FunctionParm& parm, bo
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDate(parm[0]->data()->getStrVal(row, isNull));
val = dataconvert::DataConvert::stringToDate(parm[0]->data()->getStrVal(row, isNull).safeString(""));
if (val == -1)
isNull = true;
@ -659,7 +659,7 @@ int64_t Func_cast_date::getDatetimeIntVal(rowgroup::Row& row, FunctionParm& parm
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull).safeString(""));
if (val == -1)
isNull = true;
@ -821,7 +821,7 @@ int64_t Func_cast_datetime::getDatetimeIntVal(rowgroup::Row& row, FunctionParm&
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull).safeString(""));
if (val == -1)
isNull = true;
@ -932,7 +932,7 @@ int64_t Func_cast_datetime::getTimeIntVal(rowgroup::Row& row, FunctionParm& parm
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToTime(parm[0]->data()->getStrVal(row, isNull));
val = dataconvert::DataConvert::stringToTime(parm[0]->data()->getStrVal(row, isNull).safeString(""));
if (val == -1)
isNull = true;
@ -1072,7 +1072,6 @@ IDB_Decimal Func_cast_decimal::getDecimalVal(Row& row, FunctionParm& parm, bool&
if (decimal.isTSInt128ByPrecision())
{
int128_t max_number_decimal = datatypes::ConversionRangeMaxValue[max_length - 19];
uint128_t uval = parm[0]->data()->getUintVal(row, isNull);
if (uval > (uint128_t)datatypes::Decimal::maxInt128)
@ -1286,14 +1285,14 @@ IDB_Decimal Func_cast_decimal::getDecimalVal(Row& row, FunctionParm& parm, bool&
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& strValue = parm[0]->data()->getStrVal(row, isNull);
if (strValue.empty())
const utils::NullString& strValue = parm[0]->data()->getStrVal(row, isNull);
if (strValue.isNull())
{
isNull = true;
return IDB_Decimal(); // need a null value for IDB_Decimal??
}
datatypes::DataCondition convError;
return IDB_Decimal(strValue.data(), strValue.length(), convError, decimals, max_length);
return IDB_Decimal(strValue.str(), strValue.length(), convError, decimals, max_length);
}
break;
@ -1515,9 +1514,9 @@ double Func_cast_double::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& strValue = parm[0]->data()->getStrVal(row, isNull);
const utils::NullString& strValue = parm[0]->data()->getStrVal(row, isNull);
dblval = strtod(strValue.c_str(), NULL);
dblval = strtod(strValue.str(), NULL);
}
break;

View File

@ -143,10 +143,10 @@ int64_t Func_ceil::getIntVal(Row& row, FunctionParm& parm, bool& isNull, Calpont
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (int64_t)ceil(strtod(str.c_str(), 0));
ret = (int64_t)ceil(strtod(str.str(), 0));
}
break;
@ -268,10 +268,10 @@ uint64_t Func_ceil::getUintVal(Row& row, FunctionParm& parm, bool& isNull,
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (uint64_t)ceil(strtod(str.c_str(), 0));
ret = (uint64_t)ceil(strtod(str.str(), 0));
}
break;
@ -329,10 +329,10 @@ double Func_ceil::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull,
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR || op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = ceil(strtod(str.c_str(), 0));
ret = ceil(strtod(str.str(), 0));
}
else if (op_ct.colDataType == CalpontSystemCatalog::LONGDOUBLE)
{
@ -386,10 +386,12 @@ long double Func_ceil::getLongDoubleVal(Row& row, FunctionParm& parm, bool& isNu
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR || op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = ceil(strtod(str.c_str(), 0));
{
ret = ceil(strtod(str.str(), 0));
}
}
else if (op_ct.colDataType == CalpontSystemCatalog::DECIMAL ||
op_ct.colDataType == CalpontSystemCatalog::UDECIMAL)
@ -557,10 +559,10 @@ IDB_Decimal Func_ceil::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull,
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret.value = (int64_t)ceil(strtod(str.c_str(), 0));
ret.value = (int64_t)ceil(strtod(str.str(), 0));
}
break;

View File

@ -75,11 +75,11 @@ int64_t Func_char_length::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
const string& tstr = parm[0]->data()->getStrVal(row, isNull);
const auto& tstr = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
const char* b = tstr.c_str();
const char* e = tstr.c_str() + tstr.length();
const char* b = tstr.str();
const char* e = tstr.str() + tstr.length();
return (int64_t)parm[0]->data()->resultType().getCharset()->numchars(b, e);
}

View File

@ -74,7 +74,7 @@ string Func_coalesce::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& is
for (uint32_t i = 0; i < parm.size(); i++)
{
val = parm[i]->data()->getStrVal(row, isNull);
val = parm[i]->data()->getStrVal(row, isNull).safeString("");
if (isNull)
{

View File

@ -40,7 +40,28 @@ CalpontSystemCatalog::ColType Func_concat::operationType(FunctionParm& fp,
CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
int widSum = 0;
for (const auto& fpi : fp)
{
switch (fpi->data()->resultType().colDataType)
{
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
widSum += fpi->data()->resultType().precision + 2;
break;
default:
widSum += fpi->data()->resultType().colWidth * 3; // overprovision for bytes converted into decomals.
break;
}
}
if (widSum < resultType.colWidth)
{
widSum = resultType.colWidth;
}
auto temp = fp[0]->data()->resultType();
temp.colWidth = widSum;
resultType.colWidth = widSum;
return temp;
}
// Returns the string that results from concatenating the arguments.

View File

@ -95,6 +95,7 @@ string Func_concat_ws::getStrVal(Row& row, FunctionParm& parm, bool& isNull,
#endif
string str;
string tmp;
bool firstTime = true;
for (uint32_t i = 1; i < parm.size(); i++)
{
stringValue(parm[i], row, isNull, tmp);
@ -104,18 +105,20 @@ string Func_concat_ws::getStrVal(Row& row, FunctionParm& parm, bool& isNull,
continue;
}
if (!str.empty())
if (!firstTime) // XXX: XXX: XXX: concatenation of empty strings will result in empty string.
str += delim;
firstTime = false;
// TODO: Work on string reallocation. Use std::string::resize() to
// grab larger chunks in some intellegent manner.
str += tmp;
}
if (str.empty())
if (firstTime) {
// all arguments are NULL.
isNull = true;
else
isNull = false;
return str;
}
return str;
}

View File

@ -277,7 +277,7 @@ CalpontSystemCatalog::ColType Func_conv::operationType(FunctionParm& fp,
string Func_conv::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& res = parm[0]->data()->getStrVal(row, isNull);
const auto& res = parm[0]->data()->getStrVal(row, isNull);
string str;
char ans[65];
int64_t dec;
@ -285,21 +285,19 @@ string Func_conv::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull
int64_t to_base = parm[2]->data()->getIntVal(row, isNull);
if (isNull || abs(static_cast<int>(to_base)) > 36 || abs(static_cast<int>(to_base)) < 2 ||
abs(static_cast<int>(from_base)) > 36 || abs(static_cast<int>(from_base)) < 2 || !(res.length()))
abs(static_cast<int>(from_base)) > 36 || abs(static_cast<int>(from_base)) < 2 || res.length() < 1)
{
isNull = true;
return "";
}
if (from_base < 0)
dec = convStrToNum(res, -from_base, false);
dec = convStrToNum(res.safeString(""), -from_base, false);
else
dec = (int64_t)convStrToNum(res, from_base, true);
dec = (int64_t)convStrToNum(res.safeString(""), from_base, true);
str = helpers::convNumToStr(dec, ans, to_base);
isNull = str.empty();
return str;
}

View File

@ -86,26 +86,26 @@ int64_t Func_convert_tz::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool&
return -1;
}
const string& from_tz = parm[1]->data()->getStrVal(row, isNull);
const auto& from_tz = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
{
return 0;
}
const string& to_tz = parm[2]->data()->getStrVal(row, isNull);
const auto& to_tz = parm[2]->data()->getStrVal(row, isNull);
if (isNull)
{
return 0;
}
cout << "from " << from_tz << endl;
cout << "to " << to_tz << endl;
cout << "from " << from_tz.safeString("") << endl;
cout << "to " << to_tz.safeString("") << endl;
const string& serialized_from_tzinfo = parm[3]->data()->getStrVal(row, isNull);
const string& serialized_to_tzinfo = parm[4]->data()->getStrVal(row, isNull);
const auto& serialized_from_tzinfo = parm[3]->data()->getStrVal(row, isNull);
const auto& serialized_to_tzinfo = parm[4]->data()->getStrVal(row, isNull);
if (!serialized_from_tzinfo.empty())
if (!serialized_from_tzinfo.isNull())
{
bs.append((uint8_t*)serialized_from_tzinfo.c_str(), serialized_from_tzinfo.length());
bs.append((uint8_t*)serialized_from_tzinfo.str(), serialized_from_tzinfo.length());
dataconvert::unserializeTimezoneInfo(bs, &tzinfo);
deserializeInlineVector<int64_t>(bs, ats);
tzinfo.ats = ats.data();
@ -155,7 +155,7 @@ int64_t Func_convert_tz::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool&
else
{
long from_tz_offset;
dataconvert::timeZoneToOffset(from_tz.c_str(), from_tz.size(), &from_tz_offset);
dataconvert::timeZoneToOffset(from_tz.str(), from_tz.length(), &from_tz_offset);
seconds = dataconvert::mySQLTimeToGmtSec(my_start_time, from_tz_offset, valid);
if (!valid)
{
@ -165,10 +165,10 @@ int64_t Func_convert_tz::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool&
}
}
if (!serialized_to_tzinfo.empty())
if (!serialized_to_tzinfo.isNull())
{
bs.reset();
bs.append((uint8_t*)serialized_to_tzinfo.c_str(), serialized_to_tzinfo.length());
bs.append((uint8_t*)serialized_to_tzinfo.str(), serialized_to_tzinfo.length());
dataconvert::unserializeTimezoneInfo(bs, &tzinfo);
deserializeInlineVector<int64_t>(bs, ats);
tzinfo.ats = ats.data();
@ -199,7 +199,7 @@ int64_t Func_convert_tz::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool&
else
{
long to_tz_offset;
dataconvert::timeZoneToOffset(to_tz.c_str(), to_tz.size(), &to_tz_offset);
dataconvert::timeZoneToOffset(to_tz.str(), to_tz.length(), &to_tz_offset);
dataconvert::gmtSecToMySQLTime(seconds, my_time_tmp, to_tz_offset);
}

View File

@ -55,10 +55,10 @@ int64_t Func_crc32::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNu
if (isNull)
return 0;
}
const string& b = parm[parm.size() - 1]->data()->getStrVal(row, isNull);
const auto& b = parm[parm.size() - 1]->data()->getStrVal(row, isNull);
if (isNull)
return 0;
return crc32(crc, reinterpret_cast<const uint8_t*>(b.data()), b.size());
return crc32(crc, reinterpret_cast<const uint8_t*>(b.str()), b.length());
}
} // namespace funcexp

View File

@ -143,9 +143,9 @@ int64_t Func_date::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNul
string Func_date::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
CalpontSystemCatalog::ColType&)
{
const string& val = parm[0]->data()->getStrVal(row, isNull);
const auto& val = parm[0]->data()->getStrVal(row, isNull);
return val.substr(0, 10);
return val.safeString("").substr(0, 10);
}
} // namespace funcexp

View File

@ -591,6 +591,12 @@ uint64_t dateAdd(uint64_t time, const string& expr, IntervalColumn::interval_typ
if (-day < month_length[monthSave])
{
if (monthSave == 0)
{
monthSave = 12;
tmpYear--;
}
month--;
monthSave--;
@ -613,6 +619,12 @@ uint64_t dateAdd(uint64_t time, const string& expr, IntervalColumn::interval_typ
// BUG 5448 - changed from '==' to '<='
if (day <= 0)
{
if (monthSave == 0)
{
monthSave = 12;
tmpYear--;
}
month--;
monthSave--;
@ -635,6 +647,17 @@ uint64_t dateAdd(uint64_t time, const string& expr, IntervalColumn::interval_typ
break;
}
if (monthSave == 0)
{
monthSave = 12;
tmpYear--;
if (isLeapYear(tmpYear))
month_length[2] = 29;
else
month_length[2] = 28;
}
month--;
monthSave--;
@ -737,7 +760,7 @@ int64_t Func_date_add::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& i
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull).safeString(""));
break;
}
@ -793,12 +816,12 @@ int64_t Func_date_add::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& i
if ((ct3.colDataType == execplan::CalpontSystemCatalog::CHAR ||
ct3.colDataType == execplan::CalpontSystemCatalog::TEXT ||
ct3.colDataType == execplan::CalpontSystemCatalog::VARCHAR) &&
constCol != NULL && constCol->constval().compare("SUB") == 0)
constCol != NULL && constCol->constval().safeString().compare("SUB") == 0)
funcType = OP_SUB;
else
funcType = static_cast<OpType>(parm[3]->data()->getIntVal(row, isNull));
uint64_t value = helpers::dateAdd(val, parm[1]->data()->getStrVal(row, isNull), unit, dateType, funcType);
uint64_t value = helpers::dateAdd(val, parm[1]->data()->getStrVal(row, isNull).safeString(""), unit, dateType, funcType);
if (value == 0)
isNull = true;

View File

@ -314,7 +314,7 @@ string Func_date_format::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool&
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::VARCHAR:
case CalpontSystemCatalog::TEXT:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull).safeString());
if (val == -1)
{
@ -392,7 +392,7 @@ string Func_date_format::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool&
default: isNull = true; return "";
}
const string& format = parm[1]->data()->getStrVal(row, isNull);
const string& format = parm[1]->data()->getStrVal(row, isNull).safeString("");
return helpers::IDB_date_format(dt, format);
}

View File

@ -80,7 +80,7 @@ int64_t Func_day::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull).safeString(""));
if (val == -1)
{

View File

@ -97,7 +97,7 @@ int64_t Func_dayname::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& is
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull).safeString(""));
if (val == -1)
{

View File

@ -96,20 +96,28 @@ int64_t Func_dayofweek::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool&
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
val = dataconvert::DataConvert::stringToDatetime(parm[0]->data()->getStrVal(row, isNull));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
const auto& valStr = parm[0]->data()->getStrVal(row, isNull);
if (valStr.isNull())
{
isNull = true;
return -1;
}
val = dataconvert::DataConvert::stringToDatetime(valStr.safeString(""));
if (val == -1)
{
isNull = true;
return -1;
}
else
{
year = (uint32_t)((val >> 48) & 0xffff);
month = (uint32_t)((val >> 44) & 0xf);
day = (uint32_t)((val >> 38) & 0x3f);
}
}
break;
case CalpontSystemCatalog::BIGINT:

View File

@ -54,12 +54,12 @@ CalpontSystemCatalog::ColType Func_decode::operationType(FunctionParm& fp,
string Func_decode::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
CalpontSystemCatalog::ColType&)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
{
return "";
}
const string& password = parm[1]->data()->getStrVal(row, isNull);
const auto& password = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
{
return "";
@ -72,12 +72,12 @@ string Func_decode::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNu
if (!fSeeded)
{
hash_password(fSeeds, password.c_str(), nPassLen);
hash_password(fSeeds, password.str(), nPassLen);
sql_crypt.init(fSeeds);
fSeeded = true;
}
memcpy(res.data(), str.c_str(), nStrLen);
memcpy(res.data(), str.str(), nStrLen);
sql_crypt.decode(res.data(), nStrLen);
sql_crypt.reinit();

View File

@ -168,7 +168,7 @@ inline uint64_t simple_case_cmp(Row& row, FunctionParm& parm, bool& isNull,
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
const string& ev = parm[n]->data()->getStrVal(row, isNull);
const auto& ev = parm[n]->data()->getStrVal(row, isNull);
if (isNull)
break;
CHARSET_INFO* cs = parm[n]->data()->resultType().getCharset();
@ -176,10 +176,10 @@ inline uint64_t simple_case_cmp(Row& row, FunctionParm& parm, bool& isNull,
for (i = 1; i <= whereCount; i++)
{
// BUG 5362
const string& p1 = parm[i]->data()->getStrVal(row, isNull);
const auto& p1 = parm[i]->data()->getStrVal(row, isNull);
if (isNull)
break;
if (cs->strnncoll(ev.c_str(), ev.length(), p1.c_str(), p1.length()) == 0)
if (cs->strnncoll(ev.str(), ev.length(), p1.str(), p1.length()) == 0)
{
foundIt = true;
break;
@ -463,7 +463,7 @@ string Func_decode_oracle::getStrVal(Row& row, FunctionParm& parm, bool& isNull,
if (isNull)
return string("");
return parm[i]->data()->getStrVal(row, isNull);
return parm[i]->data()->getStrVal(row, isNull).safeString("");
}
IDB_Decimal Func_decode_oracle::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull,

View File

@ -55,12 +55,12 @@ CalpontSystemCatalog::ColType Func_encode::operationType(FunctionParm& fp,
string Func_encode::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
CalpontSystemCatalog::ColType&)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
{
return "";
}
const string& password = parm[1]->data()->getStrVal(row, isNull);
const auto& password = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
{
return "";
@ -73,12 +73,12 @@ string Func_encode::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNu
if (!fSeeded)
{
hash_password(fSeeds, password.c_str(), nPassLen);
hash_password(fSeeds, password.str(), nPassLen);
sql_crypt.init(fSeeds);
fSeeded = true;
}
memcpy(res.data(), str.c_str(), nStrLen);
memcpy(res.data(), str.str(), nStrLen);
sql_crypt.encode(res.data(), nStrLen);
sql_crypt.reinit();

View File

@ -224,8 +224,8 @@ int64_t Func_extract::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& is
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
{
const string& val = parm[0]->data()->getStrVal(row, isNull);
time = dataconvert::DataConvert::stringToDatetime(val);
const auto& val = parm[0]->data()->getStrVal(row, isNull);
time = dataconvert::DataConvert::stringToDatetime(val.safeString(""));
break;
}

View File

@ -53,15 +53,15 @@ CalpontSystemCatalog::ColType Func_find_in_set::operationType(FunctionParm& fp,
int64_t Func_find_in_set::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& searchStr = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& searchStr = parm[0]->data()->getStrVal(row, isNull);
if (searchStr.isNull())
return 0;
const string& setString = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
const auto& setString = parm[1]->data()->getStrVal(row, isNull);
if (setString.isNull())
return 0;
if (searchStr.find(",") != string::npos)
if (searchStr.unsafeStringRef().find(",") != string::npos)
return 0;
if (setString.length() < searchStr.length())
@ -70,10 +70,10 @@ int64_t Func_find_in_set::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool
CHARSET_INFO* cs = op_ct.getCharset();
my_wc_t wc = 0;
const char* str_begin = setString.c_str();
const char* str_end = setString.c_str();
const char* str_begin = setString.str();
const char* str_end = setString.str();
const char* real_end = str_end + setString.length();
const char* find_str = searchStr.c_str();
const char* find_str = searchStr.str();
size_t find_str_len = searchStr.length();
int position = 0;
static const char separator = ',';

View File

@ -92,10 +92,10 @@ int64_t Func_floor::getIntVal(Row& row, FunctionParm& parm, bool& isNull,
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (int64_t)floor(strtod(str.c_str(), 0));
ret = (int64_t)floor(strtod(str.str(), 0));
}
break;
@ -194,10 +194,10 @@ uint64_t Func_floor::getUintVal(Row& row, FunctionParm& parm, bool& isNull,
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = (uint64_t)floor(strtod(str.c_str(), 0));
ret = (uint64_t)floor(strtod(str.str(), 0));
}
break;
@ -281,10 +281,10 @@ double Func_floor::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull,
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR || op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = floor(strtod(str.c_str(), 0));
ret = floor(strtod(str.str(), 0));
}
else if (op_ct.colDataType == CalpontSystemCatalog::DECIMAL ||
op_ct.colDataType == CalpontSystemCatalog::UDECIMAL)
@ -325,10 +325,10 @@ long double Func_floor::getLongDoubleVal(Row& row, FunctionParm& parm, bool& isN
else if (op_ct.colDataType == CalpontSystemCatalog::VARCHAR ||
op_ct.colDataType == CalpontSystemCatalog::CHAR || op_ct.colDataType == CalpontSystemCatalog::TEXT)
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret = floor(strtod(str.c_str(), 0));
ret = floor(strtod(str.str(), 0));
}
else if (op_ct.colDataType == CalpontSystemCatalog::DECIMAL ||
op_ct.colDataType == CalpontSystemCatalog::UDECIMAL)
@ -488,10 +488,10 @@ IDB_Decimal Func_floor::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& str = parm[0]->data()->getStrVal(row, isNull);
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (!isNull)
ret.value = (int64_t)floor(strtod(str.c_str(), 0));
ret.value = (int64_t)floor(strtod(str.str(), 0));
}
break;

View File

@ -124,8 +124,8 @@ string Func_from_unixtime::getStrVal(rowgroup::Row& row, FunctionParm& parm, boo
if (parm.size() == 2)
{
const string& format = parm[1]->data()->getStrVal(row, isNull);
return helpers::IDB_date_format(dt, format);
const auto& format = parm[1]->data()->getStrVal(row, isNull);
return helpers::IDB_date_format(dt, format.safeString(""));
}
char buf[256] = {0};

View File

@ -64,14 +64,14 @@ string Func_get_format::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool&
{
// parm[0] -- format
// parm[1] -- type
string format = parm[0]->data()->getStrVal(row, isNull);
string format = parm[0]->data()->getStrVal(row, isNull).safeString("");
if (isNull)
return "";
transform(format.begin(), format.end(), format.begin(), to_upper());
string type = parm[1]->data()->getStrVal(row, isNull);
string type = parm[1]->data()->getStrVal(row, isNull).safeString("");
if (isNull)
return "";
@ -98,7 +98,9 @@ string Func_get_format::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool&
{
case 0: return known_date_time_formats[i][2]; break;
default: return "";
default:
isNull = true;
return "";
}
}
}

View File

@ -124,22 +124,22 @@ long double Func_greatest::getLongDoubleVal(rowgroup::Row& row, FunctionParm& fp
std::string Func_greatest::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
const string& str = fp[0]->data()->getStrVal(row, isNull);
const auto& str = fp[0]->data()->getStrVal(row, isNull);
CHARSET_INFO* cs = fp[0]->data()->resultType().getCharset();
string greatestStr = str;
auto greatestStr = str;
for (uint32_t i = 1; i < fp.size(); i++)
{
const string& str1 = fp[i]->data()->getStrVal(row, isNull);
const auto& str1 = fp[i]->data()->getStrVal(row, isNull);
if (cs->strnncoll(greatestStr.c_str(), greatestStr.length(), str1.c_str(), str1.length()) < 0)
if (cs->strnncoll(greatestStr.str(), greatestStr.length(), str1.str(), str1.length()) < 0)
{
greatestStr = str1;
}
}
return greatestStr;
return greatestStr.safeString("");
}
IDB_Decimal Func_greatest::getDecimalVal(Row& row, FunctionParm& fp, bool& isNull,

View File

@ -78,10 +78,10 @@ string Func_hex::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
case CalpontSystemCatalog::DATE:
case CalpontSystemCatalog::TIME:
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
scoped_array<char> hexPtr(new char[strlen(arg.c_str()) * 2 + 1]);
octet2hex(hexPtr.get(), arg.c_str(), strlen(arg.c_str()));
return string(hexPtr.get(), strlen(arg.c_str()) * 2);
const auto& arg = parm[0]->data()->getStrVal(row, isNull);
scoped_array<char> hexPtr(new char[arg.length() * 2 + 1]); // XXX: code now the same as for BLOB.
octet2hex(hexPtr.get(), arg.str(), arg.length());
return string(hexPtr.get(), arg.length() * 2);
}
case CalpontSystemCatalog::DOUBLE:
@ -114,10 +114,10 @@ string Func_hex::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
case CalpontSystemCatalog::VARBINARY:
case CalpontSystemCatalog::BLOB:
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
uint64_t hexLen = arg.size() * 2;
const auto& arg = parm[0]->data()->getStrVal(row, isNull);
uint64_t hexLen = arg.length() * 2;
scoped_array<char> hexPtr(new char[hexLen + 1]); // "+ 1" for the last \0
octet2hex(hexPtr.get(), arg.data(), arg.size());
octet2hex(hexPtr.get(), arg.str(), arg.length());
return string(hexPtr.get(), hexLen);
}

View File

@ -51,7 +51,17 @@ bool boolVal(SPTP& parm, Row& row, long timeZone)
case CalpontSystemCatalog::CHAR:
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
ret = (atoi((char*)(parm->data()->getStrVal(timeZone).c_str())) != 0);
{
const auto& str = parm->data()->getStrVal(timeZone);
if (str.isNull())
{
ret = 0;
}
else
{
ret = (atoi((char*)(str.str())) != 0);
}
}
break;
case CalpontSystemCatalog::FLOAT:
case CalpontSystemCatalog::UFLOAT: ret = (parm->data()->getFloatVal(row, isNull) != 0); break;
@ -138,11 +148,11 @@ string Func_if::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSys
{
if (boolVal(parm[0], row, ct.getTimeZone()))
{
return parm[1]->data()->getStrVal(row, isNull);
return parm[1]->data()->getStrVal(row, isNull).safeString("");
}
else
{
return parm[2]->data()->getStrVal(row, isNull);
return parm[2]->data()->getStrVal(row, isNull).safeString("");
}
}

View File

@ -68,18 +68,15 @@ int64_t Func_ifnull::getIntVal(Row& row, FunctionParm& parm, bool& isNull, Calpo
string Func_ifnull::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&)
{
if (isNull)
return string();
const string& r = parm[0]->data()->getStrVal(row, isNull);
const auto& r = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
{
isNull = false;
return parm[1]->data()->getStrVal(row, isNull);
return parm[1]->data()->getStrVal(row, isNull).safeString("");
}
return r;
return r.safeString("");
}
IDB_Decimal Func_ifnull::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull,

View File

@ -263,7 +263,7 @@ inline bool getBoolForIn(rowgroup::Row& row, funcexp::FunctionParm& pm, bool& is
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& val = pm[0]->data()->getStrVal(row, isNull);
const auto& val = pm[0]->data()->getStrVal(row, isNull);
if (isNull)
return false;
@ -272,8 +272,8 @@ inline bool getBoolForIn(rowgroup::Row& row, funcexp::FunctionParm& pm, bool& is
for (uint32_t i = 1; i < pm.size(); i++)
{
isNull = false;
const string& str1 = pm[i]->data()->getStrVal(row, isNull);
if (cs->strnncoll(val.c_str(), val.length(), str1.c_str(), str1.length()) == 0 && !isNull)
const auto& str1 = pm[i]->data()->getStrVal(row, isNull);
if (cs->strnncoll(val.str(), val.length(), str1.str(), str1.length()) == 0 && !isNull)
return true;
if (isNull && isNotIn)

View File

@ -52,11 +52,11 @@ int64_t Func_inet_aton::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& is
int64_t iValue = joblist::NULL_INT64;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
const auto& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
if (!sValue.isNull())
{
int64_t iVal = convertAton(sValue, isNull);
int64_t iVal = convertAton(sValue.unsafeStringRef(), isNull);
if (!isNull)
iValue = iVal;
@ -76,11 +76,11 @@ double Func_inet_aton::getDoubleVal(rowgroup::Row& row, FunctionParm& fp, bool&
double dValue = doubleNullVal();
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
const auto& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
if (!sValue.isNull())
{
int64_t iValue = convertAton(sValue, isNull);
int64_t iValue = convertAton(sValue.unsafeStringRef(), isNull);
if (!isNull)
dValue = iValue;
@ -102,14 +102,18 @@ std::string Func_inet_aton::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool
{
// std::cout << "In Func_inet_aton::getStrVal" << std::endl;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
const auto& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
if (!sValue.isNull())
{
convertAton(sValue, isNull); // ignore return value
convertAton(sValue.unsafeStringRef(), isNull); // ignore return valuea
if (isNull)
{
return "";
}
}
return sValue;
return sValue.safeString("");
}
//------------------------------------------------------------------------------
@ -122,11 +126,11 @@ bool Func_inet_aton::getBoolVal(rowgroup::Row& row, FunctionParm& fp, bool& isNu
{
bool bValue = false;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
const auto& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
if (!sValue.isNull())
{
int64_t iVal = convertAton(sValue, isNull);
int64_t iVal = convertAton(sValue.unsafeStringRef(), isNull);
if ((!isNull) && (iVal != 0))
bValue = true;
@ -144,13 +148,13 @@ execplan::IDB_Decimal Func_inet_aton::getDecimalVal(rowgroup::Row& row, Function
{
execplan::CalpontSystemCatalog::ColType colType = fp[0]->data()->resultType();
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
const auto& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!datatypes::Decimal::isWideDecimalTypeByPrecision(colType.precision))
{
if (!isNull)
if (!sValue.isNull())
{
int64_t iValue = convertAton(sValue, isNull);
int64_t iValue = convertAton(sValue.unsafeStringRef(), isNull);
if (!isNull)
return execplan::IDB_Decimal(iValue, colType.scale, colType.precision);
@ -162,7 +166,7 @@ execplan::IDB_Decimal Func_inet_aton::getDecimalVal(rowgroup::Row& row, Function
{
if (!isNull)
{
int64_t iValue = convertAton(sValue, isNull);
int64_t iValue = convertAton(sValue.unsafeStringRef(), isNull);
if (!isNull)
return execplan::IDB_Decimal(0, colType.scale, colType.precision, (int128_t)iValue);
@ -182,11 +186,11 @@ int32_t Func_inet_aton::getDateIntVal(rowgroup::Row& row, FunctionParm& fp, bool
{
int32_t iValue = joblist::DATENULL;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
const auto& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
if (!sValue.isNull())
{
int64_t iVal = convertAton(sValue, isNull);
int64_t iVal = convertAton(sValue.unsafeStringRef(), isNull);
if (!isNull)
iValue = iVal;
@ -206,11 +210,11 @@ int64_t Func_inet_aton::getDatetimeIntVal(rowgroup::Row& row, FunctionParm& fp,
{
int64_t iValue = joblist::DATETIMENULL;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
const auto& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
if (!sValue.isNull())
{
int64_t iVal = convertAton(sValue, isNull);
int64_t iVal = convertAton(sValue.unsafeStringRef(), isNull);
if (!isNull)
iValue = iVal;
@ -224,11 +228,11 @@ int64_t Func_inet_aton::getTimestampIntVal(rowgroup::Row& row, FunctionParm& fp,
{
int64_t iValue = joblist::TIMESTAMPNULL;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
const auto& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
if (!sValue.isNull())
{
int64_t iVal = convertAton(sValue, isNull);
int64_t iVal = convertAton(sValue.unsafeStringRef(), isNull);
if (!isNull)
iValue = iVal;
@ -242,11 +246,11 @@ int64_t Func_inet_aton::getTimeIntVal(rowgroup::Row& row, FunctionParm& fp, bool
{
int64_t iValue = joblist::TIMENULL;
const std::string& sValue = fp[0]->data()->getStrVal(row, isNull);
const auto& sValue = fp[0]->data()->getStrVal(row, isNull);
if (!isNull)
if (!sValue.isNull())
{
int64_t iVal = convertAton(sValue, isNull);
int64_t iVal = convertAton(sValue.unsafeStringRef(), isNull);
if (!isNull)
iValue = iVal;

View File

@ -49,17 +49,17 @@ int64_t Func_instr::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNu
int64_t start0 = 0;
my_match_t match;
const std::string& str = parm[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& str = parm[0]->data()->getStrVal(row, isNull);
if (str.isNull())
return 0;
const char* s1 = str.c_str();
const char* s1 = str.str();
uint32_t l1 = (uint32_t)str.length();
const std::string& substr = parm[1]->data()->getStrVal(row, isNull);
if (isNull)
const auto& substr = parm[1]->data()->getStrVal(row, isNull);
if (substr.isNull())
return 0;
const char* s2 = substr.c_str();
const char* s2 = substr.str();
uint32_t l2 = (uint32_t)substr.length();
if (l2 < 1)
return start + 1;

View File

@ -23,7 +23,7 @@ CalpontSystemCatalog::ColType Func_json_array_append::operationType(FunctionParm
string Func_json_array_append::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto& js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
@ -33,16 +33,17 @@ string Func_json_array_append::getStrVal(rowgroup::Row& row, FunctionParm& fp, b
const uchar* arrEnd;
size_t strRestLen;
string retJS;
retJS.reserve(js.size() + padding);
retJS.reserve(js.length() + padding);
initJSPaths(paths, fp, 1, 2);
string tmpJS{js};
utils::NullString tmpJS(js);
for (size_t i = 1, j = 0; i < fp.size(); i += 2, j++)
{
const char* rawJS = tmpJS.data();
const size_t jsLen = tmpJS.size();
const char* rawJS = tmpJS.str();
const size_t jsLen = tmpJS.length();
JSONPath& path = paths[j];
if (!path.parsed && parseJSPath(path, row, fp[i], false))
goto error;
@ -77,7 +78,6 @@ string Func_json_array_append::getStrVal(rowgroup::Row& row, FunctionParm& fp, b
/* Wrap as an array. */
retJS.append(rawJS, (const char*)jsEg.value_begin - rawJS);
start = jsEg.value_begin;
if (jsEg.value_type == JSON_VALUE_OBJECT)
{
if (json_skip_level(&jsEg))
@ -97,7 +97,7 @@ string Func_json_array_append::getStrVal(rowgroup::Row& row, FunctionParm& fp, b
}
// tmpJS save the json string for next loop
tmpJS.swap(retJS);
tmpJS.assign(retJS);
retJS.clear();
}

View File

@ -23,7 +23,7 @@ CalpontSystemCatalog::ColType Func_json_array_insert::operationType(FunctionParm
string Func_json_array_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto& js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
@ -31,15 +31,15 @@ string Func_json_array_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, b
json_engine_t jsEg;
string retJS;
retJS.reserve(js.size() + 8);
retJS.reserve(js.length() + 8);
initJSPaths(paths, fp, 1, 2);
string tmpJS{js};
utils::NullString tmpJS(js);
for (size_t i = 1, j = 0; i < fp.size(); i += 2, j++)
{
const char* rawJS = tmpJS.data();
const size_t jsLen = tmpJS.size();
const char* rawJS = tmpJS.str();
const size_t jsLen = tmpJS.length();
JSONPath& path = paths[j];
if (!path.parsed)
{
@ -122,7 +122,7 @@ string Func_json_array_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, b
}
// tmpJS save the json string for next loop
tmpJS.swap(retJS);
tmpJS.assign(retJS);
retJS.clear();
}

View File

@ -160,8 +160,8 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
CalpontSystemCatalog::ColType& type)
{
bool isNullJS = false, isNullVal = false;
const string_view js = fp[0]->data()->getStrVal(row, isNullJS);
const string_view val = fp[1]->data()->getStrVal(row, isNullVal);
const auto& js = fp[0]->data()->getStrVal(row, isNullJS);
const auto& val = fp[1]->data()->getStrVal(row, isNullVal);
if (isNullJS || isNullVal)
{
isNull = true;

View File

@ -28,10 +28,12 @@ CalpontSystemCatalog::ColType Func_json_contains_path::operationType(
bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto& js_ns = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return false;
const string_view js = js_ns.unsafeStringRef();
#ifdef MYSQL_GE_1009
int arrayCounters[JSON_DEPTH_LIMIT];
bool hasNegPath = false;
@ -43,9 +45,10 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul
if (!isModeConst)
isModeConst = (dynamic_cast<ConstantColumn*>(fp[1]->data()) != nullptr);
string mode = fp[1]->data()->getStrVal(row, isNull);
auto mode_ns = fp[1]->data()->getStrVal(row, isNull);
if (isNull)
return false;
string mode = mode_ns.unsafeStringRef();
transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
if (mode != "one" && mode != "all")

View File

@ -22,7 +22,7 @@ CalpontSystemCatalog::ColType Func_json_depth::operationType(FunctionParm& fp,
int64_t Func_json_depth::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return 0;

View File

@ -44,14 +44,17 @@ bool Func_json_equals::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
return true;
}
const string_view js1 = fp[0]->data()->getStrVal(row, isNull);
const auto js1_ns = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return false;
const string_view js2 = fp[1]->data()->getStrVal(row, isNull);
const auto js2_ns = fp[1]->data()->getStrVal(row, isNull);
if (isNull)
return false;
const string_view js1 = js1_ns.unsafeStringRef();
const string_view js2 = js2_ns.unsafeStringRef();
bool result = false;
if (json_normalize(str1.get(), js1.data(), js1.size(), getCharset(fp[0])))
{

View File

@ -24,7 +24,7 @@ CalpontSystemCatalog::ColType Func_json_exists::operationType(FunctionParm& fp,
bool Func_json_exists::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return false;

View File

@ -17,10 +17,10 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t
bool compareWhole = true)
{
bool isNull = false;
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return 1;
const char* rawJS = js.data();
const char* rawJS = js.str();
json_engine_t jsEg, savJSEg;
json_path_t p;
const uchar* value;
@ -43,7 +43,7 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t
JSONPath& path = paths[i - 1];
path.p.types_used = JSON_PATH_KEY_NULL;
if (!path.parsed && parseJSPath(path, row, fp[i]))
goto error;
return 1;
#ifdef MYSQL_GE_1009
hasNegPath |= path.p.types_used & JSON_PATH_NEGATIVE_INDEX;
@ -66,14 +66,14 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t
retJS.append("[");
}
json_get_path_start(&jsEg, getCharset(fp[0]), (const uchar*)rawJS, (const uchar*)rawJS + js.size(), &p);
json_get_path_start(&jsEg, getCharset(fp[0]), (const uchar*)rawJS, (const uchar*)rawJS + js.length(), &p);
while (json_get_path_next(&jsEg, &p) == 0)
{
#ifdef MYSQL_GE_1009
if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY &&
json_skip_array_and_count(&jsEg, arrayCounter + (p.last_step - p.steps)))
goto error;
return 1;
#endif
#ifdef MYSQL_GE_1009
@ -91,7 +91,7 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t
/* we only care about the first found value */
if (!compareWhole)
{
retJS = js;
retJS = js.safeString("");
return 0;
}
@ -102,7 +102,7 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t
if (mayMulVal)
savJSEg = jsEg;
if (json_skip_level(&jsEg))
goto error;
return 1;
valLen = jsEg.s.c_str - value;
if (mayMulVal)
jsEg = savJSEg;
@ -125,26 +125,25 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t
}
if (unlikely(jsEg.s.error))
goto error;
return 1;
if (!notFirstVal)
/* Nothing was found. */
goto error;
return 1;
if (mayMulVal)
retJS.append("]");
initJSEngine(jsEg, getCharset(fp[0]), retJS);
utils::NullString retJS_ns(retJS);
initJSEngine(jsEg, getCharset(fp[0]), retJS_ns);
if (doFormat(&jsEg, tmp, Func_json_format::LOOSE))
goto error;
return 1;
retJS.clear();
retJS.swap(tmp);
return 0;
error:
return 1;
}
CalpontSystemCatalog::ColType Func_json_extract::operationType(FunctionParm& fp,

View File

@ -25,7 +25,7 @@ CalpontSystemCatalog::ColType Func_json_format::operationType(FunctionParm& fp,
string Func_json_format::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto& js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";

View File

@ -23,7 +23,7 @@ CalpontSystemCatalog::ColType Func_json_insert::operationType(FunctionParm& fp,
string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto& js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
@ -41,11 +41,11 @@ string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
// Save the result of each merge and the result of the final merge separately
string retJS;
string tmpJS{js};
utils::NullString tmpJS(js);
for (size_t i = 1, j = 0; i < fp.size(); i += 2, j++)
{
const char* rawJS = tmpJS.data();
const size_t jsLen = tmpJS.size();
const char* rawJS = tmpJS.str();
const size_t jsLen = tmpJS.length();
JSONPath& path = paths[j];
const json_path_step_t* lastStep;
@ -226,7 +226,7 @@ string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
continue_point:
// tmpJS save the json string for next loop
tmpJS.swap(retJS);
tmpJS.assign(retJS);
retJS.clear();
}

View File

@ -54,10 +54,10 @@ CalpontSystemCatalog::ColType Func_json_keys::operationType(FunctionParm& fp,
string Func_json_keys::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
IntType keySize = 0;
string ret;
json_engine_t jsEg;

View File

@ -23,7 +23,7 @@ CalpontSystemCatalog::ColType Func_json_length::operationType(FunctionParm& fp,
int64_t Func_json_length::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto& js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return 0;

View File

@ -217,7 +217,7 @@ CalpontSystemCatalog::ColType Func_json_merge::operationType(FunctionParm& fp,
string Func_json_merge::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
@ -225,12 +225,12 @@ string Func_json_merge::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is
json_engine_t jsEg1, jsEg2;
string tmpJS{js};
utils::NullString tmpJS(js);
string retJS;
for (size_t i = 1; i < fp.size(); i++)
{
const string_view js2 = fp[i]->data()->getStrVal(row, isNull);
const auto js2 = fp[i]->data()->getStrVal(row, isNull);
if (isNull)
goto error;
@ -241,7 +241,7 @@ string Func_json_merge::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is
goto error;
// tmpJS save the merge result for next loop
tmpJS.swap(retJS);
tmpJS.assign(retJS);
retJS.clear();
}

View File

@ -71,8 +71,14 @@ int copyValuePatch(string& retJS, json_engine_t* jsEg)
int doMergePatch(string& retJS, json_engine_t* jsEg1, json_engine_t* jsEg2, bool& isEmpty)
{
if (json_read_value(jsEg1) || json_read_value(jsEg2))
if (json_read_value(jsEg1))
{
return 1;
}
if (json_read_value(jsEg2))
{
return 1;
}
if (jsEg1->value_type == JSON_VALUE_OBJECT && jsEg2->value_type == JSON_VALUE_OBJECT)
{
@ -100,7 +106,9 @@ int doMergePatch(string& retJS, json_engine_t* jsEg1, json_engine_t* jsEg2, bool
} while (json_read_keyname_chr(jsEg1) == 0);
if (jsEg1->s.error)
{
return 1;
}
savLen = retJS.size();
@ -122,13 +130,17 @@ int doMergePatch(string& retJS, json_engine_t* jsEg1, json_engine_t* jsEg2, bool
if (!json_key_matches(jsEg2, &keyName))
{
if (jsEg2->s.error || json_skip_key(jsEg2))
{
return 2;
}
continue;
}
/* Json_2 has same key as Json_1. Merge them. */
if ((ires = doMergePatch(retJS, jsEg1, jsEg2, mrgEmpty)))
{
return ires;
}
if (mrgEmpty)
retJS = retJS.substr(0, savLen);
@ -144,7 +156,9 @@ int doMergePatch(string& retJS, json_engine_t* jsEg1, json_engine_t* jsEg2, bool
keyStart = jsEg1->s.c_str;
/* Just append the Json_1 key value. */
if (json_skip_key(jsEg1))
{
return 1;
}
retJS.append((const char*)keyStart, jsEg1->s.c_str - keyStart);
firstKey = 0;
@ -168,7 +182,9 @@ int doMergePatch(string& retJS, json_engine_t* jsEg1, json_engine_t* jsEg2, bool
} while (json_read_keyname_chr(jsEg2) == 0);
if (jsEg2->s.error)
{
return 1;
}
*jsEg1 = savJSEg1;
while (json_scan_next(jsEg1) == 0 && jsEg1->state != JST_OBJ_END)
@ -178,11 +194,15 @@ int doMergePatch(string& retJS, json_engine_t* jsEg1, json_engine_t* jsEg2, bool
if (!json_key_matches(jsEg1, &keyName))
{
if (jsEg1->s.error || json_skip_key(jsEg1))
{
return 2;
}
continue;
}
if (json_skip_key(jsEg2) || json_skip_level(jsEg1))
{
return 1;
}
goto continue_j2;
}
@ -199,14 +219,18 @@ int doMergePatch(string& retJS, json_engine_t* jsEg1, json_engine_t* jsEg2, bool
retJS.append("\":");
if (json_read_value(jsEg2))
{
return 1;
}
if (jsEg2->value_type == JSON_VALUE_NULL)
retJS = retJS.substr(0, savLen);
else
{
if (copyValuePatch(retJS, jsEg2))
{
return 1;
}
firstKey = 0;
}
@ -219,11 +243,15 @@ int doMergePatch(string& retJS, json_engine_t* jsEg1, json_engine_t* jsEg2, bool
else
{
if (!json_value_scalar(jsEg1) && json_skip_level(jsEg1))
{
return 1;
}
isEmpty = (jsEg2->value_type == JSON_VALUE_NULL);
if (!isEmpty && copyValuePatch(retJS, jsEg2))
{
return 1;
}
}
return 0;
@ -243,19 +271,18 @@ string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
{
// JSON_MERGE_PATCH return NULL if any argument is NULL
bool isEmpty = false, hasNullArg = false;
const string_view js = fp[0]->data()->getStrVal(row, isNull);
hasNullArg = isNull;
if (isNull)
isNull = false;
const auto& js = fp[0]->data()->getStrVal(row, hasNullArg);
isNull = false;
json_engine_t jsEg1, jsEg2;
jsEg1.s.error = jsEg2.s.error = 0;
string tmpJS{js};
utils::NullString tmpJS(js);
string retJS;
for (size_t i = 1; i < fp.size(); i++)
{
const string_view js2 = fp[i]->data()->getStrVal(row, isNull);
const auto& js2 = fp[i]->data()->getStrVal(row, isNull);
if (isNull)
{
hasNullArg = true;
@ -273,23 +300,24 @@ string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
goto next;
hasNullArg = false;
retJS.append(js2.data());
retJS.append(js2.str());
goto next;
}
initJSEngine(jsEg1, getCharset(fp[0]), tmpJS);
if (doMergePatch(retJS, &jsEg1, &jsEg2, isEmpty))
{
goto error;
}
if (isEmpty)
retJS.append("null");
next:
// tmpJS save the merge result for next loop
tmpJS.swap(retJS);
tmpJS.assign(retJS);
retJS.clear();
}
if (hasNullArg)
goto error;
@ -297,7 +325,6 @@ string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
retJS.clear();
if (doFormat(&jsEg1, retJS, Func_json_format::LOOSE))
goto error;
isNull = false;
return retJS;

View File

@ -25,9 +25,10 @@ CalpontSystemCatalog::ColType Func_json_normalize::operationType(FunctionParm& f
string Func_json_normalize::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto js_ns = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
const string_view js = js_ns.unsafeStringRef();
using DynamicString = unique_ptr<DYNAMIC_STRING, decltype(&dynstr_free)>;

View File

@ -279,8 +279,8 @@ bool Func_json_overlaps::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
CalpontSystemCatalog::ColType& type)
{
bool isNullJS1 = false, isNullJS2 = false;
const string_view js1 = fp[0]->data()->getStrVal(row, isNullJS1);
const string_view js2 = fp[1]->data()->getStrVal(row, isNullJS2);
const auto js1 = fp[0]->data()->getStrVal(row, isNullJS1);
const auto js2 = fp[1]->data()->getStrVal(row, isNullJS2);
if (isNullJS1 || isNullJS2)
return false;

View File

@ -28,9 +28,12 @@ CalpontSystemCatalog::ColType Func_json_quote::operationType(FunctionParm& fp,
std::string Func_json_quote::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto js = fp[0]->data()->getStrVal(row, isNull);
if (isNull || !isCharType(fp[0]->data()->resultType().colDataType))
{
isNull = true;
return "";
}
string ret("\"");

View File

@ -23,7 +23,8 @@ CalpontSystemCatalog::ColType Func_json_remove::operationType(FunctionParm& fp,
string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto& js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
@ -37,11 +38,11 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
initJSPaths(paths, fp, 1, 1);
string retJS;
string tmpJS{js};
utils::NullString tmpJS(js);
for (size_t i = 1, j = 0; i < fp.size(); i++, j++)
{
const char* rawJS = tmpJS.data();
const size_t jsLen = tmpJS.size();
const char* rawJS = tmpJS.str();
const size_t jsLen = tmpJS.length();
JSONPath& path = paths[j];
const json_path_step_t* lastStep;
@ -61,7 +62,7 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
}
}
initJSEngine(jsEg, cs, rawJS);
initJSEngine(jsEg, cs, tmpJS);
if (path.p.last_step < path.p.steps)
goto v_found;
@ -145,7 +146,7 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
retJS.append(",");
retJS.append(remEnd, rawJS + jsLen - remEnd);
tmpJS.swap(retJS);
tmpJS.assign(retJS);
retJS.clear();
}

View File

@ -54,11 +54,11 @@ namespace funcexp
{
const static int wildOne = '_';
const static int wildMany = '%';
int Func_json_search::cmpJSValWild(json_engine_t* jsEg, const string_view& cmpStr, const CHARSET_INFO* cs)
int Func_json_search::cmpJSValWild(json_engine_t* jsEg, const utils::NullString& cmpStr, const CHARSET_INFO* cs)
{
if (jsEg->value_type != JSON_VALUE_STRING || !jsEg->value_escaped)
return cs->wildcmp((const char*)jsEg->value, (const char*)(jsEg->value + jsEg->value_len),
(const char*)cmpStr.data(), (const char*)cmpStr.data() + cmpStr.size(), escape,
(const char*)cmpStr.str(), (const char*)cmpStr.end(), escape,
wildOne, wildMany)
? 0
: 1;
@ -71,7 +71,7 @@ int Func_json_search::cmpJSValWild(json_engine_t* jsEg, const string_view& cmpSt
(uchar*)buf, (uchar*)(buf + strLen))) <= 0)
return 0;
return cs->wildcmp(buf, buf + strLen, cmpStr.data(), cmpStr.data() + cmpStr.size(), escape, wildOne,
return cs->wildcmp(buf, buf + strLen, cmpStr.str(), cmpStr.end(), escape, wildOne,
wildMany)
? 0
: 1;
@ -89,8 +89,8 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
{
string ret;
bool isNullJS = false, isNullVal = false;
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const string_view cmpStr = fp[2]->data()->getStrVal(row, isNull);
const auto& js = fp[0]->data()->getStrVal(row, isNull);
const auto& cmpStr = fp[2]->data()->getStrVal(row, isNull);
if (isNullJS || isNullVal)
{
isNull = true;
@ -102,9 +102,10 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
if (!isModeConst)
isModeConst = (dynamic_cast<ConstantColumn*>(fp[1]->data()) != nullptr);
string mode = fp[1]->data()->getStrVal(row, isNull);
const auto& mode_ns = fp[1]->data()->getStrVal(row, isNull);
if (isNull)
return "";
string mode = mode_ns.safeString("");
transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
if (mode != "one" && mode != "all")
@ -125,13 +126,13 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
return "";
}
bool isNullEscape = false;
const string_view escapeStr = fp[3]->data()->getStrVal(row, isNullEscape);
if (escapeStr.size() > 1)
const auto& escapeStr = fp[3]->data()->getStrVal(row, isNullEscape);
if (escapeStr.length() > 1)
{
isNull = true;
return "";
}
escape = isNullEscape ? '\\' : escapeStr[0];
escape = isNullEscape ? '\\' : escapeStr.safeString("")[0];
}
json_engine_t jsEg;
@ -159,7 +160,7 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
}
}
json_get_path_start(&jsEg, cs, (const uchar*)js.data(), (const uchar*)js.data() + js.size(), &p);
json_get_path_start(&jsEg, cs, (const uchar*)js.str(), (const uchar*)js.end(), &p);
while (json_get_path_next(&jsEg, &p) == 0)
{

View File

@ -22,7 +22,7 @@ CalpontSystemCatalog::ColType Func_json_type::operationType(FunctionParm& fp,
string Func_json_type::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";

View File

@ -22,7 +22,7 @@ CalpontSystemCatalog::ColType Func_json_unquote::operationType(FunctionParm& fp,
std::string Func_json_unquote::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
@ -35,9 +35,9 @@ std::string Func_json_unquote::getStrVal(rowgroup::Row& row, FunctionParm& fp, b
json_read_value(&jsEg);
if (unlikely(jsEg.s.error) || jsEg.value_type != JSON_VALUE_STRING)
return js.data();
return js.safeString();
char* buf = (char*)alloca(jsEg.value_len);
char* buf = (char*)alloca(jsEg.value_len + 1);
if ((strLen = json_unescape(cs, jsEg.value, jsEg.value + jsEg.value_len, &my_charset_utf8mb3_general_ci,
(uchar*)buf, (uchar*)(buf + jsEg.value_len))) >= 0)
{
@ -46,6 +46,6 @@ std::string Func_json_unquote::getStrVal(rowgroup::Row& row, FunctionParm& fp, b
return strLen == 0 ? "" : ret;
}
return js.data();
return js.safeString("");
}
} // namespace funcexp

View File

@ -25,10 +25,10 @@ CalpontSystemCatalog::ColType Func_json_valid::operationType(FunctionParm& fp,
bool Func_json_valid::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
CalpontSystemCatalog::ColType& type)
{
const string_view js = fp[0]->data()->getStrVal(row, isNull);
const auto js = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return false;
return json_valid(js.data(), js.size(), getCharset(fp[0]));
return json_valid(js.unsafeStringRef().data(), js.unsafeStringRef().size(), getCharset(fp[0]));
}
} // namespace funcexp

View File

@ -63,8 +63,9 @@ bool JSONPathWrapper::extract(std::string& ret, rowgroup::Row& row, execplan::SP
{
bool isNullJS = false, isNullPath = false;
const string& js = funcParamJS->data()->getStrVal(row, isNullJS);
const string_view jsp = funcParamPath->data()->getStrVal(row, isNullPath);
const string js = funcParamJS->data()->getStrVal(row, isNullJS).safeString("");
const string sjsp = funcParamPath->data()->getStrVal(row, isNullPath).safeString("");
const string_view jsp = sjsp;
if (isNullJS || isNullPath)
return true;

View File

@ -46,7 +46,7 @@ CalpontSystemCatalog::ColType Func_lcase::operationType(FunctionParm& fp,
std::string Func_lcase::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& colType)
{
const string& tstr = fp[0]->data()->getStrVal(row, isNull);
const auto& tstr = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
@ -56,7 +56,7 @@ std::string Func_lcase::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is
uint64_t bufLen = inLen * cs->casedn_multiply;
char* outBuf = new char[bufLen];
uint64_t outLen = cs->casedn(tstr.c_str(), inLen, outBuf, bufLen);
uint64_t outLen = cs->casedn(tstr.str(), inLen, outBuf, bufLen);
string ret = string(outBuf, outLen);
delete[] outBuf;

View File

@ -106,20 +106,20 @@ long double Func_least::getLongDoubleVal(rowgroup::Row& row, FunctionParm& fp, b
std::string Func_least::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
string leastStr = fp[0]->data()->getStrVal(row, isNull);
auto leastStr = fp[0]->data()->getStrVal(row, isNull);
CHARSET_INFO* cs = fp[0]->data()->resultType().getCharset();
for (uint32_t i = 1; i < fp.size(); i++)
{
const string& str1 = fp[i]->data()->getStrVal(row, isNull);
const auto& str1 = fp[i]->data()->getStrVal(row, isNull);
if (cs->strnncoll(leastStr.c_str(), leastStr.length(), str1.c_str(), str1.length()) > 0)
if (cs->strnncoll(leastStr.str(), leastStr.length(), str1.str(), str1.length()) > 0)
{
leastStr = str1;
}
}
return leastStr;
return leastStr.safeString("");
}
IDB_Decimal Func_least::getDecimalVal(Row& row, FunctionParm& fp, bool& isNull,

View File

@ -47,14 +47,12 @@ std::string Func_left::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull || src.length() < 1) // null or empty string.
return "";
if (src.empty() || src.length() == 0)
return src;
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* pos = src.str();
const char* end = pos + binLen;
size_t trimLength = fp[1]->data()->getUintVal(row, isNull);
@ -65,7 +63,7 @@ std::string Func_left::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN
if ((binLen <= trimLength) || (binLen <= (charPos = cs->charpos(pos, end, trimLength))))
{
return src;
return src.safeString("");
}
std::string ret(pos, charPos);

View File

@ -51,7 +51,12 @@ int64_t Func_length::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNul
(fp[0]->data()->resultType().colDataType == CalpontSystemCatalog::BLOB))
return fp[0]->data()->getStrVal(row, isNull).length();
return strlen(fp[0]->data()->getStrVal(row, isNull).c_str());
const auto& str = fp[0]->data()->getStrVal(row, isNull);
if (str.isNull())
{
return 0;
}
return strlen(str.str());
}
} // namespace funcexp

View File

@ -53,14 +53,12 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull || src.length() < 1)
return "";
if (src.empty() || src.length() == 0)
return src;
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* pos = src.str();
const char* end = pos + binLen;
// strLen = the number of characters in src
size_t strLen = cs->numchars(pos, end);
@ -83,18 +81,20 @@ std::string Func_lpad::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN
}
// The pad characters.
const string* pad = &fPad; // Defaults to space
string pad = fPad; // Defaults to space
// XXX: this is extremely suspicious thing going on below. pad was pointer and pointed value
// may escape scope. I changed pad to be reference.
if (fp.size() > 2)
{
pad = &fp[2]->data()->getStrVal(row, isNull);
pad = fp[2]->data()->getStrVal(row, isNull).safeString("");
}
// binPLen represents the number of bytes in pad
size_t binPLen = pad->length();
const char* posP = pad->c_str();
size_t binPLen = pad.length();
const char* posP = pad.c_str();
// plen = the number of characters in pad
size_t plen = cs->numchars(posP, posP + binPLen);
if (plen == 0)
return src;
return src.safeString("");
size_t byteCount = (padLength + 1) * cs->mbmaxlen; // absolute maximun number of bytes
char* buf = new char[byteCount];

View File

@ -48,27 +48,25 @@ std::string Func_ltrim::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull || src.length() < 1)
return "";
if (src.empty() || src.length() == 0)
return src;
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* pos = src.str();
const char* end = pos + binLen;
// strLen = the number of characters in src
size_t strLen = cs->numchars(pos, end);
// The trim characters.
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull) : " ");
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull).safeString("") : " ");
// binTLen represents the number of bytes in trim
size_t binTLen = trim.length();
const char* posT = trim.c_str();
// strTLen = the number of characters in trim
size_t strTLen = cs->numchars(posT, posT + binTLen);
if (strTLen == 0 || strTLen > strLen)
return src;
return src.unsafeStringRef();
if (binTLen == 1)
{

View File

@ -48,27 +48,31 @@ std::string Func_ltrim_oracle::getStrVal(rowgroup::Row& row, FunctionParm& fp, b
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull || src.length() < 1)
{
isNull = true;
return "";
if (src.empty() || src.length() == 0)
return src;
}
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* pos = src.str();
const char* end = pos + binLen;
// strLen = the number of characters in src
size_t strLen = cs->numchars(pos, end);
// The trim characters.
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull) : " ");
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull).safeString("") : " ");
// binTLen represents the number of bytes in trim
size_t binTLen = trim.length();
const char* posT = trim.c_str();
// strTLen = the number of characters in trim
size_t strTLen = cs->numchars(posT, posT + binTLen);
if (strTLen == 0 || strTLen > strLen)
return src;
{
isNull = src.length() < 1;
return src.safeString("");
}
if (binTLen == 1)
{

View File

@ -101,7 +101,7 @@ uint64_t makedate(rowgroup::Row& row, FunctionParm& parm, bool& isNull)
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
dayofyear = parm[1]->data()->getStrVal(row, isNull);
dayofyear = parm[1]->data()->getStrVal(row, isNull).safeString("");
if (atoi(dayofyear.c_str()) < 1)
{

View File

@ -1734,7 +1734,7 @@ string Func_format::getStrVal(Row& row, FunctionParm& parm, bool& isNull,
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
value = parm[0]->data()->getStrVal(row, isNull);
value = parm[0]->data()->getStrVal(row, isNull).safeString("");
}
break;

View File

@ -504,8 +504,12 @@ CalpontSystemCatalog::ColType Func_md5::operationType(FunctionParm& fp,
string Func_md5::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
const string& arg = parm[0]->data()->getStrVal(row, isNull);
return MD5String(arg.c_str());
const auto& arg = parm[0]->data()->getStrVal(row, isNull);
if (arg.isNull())
{
return "";
}
return MD5String(arg.str());
// return str;
}

View File

@ -348,16 +348,16 @@ uint64_t Func_nullif::getUintVal(rowgroup::Row& row, FunctionParm& parm, bool& i
string Func_nullif::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
CalpontSystemCatalog::ColType& op_ct)
{
string exp1 = parm[0]->data()->getStrVal(row, isNull);
string exp1 = parm[0]->data()->getStrVal(row, isNull).safeString("");
CHARSET_INFO* cs = parm[0]->data()->resultType().getCharset();
if (isNull)
{
isNull = false;
// NULLIF(NULL, ...) is NULL, according to server's results.
return "";
}
string exp2 = parm[1]->data()->getStrVal(row, isNull);
string exp2 = parm[1]->data()->getStrVal(row, isNull).safeString("");
if (isNull)
{
@ -388,7 +388,7 @@ string Func_nullif::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNu
return "";
}
return parm[0]->data()->getStrVal(row, isNull);
return parm[0]->data()->getStrVal(row, isNull).safeString("");
}
int32_t Func_nullif::getDateIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,

View File

@ -76,7 +76,11 @@ int64_t getArgSInt64Val(rowgroup::Row& row, TreeNode* exp, bool& isNull)
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT: return atoi(exp->getStrVal(row, isNull).c_str());
case execplan::CalpontSystemCatalog::TEXT:
{
const auto& str = exp->getStrVal(row, isNull);
return str.isNull() ? 0 : atoi(str.str());
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:

View File

@ -45,15 +45,14 @@ std::string Func_quote::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is
return "NULL";
}
if (str.empty())
return "NULL";
size_t strSize = strlen(str.c_str());
string result;
result.reserve((str.size() * 1.3) + 2);
result.reserve(((strSize + 1) * 1.3) + 2);
result.push_back('\'');
for (uint64_t i = 0; i < str.size(); i++)
for (uint64_t i = 0; i < strSize; i++)
{
switch (str[i])
{

View File

@ -73,7 +73,7 @@ inline bool getBool(rowgroup::Row& row, funcexp::FunctionParm& pm, bool& isNull,
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
expr = pm[0]->data()->getStrVal(row, isNull);
expr = pm[0]->data()->getStrVal(row, isNull).safeString("");
break;
}
@ -153,7 +153,7 @@ inline bool getBool(rowgroup::Row& row, funcexp::FunctionParm& pm, bool& isNull,
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
pattern = pm[1]->data()->getStrVal(row, isNull);
pattern = pm[1]->data()->getStrVal(row, isNull).safeString("");
break;
}

View File

@ -53,7 +53,7 @@ std::string Func_repeat::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
stringValue(fp[0], row, isNull, str);
if (str.empty() || str == "")
if (isNull)
return "";
int count = fp[1]->data()->getIntVal(row, isNull);
@ -62,7 +62,10 @@ std::string Func_repeat::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
return "";
if (count < 1)
{
isNull = true;
return "";
}
// calculate size of buffer to allocate
@ -73,15 +76,19 @@ std::string Func_repeat::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
if (result == NULL)
{
isNull = true;
return "";
}
memset((char*)result, 0, size);
memset((char*)result, 0, size + 1);
for (int i = 0; i < count; i++)
{
if (strcat(result, str.c_str()) == NULL) // questionable check
{
isNull = true;
return "";
}
}
std::string res(result);

View File

@ -48,21 +48,27 @@ std::string Func_replace::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool&
{
CHARSET_INFO* cs = ct.getCharset();
const string& str = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& nstr = fp[0]->data()->getStrVal(row, isNull);
if (nstr.isNull())
return "";
const auto& str = nstr.unsafeStringRef();
size_t strLen = str.length();
const string& fromstr = fp[1]->data()->getStrVal(row, isNull);
if (isNull)
const auto& nfromstr = fp[1]->data()->getStrVal(row, isNull);
if (nfromstr.isNull())
return "";
const auto& fromstr = nfromstr.unsafeStringRef();
if (fromstr.length() == 0)
return str;
size_t fromLen = fromstr.length();
const string& tostr = fp[2]->data()->getStrVal(row, isNull);
if (isNull)
const auto& ntostr = fp[2]->data()->getStrVal(row, isNull);
if (ntostr.isNull())
return "";
const auto& tostr = ntostr.unsafeStringRef();
size_t toLen = tostr.length();
bool binaryCmp = (cs->state & MY_CS_BINSORT) || !cs->use_mb();

View File

@ -42,21 +42,27 @@ std::string Func_replace_oracle::getStrVal(rowgroup::Row& row, FunctionParm& fp,
{
CHARSET_INFO* cs = ct.getCharset();
const string& str = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& nstr = fp[0]->data()->getStrVal(row, isNull);
if (nstr.isNull())
return "";
const auto& str = nstr.unsafeStringRef();
size_t strLen = str.length();
const string& fromstr = fp[1]->data()->getStrVal(row, isNull);
if (isNull)
const auto& nfromstr = fp[1]->data()->getStrVal(row, isNull);
if (nfromstr.isNull())
return "";
const auto& fromstr = nfromstr.unsafeStringRef();
if (fromstr.length() == 0)
return str;
size_t fromLen = fromstr.length();
const string& tostr = fp[2]->data()->getStrVal(row, isNull);
if (isNull)
const auto& ntostr = fp[2]->data()->getStrVal(row, isNull);
if (ntostr.isNull())
return "";
const auto& tostr = ntostr.unsafeStringRef();
size_t toLen = tostr.length();
bool binaryCmp = (cs->state & MY_CS_BINSORT) || !cs->use_mb();

View File

@ -48,14 +48,12 @@ std::string Func_right::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull || src.length() < 1)
return "";
if (src.empty() || src.length() == 0)
return src;
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* pos = src.str();
const char* end = pos + binLen;
size_t trimLength = fp[1]->data()->getUintVal(row, isNull);
@ -64,7 +62,7 @@ std::string Func_right::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is
size_t start = cs->numchars(pos, end); // Here, start is number of characters in src
if (start <= trimLength)
return src;
return src.safeString("");
start = cs->charpos(pos, end,
start - trimLength); // Here, start becomes number of bytes into src to start copying

View File

@ -52,14 +52,12 @@ std::string Func_rpad::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& src = fp[0]->data()->getStrVal(row, isNull);
if (src.isNull() || src.length() < 1)
return "";
if (src.empty() || src.length() == 0)
return src;
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* pos = src.str();
const char* end = pos + binLen;
// strLen = the number of characters in src
size_t strLen = cs->numchars(pos, end);
@ -82,18 +80,18 @@ std::string Func_rpad::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN
}
// The pad characters.
const string* pad = &fPad;
string pad = fPad;
if (fp.size() > 2)
{
pad = &fp[2]->data()->getStrVal(row, isNull);
pad = fp[2]->data()->getStrVal(row, isNull).safeString("");
}
// binPLen represents the number of bytes in pad
size_t binPLen = pad->length();
const char* posP = pad->c_str();
size_t binPLen = pad.length();
const char* posP = pad.c_str();
// plen = the number of characters in pad
size_t plen = cs->numchars(posP, posP + binPLen);
if (plen == 0)
return src;
return src.safeString("");
size_t byteCount = (padLength + 1) * cs->mbmaxlen; // absolute maximun number of bytes
char* buf = new char[byteCount];

View File

@ -48,27 +48,25 @@ std::string Func_rtrim::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& src = fp[0]->data()->getStrVal(row, isNull);
if (src.isNull() || src.length() < 1)
return "";
if (src.empty() || src.length() == 0)
return src;
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* pos = src.str();
const char* end = pos + binLen;
// strLen = the number of characters in src
size_t strLen = cs->numchars(pos, end);
// The trim characters.
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull) : " ");
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull).safeString("") : " ");
// binTLen represents the number of bytes in trim
size_t binTLen = trim.length();
const char* posT = trim.c_str();
// strTLen = the number of characters in trim
size_t strTLen = cs->numchars(posT, posT + binTLen);
if (strTLen == 0 || strTLen > strLen)
return src;
return src.safeString("");
if (binTLen == 1)
{

View File

@ -48,27 +48,31 @@ std::string Func_rtrim_oracle::getStrVal(rowgroup::Row& row, FunctionParm& fp, b
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& src = fp[0]->data()->getStrVal(row, isNull);
if (src.isNull() || src.length() < 1)
{
isNull = true;
return "";
if (src.empty() || src.length() == 0)
return src;
}
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* pos = src.str();
const char* end = pos + binLen;
// strLen = the number of characters in src
size_t strLen = cs->numchars(pos, end);
// The trim characters.
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull) : " ");
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull).safeString("") : " ");
// binTLen represents the number of bytes in trim
size_t binTLen = trim.length();
const char* posT = trim.c_str();
// strTLen = the number of characters in trim
size_t strTLen = cs->numchars(posT, posT + binTLen);
if (strTLen == 0 || strTLen > strLen)
return src;
{
isNull = src.length() < 1;
return src.safeString("");
}
if (binTLen == 1)
{

View File

@ -628,7 +628,7 @@ string Func_sha::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull,
// Input is always treated as sring
sha.Reset();
sha << parm[0]->data()->getStrVal(row, isNull).c_str();
sha << parm[0]->data()->getStrVal(row, isNull).safeString("").c_str();
// can not compute
if (!sha.Result(message_digest))

View File

@ -49,7 +49,10 @@ std::string Func_space::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is
int64_t count = fp[0]->data()->getIntVal(row, isNull);
if (isNull || count < 1)
{
isNull = true;
return "";
}
string result(count, ' ');

View File

@ -55,7 +55,7 @@ dataconvert::DateTime getDateTime(rowgroup::Row& row, FunctionParm& parm, bool&
dateTime.msecond = 0;
int64_t val = 0;
string valStr;
const string& formatStr = parm[1]->data()->getStrVal(row, isNull);
const auto& formatStr = parm[1]->data()->getStrVal(row, isNull).safeString("");
int rc = 0;
switch (parm[0]->data()->resultType().colDataType)
@ -109,7 +109,7 @@ dataconvert::DateTime getDateTime(rowgroup::Row& row, FunctionParm& parm, bool&
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
const string& valref = parm[0]->data()->getStrVal(row, isNull);
const string& valref = parm[0]->data()->getStrVal(row, isNull).safeString("");
// decode with provided format
rc = extractor.extractTime(valref, formatStr, dateTime);

View File

@ -52,10 +52,11 @@ int64_t Func_strcmp::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNul
execplan::CalpontSystemCatalog::ColType& type)
{
CHARSET_INFO* cs = fp[0]->data()->resultType().getCharset();
const string& str = fp[0]->data()->getStrVal(row, isNull);
const string& str1 = fp[1]->data()->getStrVal(row, isNull);
const auto& str = fp[0]->data()->getStrVal(row, isNull);
const auto& str1 = fp[1]->data()->getStrVal(row, isNull);
int ret = cs->strnncollsp(str.c_str(), str.length(), str1.c_str(), str1.length());
// XXX: str() results may be nullptrs.
int ret = cs->strnncollsp(str.str(), str.length(), str1.str(), str1.length());
// mysql's strcmp returns only -1, 0, and 1
return (ret < 0 ? -1 : (ret > 0 ? 1 : 0));
}

View File

@ -48,11 +48,11 @@ std::string Func_substr::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
{
CHARSET_INFO* cs = ct.getCharset();
const string& str = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& str = fp[0]->data()->getStrVal(row, isNull);
if (str.isNull())
return "";
int64_t strLen = str.length();
const char* strptr = str.c_str();
const char* strptr = str.str();
const char* strend = strptr + strLen;
uint32_t strChars = cs->numchars(strptr, strend);
@ -89,7 +89,7 @@ std::string Func_substr::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i
return "";
if (start == 0 && strLen == length)
return str;
return str.safeString("");
length = std::min(length, strLen - start);

View File

@ -48,14 +48,16 @@ std::string Func_substring_index::getStrVal(rowgroup::Row& row, FunctionParm& fp
{
CHARSET_INFO* cs = ct.getCharset();
const string& str = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& nstr = fp[0]->data()->getStrVal(row, isNull);
if (nstr.isNull())
return "";
const auto& str = nstr.unsafeStringRef();
int64_t strLen = str.length();
const string& delimstr = fp[1]->data()->getStrVal(row, isNull);
if (isNull)
const auto& ndelimstr = fp[1]->data()->getStrVal(row, isNull);
if (ndelimstr.isNull())
return "";
const auto& delimstr = ndelimstr.unsafeStringRef();
int64_t delimLen = delimstr.length();
int64_t count = fp[2]->data()->getIntVal(row, isNull);

View File

@ -152,19 +152,22 @@ string Func_time_format::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool&
default: isNull = true; return "";
}
const string& format = parm[1]->data()->getStrVal(row, isNull);
const auto& format = parm[1]->data()->getStrVal(row, isNull);
char* ptr = buf;
for (uint32_t i = 0; i < format.length(); i++)
{
if (format[i] != '%')
*ptr++ = format[i];
char fi = format.unsafeStringRef()[i];
if (fi != '%')
*ptr++ = fi;
else
{
i++;
switch (format[i])
fi = format.unsafeStringRef()[i];
switch (fi)
{
case 'f':
sprintf(ptr, "%06d", msec);

View File

@ -100,9 +100,9 @@ int64_t Func_time_to_sec::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool
case CalpontSystemCatalog::TEXT:
case CalpontSystemCatalog::VARCHAR:
{
std::string strVal = parm[0]->data()->getStrVal(row, isNull);
std::string strVal = parm[0]->data()->getStrVal(row, isNull).safeString("");
if (strVal[0] == '-')
if (strVal.length() > 0 && strVal[0] == '-')
{
bIsNegative = true;
strVal.replace(0, 1, 1, ' ');

View File

@ -163,7 +163,7 @@ string Func_timediff::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& is
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
text = parm[0]->data()->getStrVal(row, isNull);
text = parm[0]->data()->getStrVal(row, isNull).safeString("");
if (text.length() >= 12) // datetime has length at least 12 (YYMMDDHHMMSS), convert others to time
{
@ -181,7 +181,7 @@ string Func_timediff::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& is
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
text = parm[0]->data()->getStrVal(row, isNull);
text = parm[0]->data()->getStrVal(row, isNull).safeString("");
if (treatIntAsDatetime(text))
val1 = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull), &isDate1);
else
@ -200,7 +200,7 @@ string Func_timediff::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& is
}
else
{
text = parm[0]->data()->getStrVal(row, isNull);
text = parm[0]->data()->getStrVal(row, isNull).safeString("");
if (treatIntAsDatetime(text))
val1 = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(row, isNull), &isDate1);
else
@ -250,7 +250,7 @@ string Func_timediff::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& is
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
text = parm[1]->data()->getStrVal(row, isNull);
text = parm[1]->data()->getStrVal(row, isNull).safeString("");
if (text.length() >= 12) // datetime has length at least 12 (YYMMDDHHMMSS), convert others to time
{
val2 = dataconvert::DataConvert::stringToDatetime(text, &isDate2);
@ -267,7 +267,7 @@ string Func_timediff::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& is
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
text = parm[1]->data()->getStrVal(row, isNull);
text = parm[1]->data()->getStrVal(row, isNull).safeString("");
if (treatIntAsDatetime(text))
val2 = dataconvert::DataConvert::intToDatetime(parm[1]->data()->getIntVal(row, isNull), &isDate2);
else
@ -286,7 +286,7 @@ string Func_timediff::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& is
}
else
{
text = parm[1]->data()->getStrVal(row, isNull);
text = parm[1]->data()->getStrVal(row, isNull).safeString("");
if (treatIntAsDatetime(text))
val2 = dataconvert::DataConvert::intToDatetime(parm[1]->data()->getIntVal(row, isNull), &isDate2);
else

View File

@ -114,10 +114,10 @@ int64_t Func_to_days::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& is
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& value = parm[0]->data()->getStrVal(row, isNull);
const auto& value = parm[0]->data()->getStrVal(row, isNull);
int64_t val = 0;
if (value.size() == 10)
if (value.length() == 10)
{
// date type
val = dataconvert::DataConvert::dateToInt(value);

View File

@ -48,27 +48,25 @@ std::string Func_trim::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
const auto& src = fp[0]->data()->getStrVal(row, isNull);
if (src.isNull() || src.length() < 1)
return "";
if (src.empty() || src.length() == 0)
return src;
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* pos = src.str();
const char* end = pos + binLen;
// strLen = the number of characters in src
size_t strLen = cs->numchars(pos, end);
// The trim characters.
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull) : " ");
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull).safeString("") : " ");
// binTLen represents the number of bytes in trim
size_t binTLen = trim.length();
const char* posT = trim.c_str();
// strTLen = the number of characters in trim
size_t strTLen = cs->numchars(posT, posT + binTLen);
if (strTLen == 0 || strTLen > strLen)
return src;
return src.safeString("");
if (binTLen == 1)
{

Some files were not shown because too many files have changed in this diff Show More