From c0b3607756564ff4e8b67f3e9e9c3c2d76717c58 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 12 Apr 2022 20:02:33 +0800 Subject: [PATCH] feat(query): add to_unixtimestamp function TD-14243 --- include/common/ttime.h | 1 + include/libs/function/functionMgt.h | 2 +- include/libs/scalar/scalar.h | 1 + source/common/src/ttime.c | 26 +++++++++++++++++++++++- source/libs/function/inc/builtins.h | 2 +- source/libs/function/src/builtins.c | 13 ++++++++++++ source/libs/scalar/inc/sclInt.h | 5 +++-- source/libs/scalar/src/sclfunc.c | 31 +++++++++++++++++++++++++++++ 8 files changed, 76 insertions(+), 5 deletions(-) diff --git a/include/common/ttime.h b/include/common/ttime.h index 306f54bedb..15450c31ca 100644 --- a/include/common/ttime.h +++ b/include/common/ttime.h @@ -64,6 +64,7 @@ char getPrecisionUnit(int32_t precision); int64_t convertTimePrecision(int64_t time, int32_t fromPrecision, int32_t toPrecision); int64_t convertTimeFromPrecisionToUnit(int64_t time, int32_t fromPrecision, char toUnit); +int32_t convertStringToTimestamp(int16_t type, char *inputData, int64_t timePrec, int64_t *timeVal); void taosFormatUtcTime(char *buf, int32_t bufLen, int64_t time, int32_t precision); diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index 9d1b2c9ea0..148a9f77d6 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -85,8 +85,8 @@ typedef enum EFunctionType { // conversion function FUNCTION_TYPE_CAST = 2000, FUNCTION_TYPE_TO_ISO8601, + FUNCTION_TYPE_TO_UNIXTIMESTAMP, FUNCTION_TYPE_TO_JSON, - FUNCTION_TYPE_UNIXTIMESTAMP, // date and time function FUNCTION_TYPE_NOW = 2500, diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index cd9c6f5bf2..226909a187 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -75,6 +75,7 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp /* Time related functions */ int32_t toISO8601Function(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t toUnixtimestampFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); bool getTimePseudoFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); diff --git a/source/common/src/ttime.c b/source/common/src/ttime.c index a65352f2b9..1baf393e9a 100644 --- a/source/common/src/ttime.c +++ b/source/common/src/ttime.c @@ -406,7 +406,31 @@ int64_t convertTimeFromPrecisionToUnit(int64_t time, int32_t fromPrecision, char default: { return -1; } - } + } +} + +int32_t convertStringToTimestamp(int16_t type, char *inputData, int64_t timePrec, int64_t *timeVal) { + int32_t charLen = varDataLen(inputData); + char *newColData; + if (type == TSDB_DATA_TYPE_BINARY) { + newColData = taosMemoryCalloc(1, charLen + 1); + memcpy(newColData, varDataVal(inputData), charLen); + taosParseTime(newColData, timeVal, charLen, (int32_t)timePrec, 0); + taosMemoryFree(newColData); + } else if (type == TSDB_DATA_TYPE_NCHAR) { + newColData = taosMemoryCalloc(1, charLen / TSDB_NCHAR_SIZE + 1); + int len = taosUcs4ToMbs((TdUcs4 *)varDataVal(inputData), charLen, newColData); + if (len < 0){ + taosMemoryFree(newColData); + return TSDB_CODE_FAILED; + } + newColData[len] = 0; + taosParseTime(newColData, timeVal, len + 1, (int32_t)timePrec, 0); + taosMemoryFree(newColData); + } else { + return TSDB_CODE_FAILED; + } + return TSDB_CODE_SUCCESS; } static int32_t getDuration(int64_t val, char unit, int64_t* result, int32_t timePrecision) { diff --git a/source/libs/function/inc/builtins.h b/source/libs/function/inc/builtins.h index ab5a02c438..624a2953c9 100644 --- a/source/libs/function/inc/builtins.h +++ b/source/libs/function/inc/builtins.h @@ -22,7 +22,7 @@ extern "C" { #include "functionMgt.h" -#define FUNCTION_NAME_MAX_LENGTH 16 +#define FUNCTION_NAME_MAX_LENGTH 32 #define FUNC_MGT_FUNC_CLASSIFICATION_MASK(n) (1 << n) diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 55f38e9005..44888fa793 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -403,6 +403,16 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .sprocessFunc = toISO8601Function, .finalizeFunc = NULL }, + { + .name = "to_unixtimestamp", + .type = FUNCTION_TYPE_TO_UNIXTIMESTAMP, + .classification = FUNC_MGT_SCALAR_FUNC, + .checkFunc = checkAndGetResultType, + .getEnvFunc = NULL, + .initFunc = NULL, + .sprocessFunc = toUnixtimestampFunction, + .finalizeFunc = NULL + }, { .name = "_rowts", .type = FUNCTION_TYPE_ROWTS, @@ -622,6 +632,9 @@ int32_t checkAndGetResultType(SFunctionNode* pFunc) { case FUNCTION_TYPE_TO_ISO8601: { pFunc->node.resType = (SDataType) { .bytes = 64, .type = TSDB_DATA_TYPE_BINARY}; } + case FUNCTION_TYPE_TO_UNIXTIMESTAMP: { + pFunc->node.resType = (SDataType) { .bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT}; + } case FUNCTION_TYPE_TBNAME: { // todo diff --git a/source/libs/scalar/inc/sclInt.h b/source/libs/scalar/inc/sclInt.h index 58b62bb05e..3d59ffd93d 100644 --- a/source/libs/scalar/inc/sclInt.h +++ b/source/libs/scalar/inc/sclInt.h @@ -46,8 +46,9 @@ typedef struct SScalarCtx { int32_t doConvertDataType(SValueNode* pValueNode, SScalarParam* out); SColumnInfoData* createColumnInfoData(SDataType* pType, int32_t numOfRows); -#define GET_PARAM_TYPE(_c) ((_c)->columnData->info.type) -#define GET_PARAM_BYTES(_c) ((_c)->columnData->info.bytes) +#define GET_PARAM_TYPE(_c) ((_c)->columnData->info.type) +#define GET_PARAM_BYTES(_c) ((_c)->columnData->info.bytes) +#define GET_PARAM_PRECISON(_c) ((_c)->columnData->info.precision) void sclFreeParam(SScalarParam *param); diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index 0ab0052624..e2d28fe454 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1,6 +1,7 @@ #include "function.h" #include "scalar.h" #include "tdatablock.h" +#include "ttime.h" #include "sclInt.h" #include "sclvector.h" @@ -872,6 +873,36 @@ int32_t toISO8601Function(SScalarParam *pInput, int32_t inputNum, SScalarParam * return TSDB_CODE_SUCCESS; } +int32_t toUnixtimestampFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + int32_t type = GET_PARAM_TYPE(pInput); + int32_t timePrec = GET_PARAM_PRECISON(pInput); + if (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR) { + return TSDB_CODE_FAILED; + } + + if (inputNum != 1) { + return TSDB_CODE_FAILED; + } + + char *input = pInput[0].columnData->pData + pInput[0].columnData->varmeta.offset[0]; + for (int32_t i = 0; i < pInput[0].numOfRows; ++i) { + if (colDataIsNull_s(pInput[0].columnData, i)) { + colDataAppendNULL(pOutput->columnData, i); + continue; + } + + int64_t timeVal = 0; + convertStringToTimestamp(type, input, timePrec, &timeVal); + + colDataAppend(pOutput->columnData, i, (char *)&timeVal, false); + input += varDataTLen(input); + } + + pOutput->numOfRows = pInput->numOfRows; + + return TSDB_CODE_SUCCESS; +} + int32_t atanFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { return doScalarFunctionUnique(pInput, inputNum, pOutput, atan); } -- GitLab