diff --git a/dbcon/ddlpackage/ddl.y b/dbcon/ddlpackage/ddl.y index 8f6e713fc..c084f44fe 100644 --- a/dbcon/ddlpackage/ddl.y +++ b/dbcon/ddlpackage/ddl.y @@ -1114,10 +1114,11 @@ literal: ; datetime_type: - DATETIME + DATETIME opt_time_precision { $$ = new ColumnType(DDL_DATETIME); $$->fLength = DDLDatatypeLength[DDL_DATETIME]; + $$->fPrecision = $2; } | DATE diff --git a/dbcon/mysql/ha_calpont_dml.cpp b/dbcon/mysql/ha_calpont_dml.cpp index 1cef4d4da..c4ca59862 100644 --- a/dbcon/mysql/ha_calpont_dml.cpp +++ b/dbcon/mysql/ha_calpont_dml.cpp @@ -838,11 +838,21 @@ int ha_calpont_impl_write_batch_row_(uchar* buf, TABLE* table, cal_impl_if::cal_ // mariadb 10.1 compatibility -- MYSQL_TYPE_DATETIME2 introduced in mysql 5.6 MYSQL_TIME ltime; const uchar* pos = buf; - longlong tmp = my_datetime_packed_from_binary(pos, 0); + longlong tmp = my_datetime_packed_from_binary(pos, table->field[colpos]->decimals()); TIME_from_longlong_datetime_packed(<ime, tmp); - fprintf(ci.filePtr, "%04d-%02d-%02d %02d:%02d:%02d%c", - ltime.year, ltime.month, ltime.day, - ltime.hour, ltime.minute, ltime.second, ci.delimiter); + if (!ltime.second_part) + { + fprintf(ci.filePtr, "%04d-%02d-%02d %02d:%02d:%02d%c", + ltime.year, ltime.month, ltime.day, + ltime.hour, ltime.minute, ltime.second, ci.delimiter); + } + else + { + fprintf(ci.filePtr, "%04d-%02d-%02d %02d:%02d:%02d.%ld%c", + ltime.year, ltime.month, ltime.day, + ltime.hour, ltime.minute, ltime.second, + ltime.second_part, ci.delimiter); + } buf += table->field[colpos]->pack_length(); } else diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 8078d452e..6bd887332 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -486,8 +486,8 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci) * based on the result set. */ /* MCOL-683: UTF-8 datetime no msecs is 57, this sometimes happens! */ - if (((*f)->field_length > 19) && ((*f)->field_length != 57)) - (*f)->field_length = strlen(tmp); +// if (((*f)->field_length > 19) && ((*f)->field_length != 57)) +// (*f)->field_length = strlen(tmp); Field_varstring* f2 = (Field_varstring*)*f; f2->store(tmp, strlen(tmp), f2->charset()); diff --git a/utils/dataconvert/dataconvert.cpp b/utils/dataconvert/dataconvert.cpp index d0689fb0d..6e8a33dc1 100644 --- a/utils/dataconvert/dataconvert.cpp +++ b/utils/dataconvert/dataconvert.cpp @@ -1717,14 +1717,28 @@ std::string DataConvert::dateToString( int datevalue ) return buf; } -std::string DataConvert::datetimeToString( long long datetimevalue ) +std::string DataConvert::datetimeToString( long long datetimevalue, long decimals ) { + // 10 is default which means we don't need microseconds + if (decimals > 6 || decimals < 0) + { + decimals = 0; + } // @bug 4703 abandon multiple ostringstream's for conversion DateTime dt(datetimevalue); - const int DATETIMETOSTRING_LEN = 21; // YYYY-MM-DD HH:MM:SS\0 + const int DATETIMETOSTRING_LEN = 28; // YYYY-MM-DD HH:MM:SS.mmmmmm\0 char buf[DATETIMETOSTRING_LEN]; sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d", dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second); + if (dt.msecond && decimals) + { + snprintf(buf + strlen(buf), 21 + decimals, ".%d", dt.msecond); + // Pad end with zeros + if (strlen(buf) < (21 + decimals)) + { + sprintf(buf + strlen(buf), "%0*d", 21 + decimals - strlen(buf), 0); + } + } return buf; } diff --git a/utils/dataconvert/dataconvert.h b/utils/dataconvert/dataconvert.h index 1debe1bcc..d2d9b834f 100644 --- a/utils/dataconvert/dataconvert.h +++ b/utils/dataconvert/dataconvert.h @@ -361,7 +361,7 @@ public: * @param type the columns database type * @param data the columns string representation of it's data */ - EXPORT static std::string datetimeToString( long long datetimevalue ); + EXPORT static std::string datetimeToString( long long datetimevalue, long decimals = 0 ); static inline void datetimeToString( long long datetimevalue, char* buf, unsigned int buflen ); /** @@ -459,14 +459,29 @@ inline void DataConvert::dateToString( int datevalue, char* buf, unsigned int bu inline void DataConvert::datetimeToString( long long datetimevalue, char* buf, unsigned int buflen ) { - snprintf( buf, buflen, "%04d-%02d-%02d %02d:%02d:%02d", - (unsigned)((datetimevalue >> 48) & 0xffff), - (unsigned)((datetimevalue >> 44) & 0xf), - (unsigned)((datetimevalue >> 38) & 0x3f), - (unsigned)((datetimevalue >> 32) & 0x3f), - (unsigned)((datetimevalue >> 26) & 0x3f), - (unsigned)((datetimevalue >> 20) & 0x3f) - ); + if ((datetimevalue & 0xfffff) > 0) + { + snprintf( buf, buflen, "%04d-%02d-%02d %02d:%02d:%02d.%d", + (unsigned)((datetimevalue >> 48) & 0xffff), + (unsigned)((datetimevalue >> 44) & 0xf), + (unsigned)((datetimevalue >> 38) & 0x3f), + (unsigned)((datetimevalue >> 32) & 0x3f), + (unsigned)((datetimevalue >> 26) & 0x3f), + (unsigned)((datetimevalue >> 20) & 0x3f), + (unsigned)((datetimevalue) & 0xfffff) + ); + } + else + { + snprintf( buf, buflen, "%04d-%02d-%02d %02d:%02d:%02d", + (unsigned)((datetimevalue >> 48) & 0xffff), + (unsigned)((datetimevalue >> 44) & 0xf), + (unsigned)((datetimevalue >> 38) & 0x3f), + (unsigned)((datetimevalue >> 32) & 0x3f), + (unsigned)((datetimevalue >> 26) & 0x3f), + (unsigned)((datetimevalue >> 20) & 0x3f) + ); + } } inline void DataConvert::dateToString1( int datevalue, char* buf, unsigned int buflen) diff --git a/writeengine/server/we_dmlcommandproc.cpp b/writeengine/server/we_dmlcommandproc.cpp index bf5adf906..07037a1e3 100644 --- a/writeengine/server/we_dmlcommandproc.cpp +++ b/writeengine/server/we_dmlcommandproc.cpp @@ -2977,7 +2977,7 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, case CalpontSystemCatalog::DATETIME: { intColVal = row.getUintField<8>(fetchColPos); - value = DataConvert::datetimeToString(intColVal); + value = DataConvert::datetimeToString(intColVal, colType.precision); break; } @@ -3305,7 +3305,7 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, case CalpontSystemCatalog::DATETIME: { intColVal = row.getUintField<8>(fetchColPos); - value = DataConvert::datetimeToString(intColVal); + value = DataConvert::datetimeToString(intColVal, colType.precision); break; }