mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-05-31 11:41:14 +03:00
For the initial BLOB/TEXT pull request we put them in the same bucket as VARBINARY, forcing many functions to be disabled. This patch enables the same TEXT function support as VARCHAR.
194 lines
5.0 KiB
C++
194 lines
5.0 KiB
C++
/* Copyright (C) 2014 InfiniDB, Inc.
|
|
|
|
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. */
|
|
|
|
/****************************************************************************
|
|
* $Id: func_char.cpp 3931 2013-06-21 20:17:28Z bwilkinson $
|
|
*
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include <cstdlib>
|
|
#include <string>
|
|
using namespace std;
|
|
|
|
#include "functor_str.h"
|
|
#include "funchelpers.h"
|
|
#include "functioncolumn.h"
|
|
using namespace execplan;
|
|
|
|
#include "rowgroup.h"
|
|
using namespace rowgroup;
|
|
|
|
#include "errorcodes.h"
|
|
#include "idberrorinfo.h"
|
|
#include "errorids.h"
|
|
using namespace logging;
|
|
|
|
namespace
|
|
{
|
|
|
|
// buf must be at least 9 characters since given 64-bit input
|
|
// we will convert at most 8 characters and then add the null
|
|
inline bool getChar( uint64_t value, char* buf )
|
|
{
|
|
uint32_t cur_offset = 0; // current index into buf
|
|
int cur_bitpos = 56; // 8th octet in input val
|
|
|
|
while( cur_bitpos >= 0 )
|
|
{
|
|
if( ( ( value >> cur_bitpos ) & 0xff ) != 0 )
|
|
{
|
|
buf[cur_offset++] = char( ( value >> cur_bitpos ) & 0xff );
|
|
}
|
|
cur_bitpos -= 8;
|
|
}
|
|
buf[cur_offset] = '\0';
|
|
|
|
return true;
|
|
}
|
|
|
|
// see comment above regarding buf assumptions
|
|
inline bool getChar( int64_t value, char* buf )
|
|
{
|
|
if ( value < 0 )
|
|
return false;
|
|
else
|
|
return getChar( (uint64_t) value, buf );
|
|
}
|
|
}
|
|
|
|
namespace funcexp
|
|
{
|
|
CalpontSystemCatalog::ColType Func_char::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
|
|
{
|
|
// operation type is not used by this functor
|
|
return fp[0]->data()->resultType();
|
|
}
|
|
|
|
string Func_char::getStrVal(Row& row,
|
|
FunctionParm& parm,
|
|
bool& isNull,
|
|
CalpontSystemCatalog::ColType& ct)
|
|
{
|
|
const int BUF_SIZE = 9; // see comment above for size requirement
|
|
char buf[BUF_SIZE];
|
|
|
|
switch (ct.colDataType)
|
|
{
|
|
case execplan::CalpontSystemCatalog::BIGINT:
|
|
case execplan::CalpontSystemCatalog::INT:
|
|
case execplan::CalpontSystemCatalog::MEDINT:
|
|
case execplan::CalpontSystemCatalog::TINYINT:
|
|
case execplan::CalpontSystemCatalog::SMALLINT:
|
|
{
|
|
int64_t value = parm[0]->data()->getIntVal(row, isNull);
|
|
|
|
if ( !getChar(value, buf) ) {
|
|
isNull = true;
|
|
return "";
|
|
}
|
|
}
|
|
break;
|
|
|
|
case execplan::CalpontSystemCatalog::UBIGINT:
|
|
case execplan::CalpontSystemCatalog::UINT:
|
|
case execplan::CalpontSystemCatalog::UMEDINT:
|
|
case execplan::CalpontSystemCatalog::UTINYINT:
|
|
case execplan::CalpontSystemCatalog::USMALLINT:
|
|
{
|
|
uint64_t value = parm[0]->data()->getUintVal(row, isNull);
|
|
|
|
if ( !getChar(value, buf) ) {
|
|
isNull = true;
|
|
return "";
|
|
}
|
|
}
|
|
break;
|
|
|
|
case execplan::CalpontSystemCatalog::VARCHAR: // including CHAR'
|
|
case execplan::CalpontSystemCatalog::CHAR:
|
|
case execplan::CalpontSystemCatalog::TEXT:
|
|
case execplan::CalpontSystemCatalog::DOUBLE:
|
|
case execplan::CalpontSystemCatalog::UDOUBLE:
|
|
{
|
|
double value = parm[0]->data()->getDoubleVal(row, isNull);
|
|
if ( !getChar((int64_t)value, buf) ) {
|
|
isNull = true;
|
|
return "";
|
|
}
|
|
}
|
|
break;
|
|
|
|
case execplan::CalpontSystemCatalog::FLOAT:
|
|
case execplan::CalpontSystemCatalog::UFLOAT:
|
|
{
|
|
float value = parm[0]->data()->getFloatVal(row, isNull);
|
|
if ( !getChar((int64_t)value, buf) ) {
|
|
isNull = true;
|
|
return "";
|
|
}
|
|
}
|
|
break;
|
|
|
|
case execplan::CalpontSystemCatalog::DECIMAL:
|
|
case execplan::CalpontSystemCatalog::UDECIMAL:
|
|
{
|
|
IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull);
|
|
// get decimal and round up
|
|
int value = d.value / helpers::power(d.scale);
|
|
int lefto = (d.value - value * helpers::power(d.scale)) / helpers::power(d.scale-1);
|
|
if ( lefto > 4 )
|
|
value++;
|
|
if ( !getChar((int64_t)value, buf) ) {
|
|
isNull = true;
|
|
return "";
|
|
}
|
|
}
|
|
break;
|
|
|
|
case execplan::CalpontSystemCatalog::DATE:
|
|
case execplan::CalpontSystemCatalog::DATETIME:
|
|
{
|
|
isNull = true;
|
|
return "";
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "char: datatype of " << execplan::colDataTypeToString(ct.colDataType);
|
|
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
|
|
}
|
|
|
|
}
|
|
// Bug 5110 : Here the data in col is null. But there might have other
|
|
// non-null columns we processed before and we do not want entire value
|
|
// to become null. Therefore we set isNull flag to false.
|
|
if(isNull)
|
|
{
|
|
isNull = false;
|
|
return "";
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
|
|
} // namespace funcexp
|
|
// vim:ts=4 sw=4:
|