// Returns the string that results from concatenating the arguments. // concat() returns NULL if any argument is NULL. // string Func_concat::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&) { string ret = stringValue(parm[0], row, isNull); for ( unsigned int id = 1 ; id < parm.size() ; id++) { ret.append( stringValue(parm[id], row, isNull) ); } return ret; }
uint64_t Func_greatest::getUintVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct) { double str = fp[0]->data()->getDoubleVal(row, isNull); double greatestStr = str; for (uint i = 1; i < fp.size(); i++) { double str1 = fp[i]->data()->getDoubleVal(row, isNull); if ( greatestStr < str1 ) greatestStr = str1; } return (uint64_t) greatestStr; }
IDB_Decimal Func_greatest::getDecimalVal(Row& row, FunctionParm& fp, bool& isNull, CalpontSystemCatalog::ColType& ct) { // double str = fp[0]->data()->getDoubleVal(row, isNull); IDB_Decimal str = fp[0]->data()->getDecimalVal(row, isNull); IDB_Decimal greatestStr = str; for (uint i = 1; i < fp.size(); i++) { IDB_Decimal str1 = fp[i]->data()->getDecimalVal(row, isNull); if ( greatestStr < str1 ) greatestStr = str1; } return greatestStr; }
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); string greatestStr = str; for (uint i = 1; i < fp.size(); i++) { const string& str1 = fp[i]->data()->getStrVal(row, isNull); int tmp = utf8::idb_strcoll(greatestStr.c_str(), str1.c_str()); if ( tmp < 0 ) // if ( greatestStr < str1 ) greatestStr = str1; } return greatestStr; }
int64_t Func_bitxor::getIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& operationColType) { if ( parm.size() < 2 ) { isNull = true; return 0; } uint64_t val1 = 0; uint64_t val2 = 0; if (!getUIntValFromParm(row, parm[0], val1, isNull) || !getUIntValFromParm(row, parm[1], val2, isNull)) { std::ostringstream oss; oss << "bitxor: datatype of " << execplan::colDataTypeToString(operationColType.colDataType); throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT); } return val1 ^ val2; }
string Func_from_unixtime::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&) { DateTime dt = getDateTime(row, parm, isNull); if (*reinterpret_cast<int64_t*>(&dt) == 0) { isNull = true; return ""; } if (parm.size() == 2) { const string& format = parm[1]->data()->getStrVal(row, isNull); return helpers::IDB_date_format(dt, format); } char buf[256] = {0}; DataConvert::datetimeToString(*(reinterpret_cast<int64_t*>(&dt)), buf, 255); return string(buf, 255); }
double Func_from_unixtime::getDoubleVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& ct) { if (parm.size() == 1) { DateTime dt = getDateTime(row, parm, isNull); if (*reinterpret_cast<int64_t*>(&dt) == 0) { isNull = true; return 0; } char buf[32]; // actual string guaranteed to be 22 snprintf( buf, 32, "%04d%02d%02d%02d%02d%02d.%06d", dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.msecond ); return atof(buf); } return (double) atoi(getStrVal(row, parm, isNull, ct).c_str()); }
int64_t Func_bitand::getIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& operationColType) { vector<int64_t> values; if ( parm.size() < 2 ) { isNull = true; return 0; } for (uint32_t i = 0; i < parm.size(); i++) { switch (parm[i]->data()->resultType().colDataType) { case execplan::CalpontSystemCatalog::BIGINT: case execplan::CalpontSystemCatalog::INT: case execplan::CalpontSystemCatalog::MEDINT: case execplan::CalpontSystemCatalog::TINYINT: case execplan::CalpontSystemCatalog::SMALLINT: case execplan::CalpontSystemCatalog::UBIGINT: case execplan::CalpontSystemCatalog::UINT: case execplan::CalpontSystemCatalog::UMEDINT: case execplan::CalpontSystemCatalog::UTINYINT: case execplan::CalpontSystemCatalog::USMALLINT: case execplan::CalpontSystemCatalog::DOUBLE: case execplan::CalpontSystemCatalog::FLOAT: case execplan::CalpontSystemCatalog::UDOUBLE: case execplan::CalpontSystemCatalog::UFLOAT: { values.push_back(parm[i]->data()->getIntVal(row, isNull)); } break; case execplan::CalpontSystemCatalog::VARCHAR: case execplan::CalpontSystemCatalog::CHAR: { int64_t value = parm[i]->data()->getIntVal(row, isNull); if (isNull) { isNull = true; return value; } values.push_back(0); } break; case execplan::CalpontSystemCatalog::DECIMAL: { IDB_Decimal d = parm[i]->data()->getDecimalVal(row, isNull); int64_t value = d.value / power(d.scale); int lefto = (d.value - value * power(d.scale)) / power(d.scale-1); if ( value >= 0 && lefto > 4 ) value++; if ( value < 0 && lefto < -4 ) value--; values.push_back(value); } break; case execplan::CalpontSystemCatalog::DATE: { int64_t time = parm[i]->data()->getDateIntVal(row, isNull); int32_t year = 0, month = 0, day = 0; year = (uint32_t)((time >> 16) & 0xffff); month = (uint32_t)((time >> 12) & 0xf); day = (uint32_t)((time >> 6) & 0x3f); values.push_back((year*10000)+(month*100)+day); } break; case execplan::CalpontSystemCatalog::DATETIME: { int64_t time = parm[i]->data()->getDatetimeIntVal(row, isNull); int32_t year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0; year = (uint32_t)((time >> 48) & 0xffff); month = (uint32_t)((time >> 44) & 0xf); day = (uint32_t)((time >> 38) & 0x3f); hour = (uint32_t)((time >> 32) & 0x3f); min = (uint32_t)((time >> 26) & 0x3f); sec = (uint32_t)((time >> 20) & 0x3f); // return (int64_t) (year*1000000000000)+(month*100000000)+(day*1000000)+(hour*10000)+(min*100)+sec; values.push_back((month*100000000)+(day*1000000)+(hour*10000)+(min*100)+sec); } break; default: { std::ostringstream oss; oss << "bitand: datatype of " << execplan::colDataTypeToString(operationColType.colDataType); throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT); } } } vector<int64_t>::iterator p = values.begin(); int64_t retValue = *p; p++; while ( p != values.end() ) { retValue = retValue & *p; p++; } return retValue; }
string Func_concat_ws::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&) { string delim = stringValue(parm[0], row, isNull); if (isNull) return ""; #ifdef STRCOLL_ENH__ wstring wstr; size_t strwclen = utf8::idb_mbstowcs(0,delim.c_str(),0) + 1; wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t)); strwclen = utf8::idb_mbstowcs(wcbuf, delim.c_str(), strwclen); wstring wdelim(wcbuf, strwclen); for ( unsigned int id = 1 ; id < parm.size() ; id++) { string tstr = stringValue(parm[id], row, isNull); if (isNull) { isNull = false; continue; } if (!wstr.empty()) wstr += wdelim; size_t strwclen1 = utf8::idb_mbstowcs(0, tstr.c_str(), 0) + 1; wchar_t* wcbuf1 = (wchar_t*)alloca(strwclen1 * sizeof(wchar_t)); strwclen1 = utf8::idb_mbstowcs(wcbuf1, tstr.c_str(), strwclen1); wstring str1(wcbuf1, strwclen1); wstr += str1; } size_t strmblen = utf8::idb_wcstombs(0, wstr.c_str(), 0) + 1; char* outbuf = (char*)alloca(strmblen * sizeof(char)); strmblen = utf8::idb_wcstombs(outbuf, wstr.c_str(), strmblen); if (strmblen == 0) isNull = true; else isNull = false; return string(outbuf, strmblen); #else string str; for ( uint32_t i = 1 ; i < parm.size() ; i++) { str += string(stringValue(parm[i], row, isNull).c_str()); if (isNull) { isNull = false; continue; } if (!str.empty() && !isNull) str += delim; } if (str.empty()) isNull = true; else isNull = false; return str; #endif }
int64_t Func_week::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) { uint32_t year = 0, month = 0, day = 0; int64_t val = 0; int16_t mode = 0; DateTime aDateTime; Time aTime; if (parm.size() > 1) // mode value mode = parm[1]->data()->getIntVal(row, isNull); switch (parm[0]->data()->resultType().colDataType) { case CalpontSystemCatalog::DATE: val = parm[0]->data()->getIntVal(row, isNull); year = (uint32_t)((val >> 16) & 0xffff); month = (uint32_t)((val >> 12) & 0xf); day = (uint32_t)((val >> 6) & 0x3f); break; case CalpontSystemCatalog::DATETIME: val = parm[0]->data()->getIntVal(row, isNull); year = (uint32_t)((val >> 48) & 0xffff); month = (uint32_t)((val >> 44) & 0xf); day = (uint32_t)((val >> 38) & 0x3f); break; // Time adds to now() and then gets value case CalpontSystemCatalog::TIME: aDateTime = static_cast<DateTime>(nowDatetime()); aTime = parm[0]->data()->getTimeIntVal(row, isNull); aTime.day = 0; val = addTime(aDateTime, aTime); year = (uint32_t)((val >> 48) & 0xffff); month = (uint32_t)((val >> 44) & 0xf); day = (uint32_t)((val >> 38) & 0x3f); break; 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); } break; case CalpontSystemCatalog::BIGINT: case CalpontSystemCatalog::MEDINT: case CalpontSystemCatalog::SMALLINT: case CalpontSystemCatalog::TINYINT: case CalpontSystemCatalog::INT: val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(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); } break; case CalpontSystemCatalog::DECIMAL: if (parm[0]->data()->resultType().scale == 0) { val = dataconvert::DataConvert::intToDatetime(parm[0]->data()->getIntVal(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); } } break; default: isNull = true; return -1; }
std::string Func_substr::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::erydbSystemCatalog::ColType&) { #ifdef STRCOLL_ENH__ const string& tstr = fp[0]->data()->getStrVal(row, isNull); if (isNull) return ""; size_t strwclen = utf8::erydb_mbstowcs(0, tstr.c_str(), 0) + 1; wchar_t* wcbuf = (wchar_t*)alloca(strwclen * sizeof(wchar_t)); strwclen = utf8::erydb_mbstowcs(wcbuf, tstr.c_str(), strwclen); wstring str(wcbuf, strwclen); int64_t start = fp[1]->data()->getIntVal(row, isNull) - 1; if (isNull) return ""; if (start == -1) // pos == 0 return ""; wstring::size_type n = wstring::npos; if (fp.size() == 3) { int64_t len = fp[2]->data()->getIntVal(row,isNull); if (isNull) return ""; if (len < 1) return ""; n = len; } int64_t strLen = static_cast<int64_t>(str.length()); if (start < -1) // negative pos, beginning from end start += strLen + 1; if (start < 0 || strLen <= start) { return ""; } wstring out = str.substr(start, n); size_t strmblen = utf8::erydb_wcstombs(0, out.c_str(), 0) + 1; char* outbuf = (char*)alloca(strmblen * sizeof(char)); strmblen = utf8::erydb_wcstombs(outbuf, out.c_str(), strmblen); return string(outbuf, strmblen); #else const string& str = fp[0]->data()->getStrVal(row, isNull); if (isNull) return ""; int64_t start = fp[1]->data()->getIntVal(row, isNull) - 1; if (isNull) return ""; if (start == -1) // pos == 0 return ""; size_t n = string::npos; if (fp.size() == 3) { int64_t len = fp[2]->data()->getIntVal(row,isNull); if (isNull) return ""; if (len < 1) return ""; n = len; } size_t strLen = strlen(str.c_str()); if (start < -1) // negative pos, beginning from end start += strLen + 1; if (start < 0 || (int64_t)strLen <= start) { return ""; } return str.substr(start, n); #endif }
std::string Func_ltrim::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::erydbSystemCatalog::ColType&) { // The number of characters (not bytes) in our input tstr. // Not all of these are necessarily significant. We need to search for the // NULL terminator to be sure. size_t strwclen; // this holds the number of characters (not bytes) in ourtrim tstr. size_t trimwclen; // The original string const string& tstr = fp[0]->data()->getStrVal(row, isNull); // The trim characters. const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull) : " "); if (isNull) return ""; if (tstr.empty() || tstr.length() == 0) return tstr; // Rather than calling the wideconvert functions with a null buffer to // determine the size of buffer to allocate, we can be sure the wide // char string won't be longer than: strwclen = tstr.length(); // a guess to start with. This will be >= to the real count. int bufsize = (strwclen+1) * sizeof(wchar_t); // Convert the string to wide characters. Do all further work in wide characters wchar_t* wcbuf = (wchar_t*)alloca(bufsize); strwclen = utf8::erydb_mbstowcs(wcbuf, tstr.c_str(), strwclen+1); // erydb_mbstowcs can return -1 if there is bad mbs char in tstr if(strwclen == static_cast<size_t>(-1)) strwclen = 0; // Convert the trim string to wide trimwclen = trim.length(); // A guess to start. int trimbufsize = (trimwclen+1) * sizeof(wchar_t); wchar_t* wctrim = (wchar_t*)alloca(trimbufsize); size_t trimlen = utf8::erydb_mbstowcs(wctrim,trim.c_str(), trimwclen+1); // erydb_mbstowcs can return -1 if there is bad mbs char in tstr if(trimlen == static_cast<size_t>(-1)) trimlen = 0; size_t trimCmpLen = trimlen * sizeof(wchar_t); const wchar_t* oPtr = wcbuf; // To remember the start of the string const wchar_t* aPtr = oPtr; const wchar_t* aEnd = wcbuf+strwclen-1; if(trimlen>0) { if (trimlen == 1) { // If trim is a single char, then don't spend the overhead for memcmp. wchar_t chr=wctrim[0]; while (aPtr <= aEnd && *aPtr == chr) aPtr++; } else { aEnd-=(trimlen-1); // So we don't compare past the end of the string. while (aPtr <= aEnd && !memcmp(aPtr, wctrim, trimCmpLen)) aPtr+=trimlen; } } // Bug 5110 - error in allocating enough memory for utf8 chars size_t aLen = strwclen-(aPtr-oPtr); wstring trimmed = wstring(aPtr, aLen); // Turn back to a string return utf8::wstring_to_utf8(trimmed.c_str()); }