From 52c0f79fcfdfc0edcd2e0ea26bf3abafb50caa41 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Thu, 29 Sep 2016 17:27:52 +0100 Subject: [PATCH] MCOL-330 Fix datetime to int conversion Datetime has internal int value which is very different to MySQL's int value. This patch differentiates between the two and also fixes a column width issue which appeared once the datetime handling was fixed. --- dbcon/mysql/ha_calpont_impl.cpp | 11 +++++++++++ utils/funcexp/func_date_format.cpp | 2 +- utils/funcexp/func_from_unixtime.cpp | 11 ++++------- utils/funcexp/funcexp.cpp | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index bef98e714..25cd2b9ea 100755 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -448,6 +448,17 @@ int fetchNextRow(uchar *buf, cal_table_info& ti, cal_connection_info* ci) *(*f)->null_ptr &= ~(*f)->null_bit; intColVal = row.getUintField<8>(s); DataConvert::datetimeToString(intColVal, tmp, 255); + + /* setting the field_length is a sort-of hack. The length + * at this point can be long enough to include mseconds. + * ColumnStore doesn't fully support mseconds yet so if + * they are requested, trim them off. + * At a later date we should set this more intelligently + * based on the result set. + */ + if ((*f)->field_length > 19) + (*f)->field_length = strlen(tmp); + Field_varstring* f2 = (Field_varstring*)*f; f2->store(tmp, strlen(tmp), f2->charset()); break; diff --git a/utils/funcexp/func_date_format.cpp b/utils/funcexp/func_date_format.cpp index bce8f0baf..6a082cb4e 100644 --- a/utils/funcexp/func_date_format.cpp +++ b/utils/funcexp/func_date_format.cpp @@ -227,7 +227,7 @@ string Func_date_format::getStrVal(rowgroup::Row& row, dt.day = (uint32_t)((val >> 6) & 0x3f); break; case CalpontSystemCatalog::DATETIME: - val = parm[0]->data()->getIntVal(row, isNull); + val = parm[0]->data()->getDatetimeIntVal(row, isNull); dt.year = (uint32_t)((val >> 48) & 0xffff); dt.month = (uint32_t)((val >> 44) & 0xf); dt.day = (uint32_t)((val >> 38) & 0x3f); diff --git a/utils/funcexp/func_from_unixtime.cpp b/utils/funcexp/func_from_unixtime.cpp index 6d0f9be61..3c2a339c3 100644 --- a/utils/funcexp/func_from_unixtime.cpp +++ b/utils/funcexp/func_from_unixtime.cpp @@ -61,7 +61,7 @@ DateTime getDateTime(rowgroup::Row& row, break; } default: - val = parm[0]->data()->getIntVal(row, isNull); + val = parm[0]->data()->getDatetimeIntVal(row, isNull); } if (val < 0 || val > helpers::TIMESTAMP_MAX_VALUE) @@ -146,7 +146,6 @@ int64_t Func_from_unixtime::getIntVal(rowgroup::Row& row, bool& isNull, CalpontSystemCatalog::ColType& ct) { -#if 0 DateTime dt = getDateTime(row, parm, isNull); if (*reinterpret_cast(&dt) == 0) { @@ -154,13 +153,11 @@ int64_t Func_from_unixtime::getIntVal(rowgroup::Row& row, return 0; } char buf[32]; // actual string guaranteed to be 22 - snprintf( buf, 32, "%04d%02d%02d%02d%02d%02", + snprintf( buf, 32, "%04d%02d%02d%02d%02d%02d", dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second ); return atoll(buf); -#endif - return getDatetimeIntVal(row, parm, isNull, ct); -} +} double Func_from_unixtime::getDoubleVal(rowgroup::Row& row, FunctionParm& parm, @@ -181,7 +178,7 @@ double Func_from_unixtime::getDoubleVal(rowgroup::Row& row, dt.minute, dt.second, dt.msecond ); return atof(buf); } - + return (double) atoi(getStrVal(row, parm, isNull, ct).c_str()); } diff --git a/utils/funcexp/funcexp.cpp b/utils/funcexp/funcexp.cpp index b291a4ccb..675208f9a 100644 --- a/utils/funcexp/funcexp.cpp +++ b/utils/funcexp/funcexp.cpp @@ -257,7 +257,7 @@ void FuncExp::evaluate(rowgroup::Row& row, std::vector& expressi } case CalpontSystemCatalog::DATETIME: { - int64_t val = expression[i]->getIntVal(row, isNull); + int64_t val = expression[i]->getDatetimeIntVal(row, isNull); if (isNull) row.setUintField<8>(DATETIMENULL, expression[i]->outputIndex()); else