You've already forked mariadb-columnstore-engine
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:
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
217
utils/common/nullstring.h
Normal 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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 = ',';
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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};
|
||||
|
@ -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 "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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("");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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")
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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])))
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 "";
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)>;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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("\"");
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 "";
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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])
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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))
|
||||
|
@ -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, ' ');
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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, ' ');
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
Reference in New Issue
Block a user