From a391cc49df3f1951842bdb15fc94c4739e13fa6b Mon Sep 17 00:00:00 2001 From: facetosea <285808407@qq.com> Date: Thu, 13 Feb 2025 11:08:58 +0000 Subject: [PATCH] cols in order clause --- source/libs/nodes/src/nodesEqualFuncs.c | 1 + source/libs/parser/src/parTranslater.c | 61 +++------------------- tests/system-test/2-query/cols_function.py | 17 ++++++ 3 files changed, 24 insertions(+), 55 deletions(-) diff --git a/source/libs/nodes/src/nodesEqualFuncs.c b/source/libs/nodes/src/nodesEqualFuncs.c index d255c2fd6b..e1c17f5c35 100644 --- a/source/libs/nodes/src/nodesEqualFuncs.c +++ b/source/libs/nodes/src/nodesEqualFuncs.c @@ -141,6 +141,7 @@ static bool functionNodeEqual(const SFunctionNode* a, const SFunctionNode* b) { if (a->funcType == FUNCTION_TYPE_SELECT_VALUE) { if ((a->node.bindTupleFuncIdx != b->node.bindTupleFuncIdx)) return false; } else { + // select cols(cols(first(c0), ts), first(c0) from meters; if ((a->node.tupleFuncIdx != b->node.tupleFuncIdx)) { return false; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 7ab0261458..d890c8ed04 100755 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5461,12 +5461,17 @@ static int32_t translateClausePosition(STranslateContext* pCxt, SNodeList* pProj } static int32_t rewriteColsFunction(STranslateContext* pCxt, SNodeList** nodeList, SNodeList** selectFuncList); +static int32_t preGetBindCols(STranslateContext* pCxt, SSelectStmt* pSelect, SNodeList** selectFuncList) { + return rewriteColsFunction(pCxt, &pSelect->pOrderByList, selectFuncList); +} + static int32_t translateSelectColsFunction(STranslateContext* pCxt, SSelectStmt* pSelect) { SNodeList* selectFuncList = NULL; int32_t code = rewriteColsFunction(pCxt, &pSelect->pProjectionList, &selectFuncList); if (TSDB_CODE_SUCCESS != code) { goto _end; } + code = preGetBindCols(pCxt, pSelect, &selectFuncList); if (selectFuncList != NULL) { code = nodesListAppendList(pSelect->pProjectionList, selectFuncList); if (TSDB_CODE_SUCCESS != code) { @@ -5481,62 +5486,9 @@ _end: return code; } -static int32_t getBindedExprList(STranslateContext* pCxt, SNodeList* projectionList, SNodeList** selectFuncList) { - int32_t code = TSDB_CODE_SUCCESS; - for (int32_t i = 0; i < LIST_LENGTH(projectionList); ++i) { - SNode* pNode = nodesListGetNode(projectionList, i); - if (((SExprNode*)pNode)->bindTupleFuncIdx > 0) { - if (NULL == *selectFuncList) { - code = nodesMakeList(selectFuncList); - if (TSDB_CODE_SUCCESS != code) { - return code; - } - } - code = nodesListStrictAppend(*selectFuncList, pNode); - if (TSDB_CODE_SUCCESS != code) { - return code; - } - } - } - return code; -} - -static int32_t translateOrderbyColsFunction(STranslateContext* pCxt, SSelectStmt* pSelect) { - SNodeList* selectFuncList = NULL; - int32_t code = getBindedExprList(pCxt, pSelect->pProjectionList, &selectFuncList); - if (TSDB_CODE_SUCCESS != code) { - goto _end; - } - int len = LIST_LENGTH(selectFuncList); - code = rewriteColsFunction(pCxt, &pSelect->pOrderByList, &selectFuncList); - if (TSDB_CODE_SUCCESS != code) { - goto _end; - } - if(LIST_LENGTH(selectFuncList) - len > 0) { - for (int i = len; i < LIST_LENGTH(selectFuncList); ++i) { - SNode* pNode = nodesListGetNode(selectFuncList, i); - int32_t code = nodesListStrictAppend(pSelect->pProjectionList, pNode); - if (TSDB_CODE_SUCCESS != code) { - return code; - } - } - } - nodesClearList(selectFuncList); - return code; -_end: - if (selectFuncList) { - nodesDestroyList(selectFuncList); - } - return code; -} - static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) { bool other; - int32_t code = translateOrderbyColsFunction(pCxt, pSelect); - if (TSDB_CODE_SUCCESS != code) { - return code; - } - code = translateClausePosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other); + int32_t code = translateClausePosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other); if (TSDB_CODE_SUCCESS == code) { if (0 == LIST_LENGTH(pSelect->pOrderByList)) { NODES_DESTORY_LIST(pSelect->pOrderByList); @@ -5756,7 +5708,6 @@ static int32_t translatePartitionByList(STranslateContext* pCxt, SSelectStmt* pS static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect) { pCxt->currClause = SQL_CLAUSE_SELECT; int32_t code = translateSelectColsFunction(pCxt, pSelect); - code = translateOrderbyColsFunction(pCxt, pSelect); if (TSDB_CODE_SUCCESS == code) { code = translateExprList(pCxt, pSelect->pProjectionList); } diff --git a/tests/system-test/2-query/cols_function.py b/tests/system-test/2-query/cols_function.py index 7707fbccb5..7f128e28d0 100644 --- a/tests/system-test/2-query/cols_function.py +++ b/tests/system-test/2-query/cols_function.py @@ -941,6 +941,22 @@ class TDTestCase: def stream_cols_test(self): tdSql.error(f'CREATE STREAM last_col_s1 INTO last_col1 AS SELECT cols(last(ts), ts, c0) FROM meters PARTITION BY tbname INTERVAL(1s) SLIDING(1s);', TSDB_CODE_PAR_INVALID_COLS_FUNCTION) tdSql.query(f'CREATE STREAM last_col_s INTO last_col AS SELECT last(ts), c0 FROM meters PARTITION BY tbname INTERVAL(1s) SLIDING(1s);') + + def include_null_test(self): + tdSql.execute(f'insert into {self.dbname}.d0 values(1734574929010, 0, NULL, NULL, NULL)') + tdSql.execute(f'insert into {self.dbname}.d0 values(1734574929011, NULL, 1, NULL, NULL)') + tdSql.execute(f'insert into {self.dbname}.d0 values(1734574929012, NULL, NULL, 2, NULL)') + tdSql.execute(f'insert into {self.dbname}.d0 values(1734574929013, NULL, NULL, NULL, false)') + tdSql.execute(f'insert into {self.dbname}.d0 values(1734574929014, NULL, NULL, NULL, NULL)') + + tdSql.query(f'select cols(last(c0), ts), cols(last(c1), ts), cols(last(c2), ts), cols(last(c3), ts) from {self.dbname}.d0') + tdSql.checkRows(1) + tdSql.checkCols(4) + tdSql.checkData(0, 0, 1734574929010) + tdSql.checkData(0, 1, 1734574929011) + tdSql.checkData(0, 2, 1734574929012) + tdSql.checkData(0, 3, 1734574929013) + def run(self): self.funcNestTest() @@ -953,6 +969,7 @@ class TDTestCase: self.window_test() self.join_test() self.stream_cols_test() + self.include_null_test() def stop(self): tdSql.close()