1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

MCOL-973 Fix DOUBLE typecast crash

DOUBLE typecast was not supported and the failure detection caused a
crash.

This patch adds support for DOUBLE typecast and fixes the crash caused
when a non-supported function is detected as part of an arithmatic.
This commit is contained in:
Andrew Hutchings
2017-10-20 12:38:11 +03:00
parent cb9714bd90
commit 5911e677fa
4 changed files with 143 additions and 2 deletions

View File

@ -2655,7 +2655,7 @@ ArithmeticColumn* buildArithmeticColumn(Item_func* item, gp_walk_info& gwi, bool
} }
} }
if (!lhs->data() || !rhs->data() || nonSupport) if (nonSupport || !lhs->data() || !rhs->data())
{ {
gwi.fatalParseError = true; gwi.fatalParseError = true;
if (gwi.parseErrorText.empty()) if (gwi.parseErrorText.empty())
@ -2688,7 +2688,7 @@ ArithmeticColumn* buildArithmeticColumn(Item_func* item, gp_walk_info& gwi, bool
gwi.rcWorkStack.pop(); gwi.rcWorkStack.pop();
} }
} }
if (!rhs->data() || nonSupport) if (nonSupport || !rhs->data())
{ {
gwi.fatalParseError = true; gwi.fatalParseError = true;
if (gwi.parseErrorText.empty()) if (gwi.parseErrorText.empty())

View File

@ -80,6 +80,11 @@ CalpontSystemCatalog::ColType Func_cast_decimal::operationType( FunctionParm& fp
return resultType; return resultType;
} }
CalpontSystemCatalog::ColType Func_cast_double::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
return resultType;
}
// //
// Func_cast_signed // Func_cast_signed
// //
@ -1088,5 +1093,115 @@ double Func_cast_decimal::getDoubleVal(Row& row,
} }
//
// Func_cast_double
//
int64_t Func_cast_double::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
double dblval = Func_cast_double::getDoubleVal(row,
parm,
isNull,
operationColType);
return (int64_t) dblval;
}
string Func_cast_double::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
double dblval = Func_cast_double::getDoubleVal(row,
parm,
isNull,
operationColType);
std::string value = helpers::doubleToString(dblval);
return value;
}
double Func_cast_double::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
double dblval;
// TODO: Here onwards
switch (parm[0]->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::DATE:
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t intval = parm[0]->data()->getIntVal(row, isNull);
dblval = (double) intval;
}
break;
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
uint64_t uintval = parm[0]->data()->getUintVal(row, isNull);
dblval = (double) uintval;
}
break;
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
dblval = parm[0]->data()->getDoubleVal(row, isNull);
}
break;
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal decimal = parm[0]->data()->getDecimalVal(row, isNull);
dblval = (double)(decimal.value / pow((double)10, decimal.scale));
}
break;
case execplan::CalpontSystemCatalog::VARCHAR:
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
{
const string& strValue = parm[0]->data()->getStrVal(row, isNull);
dblval = strtod(strValue.c_str(), NULL);
}
break;
default:
{
std::ostringstream oss;
oss << "cast: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
return dblval;
}
} // namespace funcexp } // namespace funcexp
// vim:ts=4 sw=4: // vim:ts=4 sw=4:

View File

@ -86,6 +86,7 @@ FuncExp::FuncExp()
fFuncMap["cast_as_date"] = new Func_cast_date(); //dlh fFuncMap["cast_as_date"] = new Func_cast_date(); //dlh
fFuncMap["cast_as_datetime"] = new Func_cast_datetime(); //dlh fFuncMap["cast_as_datetime"] = new Func_cast_datetime(); //dlh
fFuncMap["decimal_typecast"] = new Func_cast_decimal(); //dlh fFuncMap["decimal_typecast"] = new Func_cast_decimal(); //dlh
fFuncMap["double_typecast"] = new Func_cast_double();
fFuncMap["ceil"] = new Func_ceil(); //dlh fFuncMap["ceil"] = new Func_ceil(); //dlh
fFuncMap["ceiling"] = new Func_ceil(); //dlh fFuncMap["ceiling"] = new Func_ceil(); //dlh
fFuncMap["char"] = new Func_char(); //dlh fFuncMap["char"] = new Func_char(); //dlh

View File

@ -303,6 +303,31 @@ public:
execplan::CalpontSystemCatalog::ColType& op_ct); execplan::CalpontSystemCatalog::ColType& op_ct);
}; };
/** @brief Func_cast_double class
*/
class Func_cast_double : public Func_Real
{
public:
Func_cast_double() : Func_Real("cast_double") {}
virtual ~Func_cast_double() {}
execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType);
int64_t getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
double getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
std::string getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
};
/** @brief Func_mod class /** @brief Func_mod class
*/ */