diff --git a/include/common/tglobal.h b/include/common/tglobal.h index e4e79e71a9..96488f3bd5 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -158,6 +158,7 @@ extern int32_t tsMetaCacheMaxSize; extern int32_t tsSlowLogThreshold; extern int32_t tsSlowLogScope; extern int32_t tsTimeSeriesThreshold; +extern bool tsMultiResultFunctionStarReturnTags; // client extern int32_t tsMinSlidingTime; diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 22c6767b65..6ae93637d4 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -171,6 +171,7 @@ int32_t tsMetaCacheMaxSize = -1; // MB int32_t tsSlowLogThreshold = 3; // seconds int32_t tsSlowLogScope = SLOW_LOG_TYPE_ALL; int32_t tsTimeSeriesThreshold = 50; +bool tsMultiResultFunctionStarReturnTags = false; /* * denote if the server needs to compress response message at the application layer to client, including query rsp, @@ -550,6 +551,8 @@ static int32_t taosAddClientCfg(SConfig *pCfg) { if (cfgAddBool(pCfg, "monitor", tsEnableMonitor, CFG_SCOPE_BOTH, CFG_DYN_BOTH) != 0) return -1; if (cfgAddInt32(pCfg, "monitorInterval", tsMonitorInterval, 1, 200000, CFG_SCOPE_BOTH, CFG_DYN_NONE) != 0) return -1; + + if (cfgAddBool(pCfg, "multiResultFunctionStarReturnTags", tsMultiResultFunctionStarReturnTags, CFG_SCOPE_CLIENT, CFG_DYN_CLIENT) != 0) return -1; return 0; } @@ -1117,6 +1120,8 @@ static int32_t taosSetClientCfg(SConfig *pCfg) { tsKeepAliveIdle = cfgGetItem(pCfg, "keepAliveIdle")->i32; tsExperimental = cfgGetItem(pCfg, "experimental")->bval; + + tsMultiResultFunctionStarReturnTags = cfgGetItem(pCfg, "multiResultFunctionStarReturnTags")->bval; return 0; } @@ -1760,7 +1765,8 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, char *name) { {"shellActivityTimer", &tsShellActivityTimer}, {"slowLogThreshold", &tsSlowLogThreshold}, {"useAdapter", &tsUseAdapter}, - {"experimental", &tsExperimental}}; + {"experimental", &tsExperimental}, + {"multiResultFunctionStarReturnTags", &tsMultiResultFunctionStarReturnTags} }; if (taosCfgSetOption(debugOptions, tListLen(debugOptions), pItem, true) != 0) { taosCfgSetOption(options, tListLen(options), pItem, false); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 456f4928c0..7821912fc9 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -3442,9 +3442,9 @@ static int32_t createMultiResFuncsParas(STranslateContext* pCxt, SNodeList* pSrc SNode* pPara = NULL; FOREACH(pPara, pSrcParas) { if (nodesIsStar(pPara)) { - code = createAllColumns(pCxt, true, &pExprs); + code = createAllColumns(pCxt, !tsMultiResultFunctionStarReturnTags, &pExprs); } else if (nodesIsTableStar(pPara)) { - code = createTableAllCols(pCxt, (SColumnNode*)pPara, true, &pExprs); + code = createTableAllCols(pCxt, (SColumnNode*)pPara, !tsMultiResultFunctionStarReturnTags, &pExprs); } else { code = nodesListMakeStrictAppend(&pExprs, nodesCloneNode(pPara)); } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index b3f50b540b..0354ae4732 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2689,7 +2689,8 @@ static bool isNeedSplitCacheLastFunc(SFunctionNode* pFunc, SScanLogicNode* pScan int32_t funcType = pFunc->funcType; if ((FUNCTION_TYPE_LAST_ROW != funcType || (FUNCTION_TYPE_LAST_ROW == funcType && TSDB_CACHE_MODEL_LAST_VALUE == pScan->cacheLastMode)) && (FUNCTION_TYPE_LAST != funcType || (FUNCTION_TYPE_LAST == funcType && (TSDB_CACHE_MODEL_LAST_ROW == pScan->cacheLastMode || - QUERY_NODE_OPERATOR == nodeType(nodesListGetNode(pFunc->pParameterList, 0)) || QUERY_NODE_VALUE == nodeType(nodesListGetNode(pFunc->pParameterList, 0))))) && + QUERY_NODE_OPERATOR == nodeType(nodesListGetNode(pFunc->pParameterList, 0)) || QUERY_NODE_VALUE == nodeType(nodesListGetNode(pFunc->pParameterList, 0)) || + COLUMN_TYPE_COLUMN != ((SColumnNode*)nodesListGetNode(pFunc->pParameterList, 0))->colType))) && FUNCTION_TYPE_SELECT_VALUE != funcType && FUNCTION_TYPE_GROUP_KEY != funcType) { return true; } @@ -2709,8 +2710,9 @@ static bool lastRowScanOptCheckFuncList(SLogicNode* pNode, int8_t cacheLastModel if (FUNCTION_TYPE_LAST == pAggFunc->funcType) { if (QUERY_NODE_COLUMN == nodeType(pParam)) { SColumnNode* pCol = (SColumnNode*)pParam; - if (pCol->colType != COLUMN_TYPE_COLUMN) { - return false; + if (pCol->colType != COLUMN_TYPE_COLUMN && TSDB_CACHE_MODEL_LAST_ROW != cacheLastModel) { + needSplitFuncCount++; + *hasOtherFunc = true; } if (lastColId != pCol->colId) { lastColId = pCol->colId; @@ -2991,6 +2993,13 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic } } } + FOREACH(pColNode, pScan->pScanPseudoCols) { + if (nodesEqualNode(pParamNode, pColNode)) { + if (funcType != FUNCTION_TYPE_LAST) { + nodesListMakeAppend(&pLastRowCols, nodesCloneNode(pColNode)); + } + } + } } } @@ -3129,6 +3138,10 @@ static int32_t splitCacheLastFuncOptCreateAggLogicNode(SAggLogicNode** pNewAgg, if (TSDB_CODE_SUCCESS != code) { return code; } + code = nodesCollectColumnsFromNode((SNode*)list, NULL, COLLECT_COL_TYPE_TAG, &pScan->pScanPseudoCols); + if (TSDB_CODE_SUCCESS != code) { + return code; + } nodesFree(list); bool found = false; FOREACH(pNode, pScan->pScanCols) { @@ -3150,6 +3163,10 @@ static int32_t splitCacheLastFuncOptCreateAggLogicNode(SAggLogicNode** pNewAgg, if (TSDB_CODE_SUCCESS != code) { return code; } + code = createColumnByRewriteExprs(pScan->pScanPseudoCols, &pScan->node.pTargets); + if (TSDB_CODE_SUCCESS != code) { + return code; + } OPTIMIZE_FLAG_CLEAR_MASK(pScan->node.optimizedFlag, OPTIMIZE_FLAG_SCAN_PATH); } diff --git a/tests/script/tsim/query/cache_last_tag.sim b/tests/script/tsim/query/cache_last_tag.sim new file mode 100644 index 0000000000..458254625f --- /dev/null +++ b/tests/script/tsim/query/cache_last_tag.sim @@ -0,0 +1,189 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sql connect + +sql alter local "multiResultFunctionStarReturnTags" "0"; + +print step1===================== +sql drop database if exists test; +sql create database test vgroups 4 CACHEMODEL 'both'; +sql use test; +sql create stable st(ts timestamp,a int,b int,c int) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create table t3 using st tags(3,3,3); +sql create table t4 using st tags(NULL,4,4); + +sql insert into t1 values(1648791211000,1,1,1); +sql insert into t1 values(1648791211001,2,2,2); +sql insert into t2 values(1648791211002,3,3,3); +sql insert into t2 values(1648791211003,4,4,4); +sql insert into t3 values(1648791211004,5,5,5); +sql insert into t3 values(1648791211005,6,6,6); +sql insert into t4 values(1648791211007,NULL,NULL,NULL); + +sql select last(*),last_row(*) from st; + +if $cols != 8 then + print ======cols=$cols + return -1 +endi + +sql alter local "multiResultFunctionStarReturnTags" "1"; + +sql select last(*),last_row(*) from st; + +if $cols != 14 then + print ======cols=$cols + return -1 +endi + +sql select last(*) from st; + +if $cols != 7 then + return -1 +endi + +sql select last_row(*) from st; + +if $cols != 7 then + return -1 +endi + +sql select last(*),last_row(*) from t1; + +if $cols != 8 then + return -1 +endi + +print step2===================== + +sql drop database if exists test1; +sql create database test1 vgroups 4 CACHEMODEL 'last_row'; +sql use test1; +sql create stable st(ts timestamp,a int,b int,c int) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create table t3 using st tags(3,3,3); +sql create table t4 using st tags(NULL,4,4); + +sql insert into t1 values(1648791211000,1,1,1); +sql insert into t1 values(1648791211001,2,2,2); +sql insert into t2 values(1648791211002,3,3,3); +sql insert into t2 values(1648791211003,4,4,4); +sql insert into t3 values(1648791211004,5,5,5); +sql insert into t3 values(1648791211005,6,6,6); +sql insert into t4 values(1648791211007,NULL,NULL,NULL); + +sql select last(*),last_row(*) from st; + +if $cols != 14 then + return -1 +endi + +sql select last(*) from st; + +if $cols != 7 then + return -1 +endi + +return -1 + +sql select last_row(*) from st; + +if $cols != 7 then + return -1 +endi + +sql select last(*),last_row(*) from t1; + +if $cols != 8 then + return -1 +endi + +print step3===================== + +sql drop database if exists test2; +sql create database test2 vgroups 4 CACHEMODEL 'last_value'; +sql use test2; +sql create stable st(ts timestamp,a int,b int,c int) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create table t3 using st tags(3,3,3); +sql create table t4 using st tags(NULL,4,4); + +sql insert into t1 values(1648791211000,1,1,1); +sql insert into t1 values(1648791211001,2,2,2); +sql insert into t2 values(1648791211002,3,3,3); +sql insert into t2 values(1648791211003,4,4,4); +sql insert into t3 values(1648791211004,5,5,5); +sql insert into t3 values(1648791211005,6,6,6); +sql insert into t4 values(1648791211007,NULL,NULL,NULL); + +sql select last(*),last_row(*) from st; + +if $cols != 14 then + return -1 +endi + +sql select last(*) from st; + +if $cols != 7 then + return -1 +endi + +sql select last_row(*) from st; + +if $cols != 7 then + return -1 +endi + +sql select last(*),last_row(*) from t1; + +if $cols != 8 then + return -1 +endi + +sql drop database if exists test4; +sql create database test4 vgroups 4; +sql use test4; +sql create stable st(ts timestamp,a int,b int,c int) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create table t3 using st tags(3,3,3); +sql create table t4 using st tags(NULL,4,4); + +sql insert into t1 values(1648791211000,1,1,1); +sql insert into t1 values(1648791211001,2,2,2); +sql insert into t2 values(1648791211002,3,3,3); +sql insert into t2 values(1648791211003,4,4,4); +sql insert into t3 values(1648791211004,5,5,5); +sql insert into t3 values(1648791211005,6,6,6); +sql insert into t4 values(1648791211007,NULL,NULL,NULL); + +sql select last(*),last_row(*) from st; + +if $cols != 14 then + return -1 +endi + +sql select last(*) from st; + +if $cols != 7 then + return -1 +endi + +sql select last_row(*) from st; + +if $cols != 7 then + return -1 +endi + +sql select last(*),last_row(*) from t1; + +if $cols != 8 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT