From 30aec155d99d2f007591510b33303209b887f789 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Tue, 8 Feb 2022 14:29:41 +0800 Subject: [PATCH] [TD-11220](query): time related functions --- src/client/src/tscSQLParser.c | 6 +-- src/common/inc/texpr.h | 4 +- src/common/src/texpr.c | 81 ++++++++++++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 5 deletions(-) diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index eebf9989b1..8d2011d6eb 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1853,7 +1853,7 @@ static int32_t handleScalarTypeExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 if (tscGetErrorMsgLength(pCmd) > 0) { return ret; } - + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } @@ -1864,7 +1864,7 @@ static int32_t handleScalarTypeExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 if (TSDB_COL_IS_TAG(pIndex->flag)) { tExprTreeDestroy(pNode, NULL); taosArrayDestroy(&colList); - + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -1876,7 +1876,7 @@ static int32_t handleScalarTypeExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 if (tscGetErrorMsgLength(pCmd) > 0) { return ret; } - + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } diff --git a/src/common/inc/texpr.h b/src/common/inc/texpr.h index 311f650733..298000e77c 100644 --- a/src/common/inc/texpr.h +++ b/src/common/inc/texpr.h @@ -65,7 +65,9 @@ struct SSchema; #define TSDB_FUNC_SCALAR_CONCAT_WS (TSDB_FUNC_FLAG_SCALAR | 0x000F) #define TSDB_FUNC_SCALAR_CHAR_LENGTH (TSDB_FUNC_FLAG_SCALAR | 0x0010) #define TSDB_FUNC_SCALAR_CAST (TSDB_FUNC_FLAG_SCALAR | 0x0011) -#define TSDB_FUNC_SCALAR_MAX_NUM 18 +#define TSDB_FUNC_SCALAR_NOW (TSDB_FUNC_FLAG_SCALAR | 0x0012) +#define TSDB_FUNC_SCALAR_TODAY (TSDB_FUNC_FLAG_SCALAR | 0x0013) +#define TSDB_FUNC_SCALAR_MAX_NUM 20 #define TSDB_FUNC_SCALAR_NAME_MAX_LEN 16 diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c index db3bec2ddf..074f005e99 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -34,6 +34,7 @@ static int32_t exprValidateStringConcatNode(tExprNode *pExpr); static int32_t exprValidateStringConcatWsNode(tExprNode *pExpr); static int32_t exprValidateStringLengthNode(tExprNode *pExpr); static int32_t exprValidateCastNode(char* msgbuf, tExprNode *pExpr); +static int32_t exprValidateTimeNode(tExprNode *pExpr); static int32_t exprInvalidOperationMsg(char *msgbuf, const char *msg) { const char* msgFormat = "invalid operation: %s"; @@ -47,7 +48,7 @@ static int32_t exprInvalidOperationMsg(char *msgbuf, const char *msg) { int32_t exprTreeValidateFunctionNode(char* msgbuf, tExprNode *pExpr) { int32_t code = TSDB_CODE_SUCCESS; - //TODO: check childs for every function + //TODO: check children for every function switch (pExpr->_func.functionId) { case TSDB_FUNC_SCALAR_POW: case TSDB_FUNC_SCALAR_LOG: @@ -77,6 +78,10 @@ int32_t exprTreeValidateFunctionNode(char* msgbuf, tExprNode *pExpr) { case TSDB_FUNC_SCALAR_CONCAT_WS: { return exprValidateStringConcatWsNode(pExpr); } + case TSDB_FUNC_SCALAR_TODAY: + case TSDB_FUNC_SCALAR_NOW: { + return exprValidateTimeNode(pExpr); + } default: break; @@ -1157,6 +1162,25 @@ int32_t exprValidateMathNode(tExprNode *pExpr) { return TSDB_CODE_SUCCESS; } +int32_t exprValidateTimeNode(tExprNode *pExpr) { + switch (pExpr->_func.functionId) { + case TSDB_FUNC_SCALAR_NOW: + case TSDB_FUNC_SCALAR_TODAY: { + if (pExpr->_func.numChildren != 0) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + pExpr->resultType = TSDB_DATA_TYPE_TIMESTAMP; + pExpr->resultBytes = (int16_t)tDataTypes[pExpr->resultType].bytes; + break; + } + default: { + assert(false); + break; + } + } + return TSDB_CODE_SUCCESS; +} + void vectorConcat(int16_t functionId, tExprOperandInfo* pInputs, int32_t numInputs, tExprOperandInfo* pOutput, int32_t order) { assert(functionId == TSDB_FUNC_SCALAR_CONCAT && numInputs >=2 && order == TSDB_ORDER_ASC); for (int i = 0; i < numInputs; ++i) { @@ -1626,6 +1650,51 @@ void vectorMathFunc(int16_t functionId, tExprOperandInfo *pInputs, int32_t numIn free(inputData); } +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); + } + + char* outputData = NULL; + char** inputData = calloc(numInputs, sizeof(char*)); + for (int i = 0; i < pOutput->numOfRows; ++i) { + for (int j = 0; j < numInputs; ++j) { + if (pInputs[j].numOfRows == 1) { + inputData[j] = pInputs[j].data; + } else { + inputData[j] = pInputs[j].data + i * pInputs[j].bytes; + } + } + + outputData = pOutput->data + i * pOutput->bytes; + + bool hasNullInputs = false; + for (int j = 0; j < numInputs; ++j) { + if (isNull(inputData[j], pInputs[j].type)) { + hasNullInputs = true; + setNull(outputData, pOutput->type, pOutput->bytes); + } + } + + if (!hasNullInputs) { + switch (functionId) { + case TSDB_FUNC_SCALAR_NOW: + case TSDB_FUNC_SCALAR_TODAY: { + assert(numInputs == 0); + double result = 345; + SET_TYPED_DATA(outputData, pOutput->type, result); + break; + } + default: { + assert(false); + break; + } + } // end switch function(id) + } // end can produce value, all child has value + } // end for each row + free(inputData); +} + _expr_scalar_function_t getExprScalarFunction(uint16_t funcId) { assert(TSDB_FUNC_IS_SCALAR(funcId)); int16_t scalaIdx = TSDB_FUNC_SCALAR_INDEX(funcId); @@ -1724,4 +1793,14 @@ tScalarFunctionInfo aScalarFunctions[] = { "cast", vectorMathFunc }, + { + TSDB_FUNC_SCALAR_NOW, + "now", + vectorTimeFunc + }, + { + TSDB_FUNC_SCALAR_TODAY, + "today", + vectorTimeFunc + }, }; -- GitLab