diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index 6d87ae9baa..1a9d7f4900 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1343,9 +1343,6 @@ int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara GET_TYPED_DATA(timePrec, int64_t, GET_PARAM_TYPE(&pInput[timePrecIdx]), pInput[timePrecIdx].columnData->pData); memcpy(timezone, varDataVal(pInput[timeZoneIdx].columnData->pData), varDataLen(pInput[timeZoneIdx].columnData->pData)); - int64_t factor = TSDB_TICK_PER_SECOND(timePrec); - int64_t unit = timeUnit * 1000 / factor; - for (int32_t i = 0; i < pInput[0].numOfRows; ++i) { if (colDataIsNull_s(pInput[0].columnData, i)) { colDataSetNULL(pOutput->columnData, i); @@ -1355,201 +1352,27 @@ int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara char *input = colDataGetData(pInput[0].columnData, i); if (IS_VAR_DATA_TYPE(type)) { /* datetime format strings */ - int32_t ret = convertStringToTimestamp(type, input, TSDB_TIME_PRECISION_NANO, &timeVal); + int32_t ret = convertStringToTimestamp(type, input, timePrec, &timeVal); if (ret != TSDB_CODE_SUCCESS) { colDataSetNULL(pOutput->columnData, i); continue; } - // If converted value is less than 10digits in second, use value in second instead - int64_t timeValSec = timeVal / 1000000000; - if (timeValSec < 1000000000) { - timeVal = timeValSec; - } } else if (type == TSDB_DATA_TYPE_BIGINT) { /* unix timestamp */ GET_TYPED_DATA(timeVal, int64_t, type, input); } else if (type == TSDB_DATA_TYPE_TIMESTAMP) { /* timestamp column*/ GET_TYPED_DATA(timeVal, int64_t, type, input); - int64_t timeValSec = timeVal / factor; - if (timeValSec < 1000000000) { - timeVal = timeValSec; - } } char buf[20] = {0}; NUM_TO_STRING(TSDB_DATA_TYPE_BIGINT, &timeVal, sizeof(buf), buf); - int32_t tsDigits = (int32_t)strlen(buf); - switch (unit) { - case 0: { /* 1u or 1b */ - if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) { - if (timePrec == TSDB_TIME_PRECISION_NANO && timeUnit == 1) { - timeVal = timeVal * 1; - } else { - timeVal = timeVal / 1000 * 1000; - } - } else if (tsDigits <= TSDB_TIME_PRECISION_SEC_DIGITS) { - timeVal = timeVal * factor; - } else { - timeVal = timeVal * 1; - } - break; - } - case 1: { /* 1a */ - if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS) { - timeVal = timeVal * 1; - } else if (tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS) { - timeVal = timeVal / 1000 * 1000; - } else if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) { - timeVal = timeVal / 1000000 * 1000000; - } else if (tsDigits <= TSDB_TIME_PRECISION_SEC_DIGITS) { - timeVal = timeVal * factor; - } else { - colDataSetNULL(pOutput->columnData, i); - continue; - } - break; - } - case 1000: { /* 1s */ - if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS) { - timeVal = timeVal / 1000 * 1000; - } else if (tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS) { - timeVal = timeVal / 1000000 * 1000000; - } else if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) { - timeVal = timeVal / 1000000000 * 1000000000; - } else if (tsDigits <= TSDB_TIME_PRECISION_SEC_DIGITS) { - timeVal = timeVal * factor; - } else { - colDataSetNULL(pOutput->columnData, i); - continue; - } - break; - } - case 60000: { /* 1m */ - if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS) { - timeVal = timeVal / 1000 / 60 * 60 * 1000; - } else if (tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS) { - timeVal = timeVal / 1000000 / 60 * 60 * 1000000; - } else if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) { - timeVal = timeVal / 1000000000 / 60 * 60 * 1000000000; - } else if (tsDigits <= TSDB_TIME_PRECISION_SEC_DIGITS) { - timeVal = timeVal * factor / factor / 60 * 60 * factor; - } else { - colDataSetNULL(pOutput->columnData, i); - continue; - } - break; - } - case 3600000: { /* 1h */ - if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS) { - timeVal = timeVal / 1000 / 3600 * 3600 * 1000; - } else if (tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS) { - timeVal = timeVal / 1000000 / 3600 * 3600 * 1000000; - } else if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) { - timeVal = timeVal / 1000000000 / 3600 * 3600 * 1000000000; - } else if (tsDigits <= TSDB_TIME_PRECISION_SEC_DIGITS) { - timeVal = timeVal * factor / factor / 3600 * 3600 * factor; - } else { - colDataSetNULL(pOutput->columnData, i); - continue; - } - break; - } - case 86400000: { /* 1d */ - if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS) { - if (ignoreTz) { - timeVal = timeVal - (timeVal + offsetFromTz(timezone, 1000)) % (((int64_t)86400) * 1000); - } else { - timeVal = timeVal / 1000 / 86400 * 86400 * 1000; - } - } else if (tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS) { - if (ignoreTz) { - timeVal = timeVal - (timeVal + offsetFromTz(timezone, 1000000)) % (((int64_t)86400) * 1000000); - } else { - timeVal = timeVal / 1000000 / 86400 * 86400 * 1000000; - } - } else if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) { - if (ignoreTz) { - timeVal = timeVal - (timeVal + offsetFromTz(timezone, 1000000000)) % (((int64_t)86400) * 1000000000); - } else { - timeVal = timeVal / 1000000000 / 86400 * 86400 * 1000000000; - } - } else if (tsDigits <= TSDB_TIME_PRECISION_SEC_DIGITS) { - if (ignoreTz) { - timeVal = (timeVal - (timeVal + offsetFromTz(timezone, 1)) % (86400L)) * factor; - } else { - timeVal = timeVal * factor / factor / 86400 * 86400 * factor; - } - } else { - colDataSetNULL(pOutput->columnData, i); - continue; - } - break; - } - case 604800000: { /* 1w */ - if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS) { - if (ignoreTz) { - timeVal = timeVal - (timeVal + offsetFromTz(timezone, 1000)) % (((int64_t)604800) * 1000); - } else { - timeVal = timeVal / 1000 / 604800 * 604800 * 1000; - } - } else if (tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS) { - if (ignoreTz) { - timeVal = timeVal - (timeVal + offsetFromTz(timezone, 1000000)) % (((int64_t)604800) * 1000000); - } else { - timeVal = timeVal / 1000000 / 604800 * 604800 * 1000000; - } - } else if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) { - if (ignoreTz) { - timeVal = timeVal - (timeVal + offsetFromTz(timezone, 1000000000)) % (((int64_t)604800) * 1000000000); - } else { - timeVal = timeVal / 1000000000 / 604800 * 604800 * 1000000000; - } - } else if (tsDigits <= TSDB_TIME_PRECISION_SEC_DIGITS) { - if (ignoreTz) { - timeVal = timeVal - (timeVal + offsetFromTz(timezone, 1)) % (((int64_t)604800L) * factor); - } else { - timeVal = timeVal * factor / factor / 604800 * 604800 * factor; - } - } else { - colDataSetNULL(pOutput->columnData, i); - continue; - } - break; - } - default: { - timeVal = timeVal * 1; - break; - } + // truncate the timestamp to time_unit precision + int64_t seconds = timeUnit / TSDB_TICK_PER_SECOND(timePrec); + if (ignoreTz && (seconds == 604800 || seconds == 86400)) { + timeVal = timeVal - (timeVal + offsetFromTz(timezone, TSDB_TICK_PER_SECOND(timePrec))) % (((int64_t)seconds) * TSDB_TICK_PER_SECOND(timePrec));; + } else { + timeVal = timeVal / timeUnit * timeUnit; } - - // truncate the timestamp to db precision - switch (timePrec) { - case TSDB_TIME_PRECISION_MILLI: { - if (tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS) { - timeVal = timeVal / 1000; - } else if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) { - timeVal = timeVal / 1000000; - } - break; - } - case TSDB_TIME_PRECISION_MICRO: { - if (tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) { - timeVal = timeVal / 1000; - } else if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS) { - timeVal = timeVal * 1000; - } - break; - } - case TSDB_TIME_PRECISION_NANO: { - if (tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS) { - timeVal = timeVal * 1000; - } else if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS) { - timeVal = timeVal * 1000000; - } - break; - } - } - colDataSetVal(pOutput->columnData, i, (char *)&timeVal, false); } diff --git a/tests/system-test/2-query/timetruncate.py b/tests/system-test/2-query/timetruncate.py index 09bdfcef63..67a71cde17 100644 --- a/tests/system-test/2-query/timetruncate.py +++ b/tests/system-test/2-query/timetruncate.py @@ -22,6 +22,7 @@ class TDTestCase: '2020-4-1 00:00:00.001002', '2020-5-1 00:00:00.001002001' ] + self.unix_ts = ['1','1111','1111111','1111111111','1111111111111'] self.db_param_precision = ['ms','us','ns'] self.time_unit = ['1w','1d','1h','1m','1s','1a','1u','1b'] self.error_unit = ['2w','2d','2h','2m','2s','2a','2u','1c','#1'] @@ -134,7 +135,7 @@ class TDTestCase: tdSql.checkEqual(tdSql.queryResult[i][0],int(date_time[i]*1000/1000/1000/1000/1000/60/60/24)*24*60*60*1000*1000*1000 ) else: # assuming the client timezone is UTC+0800 - tdSql.checkEqual(tdSql.queryResult[i][0],int(date_time[i] - (date_time[i] + 8 * 3600 * 1000000) % (86400 * 1000000))) + tdSql.checkEqual(tdSql.queryResult[i][0],int(date_time[i] - (date_time[i] + 8 * 3600 * 1000000000) % (86400 * 1000000000))) elif unit.lower() == '1w': for i in range(len(self.ts_str)): if self.rest_tag != 'rest': @@ -167,16 +168,49 @@ class TDTestCase: self.check_tb_type(unit,tb_type,ignore_tz) tdSql.checkRows(len(self.ts_str)) self.check_ms_timestamp(unit,date_time,ignore_tz) + for uts in self.unix_ts: + ans_time = [] + if tb_type.lower() == 'ntb': + tdSql.query(f'select timetruncate({uts},{unit},{ignore_tz}) from {self.ntbname}') + elif tb_type.lower() == 'ctb': + tdSql.query(f'select timetruncate({uts},{unit},{ignore_tz}) from {self.ctbname}') + elif tb_type.lower() == 'stb': + tdSql.query(f'select timetruncate({uts},{unit},{ignore_tz}) from {self.stbname}') + for i in range(len(self.ts_str)): + ans_time.append(int(uts)) + self.check_ms_timestamp(unit, ans_time, ignore_tz) elif precision.lower() == 'us': for ignore_tz in tz_options: self.check_tb_type(unit,tb_type,ignore_tz) tdSql.checkRows(len(self.ts_str)) self.check_us_timestamp(unit,date_time,ignore_tz) + for uts in self.unix_ts: + ans_time = [] + if tb_type.lower() == 'ntb': + tdSql.query(f'select timetruncate({uts},{unit},{ignore_tz}) from {self.ntbname}') + elif tb_type.lower() == 'ctb': + tdSql.query(f'select timetruncate({uts},{unit},{ignore_tz}) from {self.ctbname}') + elif tb_type.lower() == 'stb': + tdSql.query(f'select timetruncate({uts},{unit},{ignore_tz}) from {self.stbname}') + for i in range(len(self.ts_str)): + ans_time.append(int(uts)) + self.check_us_timestamp(unit, ans_time, ignore_tz) elif precision.lower() == 'ns': for ignore_tz in tz_options: self.check_tb_type(unit,tb_type, ignore_tz) tdSql.checkRows(len(self.ts_str)) self.check_ns_timestamp(unit,date_time,ignore_tz) + for uts in self.unix_ts: + ans_time = [] + if tb_type.lower() == 'ntb': + tdSql.query(f'select timetruncate({uts},{unit},{ignore_tz}) from {self.ntbname}') + elif tb_type.lower() == 'ctb': + tdSql.query(f'select timetruncate({uts},{unit},{ignore_tz}) from {self.ctbname}') + elif tb_type.lower() == 'stb': + tdSql.query(f'select timetruncate({uts},{unit},{ignore_tz}) from {self.stbname}') + for i in range(len(self.ts_str)): + ans_time.append(int(uts)) + self.check_ns_timestamp(unit, ans_time, ignore_tz) for unit in self.error_unit: if tb_type.lower() == 'ntb': tdSql.error(f'select timetruncate(ts,{unit}) from {self.ntbname}')