diff --git a/include/common/ttime.h b/include/common/ttime.h index 306f54bedb2f5609dc2f1e48d47f483e2d9f0d0f..15450c31ca09998cc7ce22853872eff718917a25 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 9d1b2c9ea07ad10c4ac167747d21c20b88b03c4c..148a9f77d6081596332ac1dc4244e86317d69427 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 cd9c6f5bf2bee3f7684bf6873bee9f3bf200881e..226909a18719822745dd81c2d51d51c7ef29c8d9 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 a65352f2b919f85894996193796f4d2efde15b16..1baf393e9a215c9e18cd2208c28a6163a501564b 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 ab5a02c438ba7975a73718e15fa34b7c477dd67d..624a2953c935997c5c35708a21dbe223c29db62a 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 55f38e9005b0e507ed88124e7cc3ae8bf8c16334..44888fa7939b757ca04a72b8f68d9dae77486184 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 58b62bb05e40ff80f50a59601fd1256eb4cc00e3..3d59ffd93d7ac7e59ac1aa9e81023f3d2cb30636 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 0ab0052624fdcf57cd67a1f3552daade82e3b493..e2d28fe454ea4603c2e5f207b88c37add3aebddd 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); }