diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index 12cd6f1bc19360deb0daf369b84b9f35a81b7de2..60692323f5806c852c8e7dc53d5857a192a93882 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -141,12 +141,12 @@ static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) { case TSDB_DATA_TYPE_NCHAR: case TSDB_DATA_TYPE_VARCHAR: case TSDB_DATA_TYPE_VARBINARY: - pDst->datum.p = malloc(pSrc->node.resType.bytes + VARSTR_HEADER_SIZE); + pDst->datum.p = malloc(pSrc->node.resType.bytes + VARSTR_HEADER_SIZE + 1); if (NULL == pDst->datum.p) { nodesDestroyNode(pDst); return NULL; } - memcpy(pDst->datum.p, pSrc->datum.p, pSrc->node.resType.bytes + VARSTR_HEADER_SIZE); + memcpy(pDst->datum.p, pSrc->datum.p, pSrc->node.resType.bytes + VARSTR_HEADER_SIZE + 1); break; case TSDB_DATA_TYPE_JSON: case TSDB_DATA_TYPE_DECIMAL: diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index b648e1880945528eb4af4b531b9bc9cccfc551e6..37be210610fea287aac0c951ba11131db336e03b 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -1807,6 +1807,45 @@ static int32_t groupingSetNodeToJson(const void* pObj, SJson* pJson) { return code; } +static const char* jkIntervalWindowInterval = "Interval"; +static const char* jkIntervalWindowOffset = "Offset"; +static const char* jkIntervalWindowSliding = "Sliding"; +static const char* jkIntervalWindowFill = "Fill"; + +static int32_t intervalWindowNodeToJson(const void* pObj, SJson* pJson) { + const SIntervalWindowNode* pNode = (const SIntervalWindowNode*)pObj; + + int32_t code = tjsonAddObject(pJson, jkIntervalWindowInterval, nodeToJson, pNode->pInterval); + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkIntervalWindowOffset, nodeToJson, pNode->pOffset); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkIntervalWindowSliding, nodeToJson, pNode->pSliding); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkIntervalWindowFill, nodeToJson, pNode->pFill); + } + + return code; +} + +static int32_t jsonToIntervalWindowNode(const SJson* pJson, void* pObj) { + SIntervalWindowNode* pNode = (SIntervalWindowNode*)pObj; + + int32_t code = jsonToNodeObject(pJson, jkIntervalWindowInterval, &pNode->pInterval); + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeObject(pJson, jkIntervalWindowOffset, &pNode->pOffset); + } + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeObject(pJson, jkIntervalWindowSliding, &pNode->pSliding); + } + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeObject(pJson, jkIntervalWindowFill, &pNode->pFill); + } + + return code; +} + static const char* jkNodeListDataType = "DataType"; static const char* jkNodeListNodeList = "NodeList"; @@ -2119,8 +2158,9 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { case QUERY_NODE_LIMIT: case QUERY_NODE_STATE_WINDOW: case QUERY_NODE_SESSION_WINDOW: - case QUERY_NODE_INTERVAL_WINDOW: break; + case QUERY_NODE_INTERVAL_WINDOW: + return intervalWindowNodeToJson(pObj, pJson); case QUERY_NODE_NODE_LIST: return nodeListNodeToJson(pObj, pJson); case QUERY_NODE_FILL: @@ -2222,7 +2262,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { // case QUERY_NODE_LIMIT: // case QUERY_NODE_STATE_WINDOW: // case QUERY_NODE_SESSION_WINDOW: - // case QUERY_NODE_INTERVAL_WINDOW: + case QUERY_NODE_INTERVAL_WINDOW: + return jsonToIntervalWindowNode(pJson, pObj); case QUERY_NODE_NODE_LIST: return jsonToNodeListNode(pJson, pObj); // case QUERY_NODE_FILL: diff --git a/source/libs/planner/test/plannerTest.cpp b/source/libs/planner/test/plannerTest.cpp index 69203384f8c0ec5b77cd36735a546f5b1e36814f..319e539fa81b1a5ae2667b9d14875527678cd4e1 100644 --- a/source/libs/planner/test/plannerTest.cpp +++ b/source/libs/planner/test/plannerTest.cpp @@ -112,6 +112,11 @@ private: if (QUERY_NODE_CREATE_TOPIC_STMT == nodeType(pQuery->pRoot)) { pCxt->pAstRoot = ((SCreateTopicStmt*)pQuery->pRoot)->pQuery; pCxt->topicQuery = true; + } else if (QUERY_NODE_CREATE_INDEX_STMT == nodeType(pQuery->pRoot)) { + SMCreateSmaReq req = {0}; + tDeserializeSMCreateSmaReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req); + nodesStringToNode(req.ast, &pCxt->pAstRoot); + pCxt->streamQuery = true; } else { pCxt->pAstRoot = pQuery->pRoot; } @@ -215,3 +220,10 @@ TEST_F(PlannerTest, stream) { bind("SELECT sum(c1) FROM st1"); ASSERT_TRUE(run(true)); } + +TEST_F(PlannerTest, createSmaIndex) { + setDatabase("root", "test"); + + bind("create sma index index1 on t1 function(max(c1), min(c3 + 10), sum(c4)) INTERVAL(10s)"); + ASSERT_TRUE(run()); +}