From cc672cfa3f7c37d738e6a2a9731cdf16b2d9e8c9 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 3 Mar 2022 00:10:25 +0800 Subject: [PATCH] fix time related function using taosParseTime generate random output --- src/common/src/texpr.c | 86 +++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 56 deletions(-) diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c index 2bf91131e6..071f3a6d0e 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -2228,6 +2228,31 @@ void vectorMathFunc(int16_t functionId, tExprOperandInfo *pInputs, int32_t numIn free(inputData); } +void convertStringToTimestamp(int16_t type, char *inputData, int64_t timePrec, int64_t *timeVal) { + if (type == TSDB_DATA_TYPE_BINARY) { + int32_t charLen = varDataLen(inputData); + char *newColData = calloc(1, charLen + 1); + memcpy(newColData, varDataVal(inputData), charLen); + taosParseTime(newColData, timeVal, charLen, timePrec, 0); + tfree(newColData); + } else if (type == TSDB_DATA_TYPE_NCHAR) { + int32_t charLen = varDataLen(inputData); + char *newColData = calloc(1, charLen / TSDB_NCHAR_SIZE + 1); + int len = taosUcs4ToMbs(varDataVal(inputData), charLen, newColData); + if (len < 0){ + uError("convertStringToTimestamp taosUcs4ToMbs error"); + tfree(newColData); + return; + } + newColData[len] = 0; + taosParseTime(newColData, timeVal, len + 1, timePrec, 0); + tfree(newColData); + } else { + uError("input type should be binary/nchar string"); + return; + } +} + void vectorTimeFunc(int16_t functionId, tExprOperandInfo *pInputs, int32_t numInputs, tExprOperandInfo* pOutput, int32_t order) { for (int i = 0; i < numInputs; ++i) { assert(pInputs[i].numOfRows == 1 || pInputs[i].numOfRows == pOutput->numOfRows); @@ -2331,25 +2356,7 @@ void vectorTimeFunc(int16_t functionId, tExprOperandInfo *pInputs, int32_t numIn int64_t timeVal = 0; int64_t timePrec; GET_TYPED_DATA(timePrec, int64_t, pInputs[1].type, inputData[1]); - if (pInputs[0].type == TSDB_DATA_TYPE_BINARY) { - int32_t charLen = varDataLen(inputData[0]); - char *newColData = calloc(1, charLen + 1); - memcpy(newColData, varDataVal(inputData[0]), charLen); - taosParseTime(newColData, &timeVal, charLen, timePrec, 0); - tfree(newColData); - } else { - int32_t charLen = varDataLen(inputData[0]); - char *newColData = calloc(1, charLen / TSDB_NCHAR_SIZE + 1); - int len = taosUcs4ToMbs(varDataVal(inputData[0]), charLen, newColData); - if (len < 0){ - uError("vectorTimeFunc taosUcs4ToMbs error"); - tfree(newColData); - return; - } - newColData[len] = 0; - taosParseTime(newColData, &timeVal, len + 1, timePrec, 0); - tfree(newColData); - } + convertStringToTimestamp(pInputs[0].type, inputData[0], timePrec, &timeVal); SET_TYPED_DATA(outputData, pOutput->type, timeVal); break; @@ -2372,25 +2379,7 @@ void vectorTimeFunc(int16_t functionId, tExprOperandInfo *pInputs, int32_t numIn if (pInputs[0].type == TSDB_DATA_TYPE_BINARY || pInputs[0].type == TSDB_DATA_TYPE_NCHAR) { /* datetime format strings */ - if (pInputs[0].type == TSDB_DATA_TYPE_BINARY) { - int32_t charLen = varDataLen(inputData[0]); - char *newColData = calloc(1, charLen + 1); - memcpy(newColData, varDataVal(inputData[0]), charLen); - taosParseTime(newColData, &timeVal, charLen, TSDB_TIME_PRECISION_NANO, 0); - tfree(newColData); - } else { - int32_t charLen = varDataLen(inputData[0]); - char *newColData = calloc(1, charLen / TSDB_NCHAR_SIZE + 1); - int len = taosUcs4ToMbs(varDataVal(inputData[0]), charLen, newColData); - if (len < 0){ - uError("vectorTimeFunc taosUcs4ToMbs error"); - tfree(newColData); - return; - } - newColData[len] = 0; - taosParseTime(newColData, &timeVal, len + 1, TSDB_TIME_PRECISION_NANO, 0); - tfree(newColData); - } + convertStringToTimestamp(pInputs[0].type, inputData[0], TSDB_TIME_PRECISION_NANO, &timeVal); //If converted value is less than 10digits in second, use value in second instead int64_t timeValSec = timeVal / 1000000000; if (timeValSec < 1000000000) { @@ -2567,24 +2556,9 @@ void vectorTimeFunc(int16_t functionId, tExprOperandInfo *pInputs, int32_t numIn pInputs[j].type == TSDB_DATA_TYPE_BINARY || pInputs[j].type == TSDB_DATA_TYPE_NCHAR); - if (pInputs[j].type == TSDB_DATA_TYPE_BINARY) { /* datetime format strings */ - int32_t charLen = varDataLen(inputData[j]); - char *newColData = calloc(1, charLen + 1); - memcpy(newColData, varDataVal(inputData[j]), charLen); - taosParseTime(newColData, &timeVal[j], charLen, TSDB_TIME_PRECISION_NANO, 0); - tfree(newColData); - } else if (pInputs[j].type == TSDB_DATA_TYPE_NCHAR) { - int32_t charLen = varDataLen(inputData[j]); - char *newColData = calloc(1, charLen / TSDB_NCHAR_SIZE + 1); - int len = taosUcs4ToMbs(varDataVal(inputData[j]), charLen, newColData); - if (len < 0){ - uError("vectorTimeFunc taosUcs4ToMbs error"); - tfree(newColData); - return; - } - newColData[len] = 0; - taosParseTime(newColData, &timeVal[j], len + 1, TSDB_TIME_PRECISION_NANO, 0); - tfree(newColData); + if (pInputs[j].type == TSDB_DATA_TYPE_BINARY || + pInputs[j].type == TSDB_DATA_TYPE_NCHAR) { /* datetime format strings */ + convertStringToTimestamp(pInputs[j].type, inputData[j], TSDB_TIME_PRECISION_NANO, &timeVal[j]); } else if (pInputs[j].type == TSDB_DATA_TYPE_BIGINT || pInputs[j].type == TSDB_DATA_TYPE_TIMESTAMP) { /* unix timestamp or ts column*/ GET_TYPED_DATA(timeVal[j], int64_t, pInputs[j].type, inputData[j]); -- GitLab