Merge pull request #26351 from taosdata/fix/TS-5105-1

fix(query):adj second param for last_row
This commit is contained in:
dapan1121 2024-07-02 10:50:36 +08:00 committed by GitHub
commit 2f970dbc03
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 139 additions and 103 deletions

View File

@ -4051,106 +4051,121 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
SNode* pNode = NULL; SNode* pNode = NULL;
SColumnNode* pPKTsCol = NULL; SColumnNode* pPKTsCol = NULL;
SColumnNode* pNonPKCol = NULL; SColumnNode* pNonPKCol = NULL;
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0); SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
pScan->scanType = SCAN_TYPE_LAST_ROW; pScan->scanType = SCAN_TYPE_LAST_ROW;
pScan->igLastNull = pAgg->hasLast ? true : false; pScan->igLastNull = pAgg->hasLast ? true : false;
SArray* isDuplicateCol = taosArrayInit(pScan->pScanCols->length, sizeof(bool)); SArray* isDuplicateCol = taosArrayInit(pScan->pScanCols->length, sizeof(bool));
SNodeList* pLastRowCols = NULL; SNodeList* pLastRowCols = NULL;
bool adjLastRowTsColName = false;
char tsColName[TSDB_COL_NAME_LEN] = {0};
FOREACH(pNode, pAgg->pAggFuncs) { FOREACH(pNode, pAgg->pAggFuncs) {
SFunctionNode* pFunc = (SFunctionNode*)pNode; SFunctionNode* pFunc = (SFunctionNode*)pNode;
int32_t funcType = pFunc->funcType; int32_t funcType = pFunc->funcType;
SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, 0); SNode* pParamNode = NULL;
if (FUNCTION_TYPE_LAST_ROW == funcType || FUNCTION_TYPE_LAST == funcType) { if (FUNCTION_TYPE_LAST == funcType) {
int32_t len = snprintf(pFunc->functionName, sizeof(pFunc->functionName), nodesListErase(pFunc->pParameterList, nodesListGetCell(pFunc->pParameterList, 1));
FUNCTION_TYPE_LAST_ROW == funcType ? "_cache_last_row" : "_cache_last"); nodesWalkExpr(nodesListGetNode(pFunc->pParameterList, 0), lastRowScanOptSetColDataType, &cxt);
pFunc->functionName[len] = '\0'; }
int32_t code = fmGetFuncInfo(pFunc, NULL, 0); FOREACH(pParamNode, pFunc->pParameterList) {
if (TSDB_CODE_SUCCESS != code) { if (FUNCTION_TYPE_LAST_ROW == funcType || FUNCTION_TYPE_LAST == funcType) {
nodesClearList(cxt.pLastCols); int32_t len = snprintf(pFunc->functionName, sizeof(pFunc->functionName),
return code; FUNCTION_TYPE_LAST_ROW == funcType ? "_cache_last_row" : "_cache_last");
} pFunc->functionName[len] = '\0';
cxt.funcType = pFunc->funcType; int32_t code = fmGetFuncInfo(pFunc, NULL, 0);
cxt.pkBytes = (pFunc->hasPk) ? pFunc->pkBytes : 0; if (TSDB_CODE_SUCCESS != code) {
// add duplicate cols which be removed for both last_row, last nodesClearList(cxt.pLastCols);
if (pAgg->hasLast && pAgg->hasLastRow) { return code;
if (QUERY_NODE_COLUMN == nodeType(pParamNode)) { }
SNode* pColNode = NULL; cxt.funcType = pFunc->funcType;
int i = 0; cxt.pkBytes = (pFunc->hasPk) ? pFunc->pkBytes : 0;
FOREACH(pColNode, pScan->pScanCols) { // add duplicate cols which be removed for both last_row, last
bool isDup = false; if (pAgg->hasLast && pAgg->hasLastRow) {
bool* isDuplicate = taosArrayGet(isDuplicateCol, i); if (QUERY_NODE_COLUMN == nodeType(pParamNode)) {
if (NULL == isDuplicate) { SNode* pColNode = NULL;
taosArrayInsert(isDuplicateCol, i, &isDup); int i = 0;
isDuplicate = taosArrayGet(isDuplicateCol, i); FOREACH(pColNode, pScan->pScanCols) {
bool isDup = false;
bool* isDuplicate = taosArrayGet(isDuplicateCol, i);
if (NULL == isDuplicate) {
taosArrayInsert(isDuplicateCol, i, &isDup);
isDuplicate = taosArrayGet(isDuplicateCol, i);
}
i++;
if (nodesEqualNode(pParamNode, pColNode)) {
if (*isDuplicate) {
if (0 == strncmp(((SColumnNode*)pColNode)->colName, "#dup_col.", 9)) {
continue;
}
SNode* newColNode = nodesCloneNode(pColNode);
sprintf(((SColumnNode*)newColNode)->colName, "#dup_col.%p", newColNode);
sprintf(((SColumnNode*)pParamNode)->colName, "#dup_col.%p", newColNode);
if (FUNCTION_TYPE_LAST_ROW == funcType &&
((SColumnNode*)pParamNode)->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
if (!adjLastRowTsColName) {
adjLastRowTsColName = true;
strncpy(tsColName, ((SColumnNode*)pParamNode)->colName, TSDB_COL_NAME_LEN);
} else {
strncpy(((SColumnNode*)pParamNode)->colName, tsColName, TSDB_COL_NAME_LEN);
nodesDestroyNode(newColNode);
continue;
}
}
nodesListAppend(pScan->pScanCols, newColNode);
isDup = true;
taosArrayInsert(isDuplicateCol, pScan->pScanCols->length, &isDup);
nodesListAppend(pScan->node.pTargets, nodesCloneNode(newColNode));
if (funcType != FUNCTION_TYPE_LAST) {
nodesListMakeAppend(&pLastRowCols, nodesCloneNode(newColNode));
}
lastRowScanBuildFuncTypes(pScan, (SColumnNode*)newColNode, pFunc->funcType);
} else {
isDup = true;
*isDuplicate = isDup;
if (funcType != FUNCTION_TYPE_LAST && !nodeListNodeEqual(cxt.pLastCols, pColNode)) {
nodesListMakeAppend(&pLastRowCols, nodesCloneNode(pColNode));
}
lastRowScanBuildFuncTypes(pScan, (SColumnNode*)pColNode, pFunc->funcType);
}
continue;
}else if (nodeListNodeEqual(pFunc->pParameterList, pColNode)) {
if (funcType != FUNCTION_TYPE_LAST && ((SColumnNode*)pColNode)->colId == PRIMARYKEY_TIMESTAMP_COL_ID &&
!nodeListNodeEqual(pLastRowCols, pColNode)) {
nodesListMakeAppend(&pLastRowCols, nodesCloneNode(pColNode));
lastRowScanBuildFuncTypes(pScan, (SColumnNode*)pColNode, pFunc->funcType);
isDup = true;
*isDuplicate = isDup;
}
}
} }
i++; FOREACH(pColNode, pScan->pScanPseudoCols) {
if (nodesEqualNode(pParamNode, pColNode)) { if (nodesEqualNode(pParamNode, pColNode)) {
if (*isDuplicate) {
if (0 == strncmp(((SColumnNode*)pColNode)->colName, "#dup_col.", 9)) {
continue;
}
SNode* newColNode = nodesCloneNode(pColNode);
sprintf(((SColumnNode*)newColNode)->colName, "#dup_col.%p", newColNode);
sprintf(((SColumnNode*)pParamNode)->colName, "#dup_col.%p", newColNode);
nodesListAppend(pScan->pScanCols, newColNode);
isDup = true;
taosArrayInsert(isDuplicateCol, pScan->pScanCols->length, &isDup);
nodesListAppend(pScan->node.pTargets, nodesCloneNode(newColNode));
if (funcType != FUNCTION_TYPE_LAST) { if (funcType != FUNCTION_TYPE_LAST) {
nodesListMakeAppend(&pLastRowCols, nodesCloneNode(newColNode));
}
lastRowScanBuildFuncTypes(pScan, (SColumnNode*)newColNode, pFunc->funcType);
} else {
isDup = true;
*isDuplicate = isDup;
if (funcType != FUNCTION_TYPE_LAST && !nodeListNodeEqual(cxt.pLastCols, pColNode)) {
nodesListMakeAppend(&pLastRowCols, nodesCloneNode(pColNode)); nodesListMakeAppend(&pLastRowCols, nodesCloneNode(pColNode));
} }
lastRowScanBuildFuncTypes(pScan, (SColumnNode*)pColNode, pFunc->funcType);
}
continue;
}else if (nodeListNodeEqual(pFunc->pParameterList, pColNode)) {
if (funcType != FUNCTION_TYPE_LAST && ((SColumnNode*)pColNode)->colId == PRIMARYKEY_TIMESTAMP_COL_ID &&
!nodeListNodeEqual(pLastRowCols, pColNode)) {
nodesListMakeAppend(&pLastRowCols, nodesCloneNode(pColNode));
lastRowScanBuildFuncTypes(pScan, (SColumnNode*)pColNode, pFunc->funcType);
isDup = true;
*isDuplicate = isDup;
}
}
}
FOREACH(pColNode, pScan->pScanPseudoCols) {
if (nodesEqualNode(pParamNode, pColNode)) {
if (funcType != FUNCTION_TYPE_LAST) {
nodesListMakeAppend(&pLastRowCols, nodesCloneNode(pColNode));
} }
} }
} }
} }
}
if (FUNCTION_TYPE_LAST == funcType) { if (pFunc->hasPk) {
nodesWalkExpr(nodesListGetNode(pFunc->pParameterList, 0), lastRowScanOptSetColDataType, &cxt); nodesListMakeAppend(&cxt.pOtherCols, nodesListGetNode(pFunc->pParameterList, LIST_LENGTH(pFunc->pParameterList) - 1));
nodesListErase(pFunc->pParameterList, nodesListGetCell(pFunc->pParameterList, 1)); }
} } else {
if (pFunc->hasPk) { pNode = nodesListGetNode(pFunc->pParameterList, 0);
nodesListMakeAppend(&cxt.pOtherCols, nodesListGetNode(pFunc->pParameterList, LIST_LENGTH(pFunc->pParameterList) - 1)); nodesListMakeAppend(&cxt.pOtherCols, pNode);
}
} else {
pNode = nodesListGetNode(pFunc->pParameterList, 0);
nodesListMakeAppend(&cxt.pOtherCols, pNode);
if (FUNCTION_TYPE_SELECT_VALUE == funcType) { if (FUNCTION_TYPE_SELECT_VALUE == funcType) {
if (nodeType(pNode) == QUERY_NODE_COLUMN) { if (nodeType(pNode) == QUERY_NODE_COLUMN) {
SColumnNode* pCol = (SColumnNode*)pNode; SColumnNode* pCol = (SColumnNode*)pNode;
if (pCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) { if (pCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
pPKTsCol = pCol; pPKTsCol = pCol;
} else { } else {
pNonPKCol = pCol; pNonPKCol = pCol;
}
} }
} }
} }

View File

@ -141,7 +141,7 @@ if $data01 != t2 then
return -1 return -1
endi endi
sql select last(ts) ts1,tbname, ts from stb group by tbname; sql select last(ts) ts1,tbname, ts from stb group by tbname order by 1 desc;
if $data00 != $data02 then if $data00 != $data02 then
print $data00 print $data00
@ -156,16 +156,16 @@ endi
print step 3------------------------------- print step 3-------------------------------
sql drop database if exists test1; sql drop database if exists test1;
sql create database test1 cachemodel 'both'; sql create database test1 cachemodel 'both' vgroups 4;
sql use test1; sql use test1;
sql create table stb (ts timestamp,a int primary key,b int,c int) tags(ta int,tb int,tc int); sql create table stb (ts timestamp,a int primary key,b int,c int) tags(ta int,tb int,tc int);
sql create table t1 using stb tags(1,1,1); sql create table aaat1 using stb tags(1,1,1);
sql create table t2 using stb tags(2,2,2); sql create table bbbt2 using stb tags(2,2,2);
sql insert into t1 values('2024-06-05 11:00:00',1,2,3); sql insert into aaat1 values('2024-06-05 11:00:00',1,2,3);
sql insert into t1 values('2024-06-05 12:00:00',2,2,3); sql insert into aaat1 values('2024-06-05 12:00:00',2,2,3);
sql insert into t2 values('2024-06-05 13:00:00',3,2,3); sql insert into bbbt2 values('2024-06-05 13:00:00',3,2,3);
sql insert into t2 values('2024-06-05 14:00:00',4,2,3); sql insert into bbbt2 values('2024-06-05 14:00:00',4,2,3);
sql select last(ts) ts1,ts from stb; sql select last(ts) ts1,ts from stb;
@ -179,7 +179,7 @@ if $data00 != @24-06-05 14:00:00.000@ then
return -1 return -1
endi endi
sql select last(ts) ts1,ts from stb group by tbname; sql select last(ts) ts1,ts from stb group by tbname order by 1 desc;
if $data00 != $data01 then if $data00 != $data01 then
print $data00 print $data00
@ -203,12 +203,12 @@ if $data00 != @24-06-05 14:00:00.000@ then
return -1 return -1
endi endi
if $data01 != t2 then if $data01 != bbbt2 then
print $data01 print $data01
return -1 return -1
endi endi
sql select last(ts) ts1,tbname, ts from stb group by tbname; sql select last(ts) ts1,tbname, ts from stb group by tbname order by 1 desc;
if $data00 != $data02 then if $data00 != $data02 then
print $data00 print $data00
@ -220,7 +220,7 @@ if $data00 != @24-06-05 14:00:00.000@ then
return -1 return -1
endi endi
if $data01 != t2 then if $data01 != bbbt2 then
print $data01 print $data01
return -1 return -1
endi endi
@ -239,7 +239,7 @@ if $data01 != @24-06-05 14:00:00.000@ then
return -1 return -1
endi endi
sql select last(a) a,ts from stb group by tbname; sql select last(a) a,ts from stb group by tbname order by 1 desc;
if $data00 != 4 then if $data00 != 4 then
print $data00 print $data00
@ -258,7 +258,7 @@ if $data00 != 4 then
return -1 return -1
endi endi
if $data01 != t2 then if $data01 != bbbt2 then
print $data01 print $data01
return -1 return -1
endi endi
@ -268,14 +268,14 @@ if $data02 != @24-06-05 14:00:00.000@ then
return -1 return -1
endi endi
sql select last(a) a,tbname, ts from stb group by tbname; sql select last(a) a,tbname, ts from stb group by tbname order by 1 desc;
if $data00 != 4 then if $data00 != 4 then
print $data00 print $data00
return -1 return -1
endi endi
if $data01 != t2 then if $data01 != bbbt2 then
print $data01 print $data01
return -1 return -1
endi endi
@ -299,7 +299,7 @@ if $data01 != 4 then
return -1 return -1
endi endi
sql select last(ts) ts1,a from stb group by tbname; sql select last(ts) ts1,a from stb group by tbname order by 1 desc;
if $data00 != @24-06-05 14:00:00.000@ then if $data00 != @24-06-05 14:00:00.000@ then
print $data00 print $data00
@ -318,7 +318,7 @@ if $data00 != @24-06-05 14:00:00.000@ then
return -1 return -1
endi endi
if $data01 != t2 then if $data01 != bbbt2 then
print $data01 print $data01
return -1 return -1
endi endi
@ -328,14 +328,14 @@ if $data02 != 4 then
return -1 return -1
endi endi
sql select last(ts) ts1,tbname, a from stb group by tbname; sql select last(ts) ts1,tbname, a from stb group by tbname order by 1 desc;
if $data00 != @24-06-05 14:00:00.000@ then if $data00 != @24-06-05 14:00:00.000@ then
print $data00 print $data00
return -1 return -1
endi endi
if $data01 != t2 then if $data01 != bbbt2 then
print $data01 print $data01
return -1 return -1
endi endi
@ -345,4 +345,25 @@ if $data02 != 4 then
return -1 return -1
endi endi
$loop_count = 0
loop0:
sql select last(ts), last_row(ts) from stb;
if $data00 != $data01 then
print ====data00=$data00
print ====data01=$data01
return -1
endi
$loop_count = $loop_count + 1
if $loop_count < 10 then
sleep 200
print ====checktimes=$loop_count
goto loop0
endi
print ------------------------end
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT