Merge pull request #16395 from taosdata/szhou/save-op-state
fix: support window pseduo column _wstart,_wend,_wduration for fill operator
This commit is contained in:
commit
689caa1f97
|
@ -205,7 +205,7 @@ typedef struct SColumn {
|
||||||
int16_t slotId;
|
int16_t slotId;
|
||||||
|
|
||||||
char name[TSDB_COL_NAME_LEN];
|
char name[TSDB_COL_NAME_LEN];
|
||||||
int8_t flag; // column type: normal column, tag, or user-input column (integer/float/string)
|
int16_t colType; // column type: normal column, tag, or window column
|
||||||
int16_t type;
|
int16_t type;
|
||||||
int32_t bytes;
|
int32_t bytes;
|
||||||
uint8_t precision;
|
uint8_t precision;
|
||||||
|
|
|
@ -57,7 +57,9 @@ typedef enum EColumnType {
|
||||||
COLUMN_TYPE_COLUMN = 1,
|
COLUMN_TYPE_COLUMN = 1,
|
||||||
COLUMN_TYPE_TAG,
|
COLUMN_TYPE_TAG,
|
||||||
COLUMN_TYPE_TBNAME,
|
COLUMN_TYPE_TBNAME,
|
||||||
COLUMN_TYPE_WINDOW_PC,
|
COLUMN_TYPE_WINDOW_START,
|
||||||
|
COLUMN_TYPE_WINDOW_END,
|
||||||
|
COLUMN_TYPE_WINDOW_DURATION,
|
||||||
COLUMN_TYPE_GROUP_KEY
|
COLUMN_TYPE_GROUP_KEY
|
||||||
} EColumnType;
|
} EColumnType;
|
||||||
|
|
||||||
|
|
|
@ -284,17 +284,17 @@ int32_t isQualifiedTable(STableKeyInfo* info, SNode* pTagCond, void* metaHandle,
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct tagFilterAssist{
|
typedef struct tagFilterAssist {
|
||||||
SHashObj *colHash;
|
SHashObj* colHash;
|
||||||
int32_t index;
|
int32_t index;
|
||||||
SArray *cInfoList;
|
SArray* cInfoList;
|
||||||
}tagFilterAssist;
|
} tagFilterAssist;
|
||||||
|
|
||||||
static EDealRes getColumn(SNode** pNode, void* pContext) {
|
static EDealRes getColumn(SNode** pNode, void* pContext) {
|
||||||
SColumnNode* pSColumnNode = NULL;
|
SColumnNode* pSColumnNode = NULL;
|
||||||
if (QUERY_NODE_COLUMN == nodeType((*pNode))) {
|
if (QUERY_NODE_COLUMN == nodeType((*pNode))) {
|
||||||
pSColumnNode = *(SColumnNode**)pNode;
|
pSColumnNode = *(SColumnNode**)pNode;
|
||||||
}else if(QUERY_NODE_FUNCTION == nodeType((*pNode))){
|
} else if (QUERY_NODE_FUNCTION == nodeType((*pNode))) {
|
||||||
SFunctionNode* pFuncNode = *(SFunctionNode**)(pNode);
|
SFunctionNode* pFuncNode = *(SFunctionNode**)(pNode);
|
||||||
if (pFuncNode->funcType == FUNCTION_TYPE_TBNAME) {
|
if (pFuncNode->funcType == FUNCTION_TYPE_TBNAME) {
|
||||||
pSColumnNode = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
pSColumnNode = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||||
|
@ -307,24 +307,26 @@ static EDealRes getColumn(SNode** pNode, void* pContext) {
|
||||||
pSColumnNode->node.resType.bytes = TSDB_TABLE_FNAME_LEN - 1 + VARSTR_HEADER_SIZE;
|
pSColumnNode->node.resType.bytes = TSDB_TABLE_FNAME_LEN - 1 + VARSTR_HEADER_SIZE;
|
||||||
nodesDestroyNode(*pNode);
|
nodesDestroyNode(*pNode);
|
||||||
*pNode = (SNode*)pSColumnNode;
|
*pNode = (SNode*)pSColumnNode;
|
||||||
}else{
|
} else {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tagFilterAssist *pData = (tagFilterAssist *)pContext;
|
tagFilterAssist* pData = (tagFilterAssist*)pContext;
|
||||||
void *data = taosHashGet(pData->colHash, &pSColumnNode->colId, sizeof(pSColumnNode->colId));
|
void* data = taosHashGet(pData->colHash, &pSColumnNode->colId, sizeof(pSColumnNode->colId));
|
||||||
if(!data){
|
if (!data) {
|
||||||
taosHashPut(pData->colHash, &pSColumnNode->colId, sizeof(pSColumnNode->colId), pNode, sizeof((*pNode)));
|
taosHashPut(pData->colHash, &pSColumnNode->colId, sizeof(pSColumnNode->colId), pNode, sizeof((*pNode)));
|
||||||
pSColumnNode->slotId = pData->index++;
|
pSColumnNode->slotId = pData->index++;
|
||||||
SColumnInfo cInfo = {.colId = pSColumnNode->colId, .type = pSColumnNode->node.resType.type, .bytes = pSColumnNode->node.resType.bytes};
|
SColumnInfo cInfo = {.colId = pSColumnNode->colId,
|
||||||
|
.type = pSColumnNode->node.resType.type,
|
||||||
|
.bytes = pSColumnNode->node.resType.bytes};
|
||||||
#if TAG_FILTER_DEBUG
|
#if TAG_FILTER_DEBUG
|
||||||
qDebug("tagfilter build column info, slotId:%d, colId:%d, type:%d", pSColumnNode->slotId, cInfo.colId, cInfo.type);
|
qDebug("tagfilter build column info, slotId:%d, colId:%d, type:%d", pSColumnNode->slotId, cInfo.colId, cInfo.type);
|
||||||
#endif
|
#endif
|
||||||
taosArrayPush(pData->cInfoList, &cInfo);
|
taosArrayPush(pData->cInfoList, &cInfo);
|
||||||
}else{
|
} else {
|
||||||
SColumnNode* col = *(SColumnNode**)data;
|
SColumnNode* col = *(SColumnNode**)data;
|
||||||
pSColumnNode->slotId = col->slotId;
|
pSColumnNode->slotId = col->slotId;
|
||||||
}
|
}
|
||||||
|
@ -339,9 +341,9 @@ static int32_t createResultData(SDataType* pType, int32_t numOfRows, SScalarPara
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
pColumnData->info.type = pType->type;
|
pColumnData->info.type = pType->type;
|
||||||
pColumnData->info.bytes = pType->bytes;
|
pColumnData->info.bytes = pType->bytes;
|
||||||
pColumnData->info.scale = pType->scale;
|
pColumnData->info.scale = pType->scale;
|
||||||
pColumnData->info.precision = pType->precision;
|
pColumnData->info.precision = pType->precision;
|
||||||
|
|
||||||
int32_t code = colInfoDataEnsureCapacity(pColumnData, numOfRows);
|
int32_t code = colInfoDataEnsureCapacity(pColumnData, numOfRows);
|
||||||
|
@ -356,27 +358,27 @@ static int32_t createResultData(SDataType* pType, int32_t numOfRows, SScalarPara
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SColumnInfoData* getColInfoResult(void* metaHandle, uint64_t suid, SArray* uidList, SNode* pTagCond){
|
static SColumnInfoData* getColInfoResult(void* metaHandle, uint64_t suid, SArray* uidList, SNode* pTagCond) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SArray* pBlockList = NULL;
|
SArray* pBlockList = NULL;
|
||||||
SSDataBlock* pResBlock = NULL;
|
SSDataBlock* pResBlock = NULL;
|
||||||
SHashObj * tags = NULL;
|
SHashObj* tags = NULL;
|
||||||
SScalarParam output = {0};
|
SScalarParam output = {0};
|
||||||
|
|
||||||
tagFilterAssist ctx = {0};
|
tagFilterAssist ctx = {0};
|
||||||
ctx.colHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_SMALLINT), false, HASH_NO_LOCK);
|
ctx.colHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_SMALLINT), false, HASH_NO_LOCK);
|
||||||
if(ctx.colHash == NULL){
|
if (ctx.colHash == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
ctx.index = 0;
|
ctx.index = 0;
|
||||||
ctx.cInfoList = taosArrayInit(4, sizeof(SColumnInfo));
|
ctx.cInfoList = taosArrayInit(4, sizeof(SColumnInfo));
|
||||||
if(ctx.cInfoList == NULL){
|
if (ctx.cInfoList == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodesRewriteExprPostOrder(&pTagCond, getColumn, (void *)&ctx);
|
nodesRewriteExprPostOrder(&pTagCond, getColumn, (void*)&ctx);
|
||||||
|
|
||||||
pResBlock = createDataBlock();
|
pResBlock = createDataBlock();
|
||||||
if (pResBlock == NULL) {
|
if (pResBlock == NULL) {
|
||||||
|
@ -390,7 +392,7 @@ static SColumnInfoData* getColInfoResult(void* metaHandle, uint64_t suid, SArray
|
||||||
blockDataAppendColInfo(pResBlock, &colInfo);
|
blockDataAppendColInfo(pResBlock, &colInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// int64_t stt = taosGetTimestampUs();
|
// int64_t stt = taosGetTimestampUs();
|
||||||
tags = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
tags = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
||||||
code = metaGetTableTags(metaHandle, suid, uidList, tags);
|
code = metaGetTableTags(metaHandle, suid, uidList, tags);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -400,11 +402,11 @@ static SColumnInfoData* getColInfoResult(void* metaHandle, uint64_t suid, SArray
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t rows = taosArrayGetSize(uidList);
|
int32_t rows = taosArrayGetSize(uidList);
|
||||||
if(rows == 0){
|
if (rows == 0) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
// int64_t stt1 = taosGetTimestampUs();
|
// int64_t stt1 = taosGetTimestampUs();
|
||||||
// qDebug("generate tag meta rows:%d, cost:%ld us", rows, stt1-stt);
|
// qDebug("generate tag meta rows:%d, cost:%ld us", rows, stt1-stt);
|
||||||
|
|
||||||
code = blockDataEnsureCapacity(pResBlock, rows);
|
code = blockDataEnsureCapacity(pResBlock, rows);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -412,46 +414,46 @@ static SColumnInfoData* getColInfoResult(void* metaHandle, uint64_t suid, SArray
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int64_t st = taosGetTimestampUs();
|
// int64_t st = taosGetTimestampUs();
|
||||||
for (int32_t i = 0; i < rows; i++) {
|
for (int32_t i = 0; i < rows; i++) {
|
||||||
int64_t* uid = taosArrayGet(uidList, i);
|
int64_t* uid = taosArrayGet(uidList, i);
|
||||||
for(int32_t j = 0; j < taosArrayGetSize(pResBlock->pDataBlock); j++){
|
for (int32_t j = 0; j < taosArrayGetSize(pResBlock->pDataBlock); j++) {
|
||||||
SColumnInfoData* pColInfo = (SColumnInfoData*)taosArrayGet(pResBlock->pDataBlock, j);
|
SColumnInfoData* pColInfo = (SColumnInfoData*)taosArrayGet(pResBlock->pDataBlock, j);
|
||||||
|
|
||||||
if(pColInfo->info.colId == -1){ // tbname
|
if (pColInfo->info.colId == -1) { // tbname
|
||||||
char str[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
char str[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||||
metaGetTableNameByUid(metaHandle, *uid, str);
|
metaGetTableNameByUid(metaHandle, *uid, str);
|
||||||
colDataAppend(pColInfo, i, str, false);
|
colDataAppend(pColInfo, i, str, false);
|
||||||
#if TAG_FILTER_DEBUG
|
#if TAG_FILTER_DEBUG
|
||||||
qDebug("tagfilter uid:%ld, tbname:%s", *uid, str+2);
|
qDebug("tagfilter uid:%ld, tbname:%s", *uid, str + 2);
|
||||||
#endif
|
#endif
|
||||||
}else{
|
} else {
|
||||||
void* tag = taosHashGet(tags, uid, sizeof(int64_t));
|
void* tag = taosHashGet(tags, uid, sizeof(int64_t));
|
||||||
ASSERT(tag);
|
ASSERT(tag);
|
||||||
STagVal tagVal = {0};
|
STagVal tagVal = {0};
|
||||||
tagVal.cid = pColInfo->info.colId;
|
tagVal.cid = pColInfo->info.colId;
|
||||||
const char* p = metaGetTableTagVal(tag, pColInfo->info.type, &tagVal);
|
const char* p = metaGetTableTagVal(tag, pColInfo->info.type, &tagVal);
|
||||||
|
|
||||||
if (p == NULL || (pColInfo->info.type == TSDB_DATA_TYPE_JSON && ((STag*)p)->nTag == 0)){
|
if (p == NULL || (pColInfo->info.type == TSDB_DATA_TYPE_JSON && ((STag*)p)->nTag == 0)) {
|
||||||
colDataAppend(pColInfo, i, p, true);
|
colDataAppend(pColInfo, i, p, true);
|
||||||
} else if (pColInfo->info.type == TSDB_DATA_TYPE_JSON) {
|
} else if (pColInfo->info.type == TSDB_DATA_TYPE_JSON) {
|
||||||
colDataAppend(pColInfo, i, p, false);
|
colDataAppend(pColInfo, i, p, false);
|
||||||
} else if (IS_VAR_DATA_TYPE(pColInfo->info.type)) {
|
} else if (IS_VAR_DATA_TYPE(pColInfo->info.type)) {
|
||||||
char *tmp = taosMemoryCalloc(tagVal.nData + VARSTR_HEADER_SIZE + 1, 1);
|
char* tmp = taosMemoryCalloc(tagVal.nData + VARSTR_HEADER_SIZE + 1, 1);
|
||||||
varDataSetLen(tmp, tagVal.nData);
|
varDataSetLen(tmp, tagVal.nData);
|
||||||
memcpy(tmp + VARSTR_HEADER_SIZE, tagVal.pData, tagVal.nData);
|
memcpy(tmp + VARSTR_HEADER_SIZE, tagVal.pData, tagVal.nData);
|
||||||
colDataAppend(pColInfo, i, tmp, false);
|
colDataAppend(pColInfo, i, tmp, false);
|
||||||
#if TAG_FILTER_DEBUG
|
#if TAG_FILTER_DEBUG
|
||||||
qDebug("tagfilter varch:%s", tmp+2);
|
qDebug("tagfilter varch:%s", tmp + 2);
|
||||||
#endif
|
#endif
|
||||||
taosMemoryFree(tmp);
|
taosMemoryFree(tmp);
|
||||||
} else {
|
} else {
|
||||||
colDataAppend(pColInfo, i, (const char*)&tagVal.i64, false);
|
colDataAppend(pColInfo, i, (const char*)&tagVal.i64, false);
|
||||||
#if TAG_FILTER_DEBUG
|
#if TAG_FILTER_DEBUG
|
||||||
if(pColInfo->info.type == TSDB_DATA_TYPE_INT){
|
if (pColInfo->info.type == TSDB_DATA_TYPE_INT) {
|
||||||
qDebug("tagfilter int:%d", *(int*)(&tagVal.i64));
|
qDebug("tagfilter int:%d", *(int*)(&tagVal.i64));
|
||||||
}else if(pColInfo->info.type == TSDB_DATA_TYPE_DOUBLE){
|
} else if (pColInfo->info.type == TSDB_DATA_TYPE_DOUBLE) {
|
||||||
qDebug("tagfilter double:%f", *(double *)(&tagVal.i64));
|
qDebug("tagfilter double:%f", *(double*)(&tagVal.i64));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -460,8 +462,8 @@ static SColumnInfoData* getColInfoResult(void* metaHandle, uint64_t suid, SArray
|
||||||
}
|
}
|
||||||
pResBlock->info.rows = rows;
|
pResBlock->info.rows = rows;
|
||||||
|
|
||||||
// int64_t st1 = taosGetTimestampUs();
|
// int64_t st1 = taosGetTimestampUs();
|
||||||
// qDebug("generate tag block rows:%d, cost:%ld us", rows, st1-st);
|
// qDebug("generate tag block rows:%d, cost:%ld us", rows, st1-st);
|
||||||
|
|
||||||
pBlockList = taosArrayInit(2, POINTER_BYTES);
|
pBlockList = taosArrayInit(2, POINTER_BYTES);
|
||||||
taosArrayPush(pBlockList, &pResBlock);
|
taosArrayPush(pBlockList, &pResBlock);
|
||||||
|
@ -475,13 +477,13 @@ static SColumnInfoData* getColInfoResult(void* metaHandle, uint64_t suid, SArray
|
||||||
}
|
}
|
||||||
|
|
||||||
code = scalarCalculate(pTagCond, pBlockList, &output);
|
code = scalarCalculate(pTagCond, pBlockList, &output);
|
||||||
if(code != TSDB_CODE_SUCCESS){
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
qError("failed to calculate scalar, reason:%s", tstrerror(code));
|
qError("failed to calculate scalar, reason:%s", tstrerror(code));
|
||||||
terrno = code;
|
terrno = code;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
// int64_t st2 = taosGetTimestampUs();
|
// int64_t st2 = taosGetTimestampUs();
|
||||||
// qDebug("calculate tag block rows:%d, cost:%ld us", rows, st2-st1);
|
// qDebug("calculate tag block rows:%d, cost:%ld us", rows, st2-st1);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
taosHashCleanup(tags);
|
taosHashCleanup(tags);
|
||||||
|
@ -493,43 +495,43 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void releaseColInfoData(void* pCol) {
|
static void releaseColInfoData(void* pCol) {
|
||||||
if(pCol){
|
if (pCol) {
|
||||||
SColumnInfoData* col = (SColumnInfoData*) pCol;
|
SColumnInfoData* col = (SColumnInfoData*)pCol;
|
||||||
colDataDestroy(col);
|
colDataDestroy(col);
|
||||||
taosMemoryFree(col);
|
taosMemoryFree(col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableListInfo* pTableListInfo){
|
int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableListInfo* pTableListInfo) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SArray *pBlockList = NULL;
|
SArray* pBlockList = NULL;
|
||||||
SSDataBlock *pResBlock = NULL;
|
SSDataBlock* pResBlock = NULL;
|
||||||
SHashObj *tags = NULL;
|
SHashObj* tags = NULL;
|
||||||
SArray *uidList = NULL;
|
SArray* uidList = NULL;
|
||||||
void *keyBuf = NULL;
|
void* keyBuf = NULL;
|
||||||
SArray *groupData = NULL;
|
SArray* groupData = NULL;
|
||||||
|
|
||||||
int32_t rows = taosArrayGetSize(pTableListInfo->pTableList);
|
int32_t rows = taosArrayGetSize(pTableListInfo->pTableList);
|
||||||
if(rows == 0){
|
if (rows == 0) {
|
||||||
return TDB_CODE_SUCCESS;
|
return TDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
tagFilterAssist ctx = {0};
|
tagFilterAssist ctx = {0};
|
||||||
ctx.colHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_SMALLINT), false, HASH_NO_LOCK);
|
ctx.colHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_SMALLINT), false, HASH_NO_LOCK);
|
||||||
if(ctx.colHash == NULL){
|
if (ctx.colHash == NULL) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
ctx.index = 0;
|
ctx.index = 0;
|
||||||
ctx.cInfoList = taosArrayInit(4, sizeof(SColumnInfo));
|
ctx.cInfoList = taosArrayInit(4, sizeof(SColumnInfo));
|
||||||
if(ctx.cInfoList == NULL){
|
if (ctx.cInfoList == NULL) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
SNode* pNode = NULL;
|
SNode* pNode = NULL;
|
||||||
FOREACH(pNode, group) {
|
FOREACH(pNode, group) {
|
||||||
nodesRewriteExprPostOrder(&pNode, getColumn, (void *)&ctx);
|
nodesRewriteExprPostOrder(&pNode, getColumn, (void*)&ctx);
|
||||||
REPLACE_NODE(pNode);
|
REPLACE_NODE(pNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,61 +553,61 @@ int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableLis
|
||||||
taosArrayPush(uidList, &pkeyInfo->uid);
|
taosArrayPush(uidList, &pkeyInfo->uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// int64_t stt = taosGetTimestampUs();
|
// int64_t stt = taosGetTimestampUs();
|
||||||
tags = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
tags = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
|
||||||
code = metaGetTableTags(metaHandle, pTableListInfo->suid, uidList, tags);
|
code = metaGetTableTags(metaHandle, pTableListInfo->suid, uidList, tags);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int64_t stt1 = taosGetTimestampUs();
|
// int64_t stt1 = taosGetTimestampUs();
|
||||||
// qDebug("generate tag meta rows:%d, cost:%ld us", rows, stt1-stt);
|
// qDebug("generate tag meta rows:%d, cost:%ld us", rows, stt1-stt);
|
||||||
|
|
||||||
code = blockDataEnsureCapacity(pResBlock, rows);
|
code = blockDataEnsureCapacity(pResBlock, rows);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int64_t st = taosGetTimestampUs();
|
// int64_t st = taosGetTimestampUs();
|
||||||
for (int32_t i = 0; i < rows; i++) {
|
for (int32_t i = 0; i < rows; i++) {
|
||||||
int64_t* uid = taosArrayGet(uidList, i);
|
int64_t* uid = taosArrayGet(uidList, i);
|
||||||
for(int32_t j = 0; j < taosArrayGetSize(pResBlock->pDataBlock); j++){
|
for (int32_t j = 0; j < taosArrayGetSize(pResBlock->pDataBlock); j++) {
|
||||||
SColumnInfoData* pColInfo = (SColumnInfoData*)taosArrayGet(pResBlock->pDataBlock, j);
|
SColumnInfoData* pColInfo = (SColumnInfoData*)taosArrayGet(pResBlock->pDataBlock, j);
|
||||||
|
|
||||||
if(pColInfo->info.colId == -1){ // tbname
|
if (pColInfo->info.colId == -1) { // tbname
|
||||||
char str[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
char str[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||||
metaGetTableNameByUid(metaHandle, *uid, str);
|
metaGetTableNameByUid(metaHandle, *uid, str);
|
||||||
colDataAppend(pColInfo, i, str, false);
|
colDataAppend(pColInfo, i, str, false);
|
||||||
#if TAG_FILTER_DEBUG
|
#if TAG_FILTER_DEBUG
|
||||||
qDebug("tagfilter uid:%ld, tbname:%s", *uid, str+2);
|
qDebug("tagfilter uid:%ld, tbname:%s", *uid, str + 2);
|
||||||
#endif
|
#endif
|
||||||
}else{
|
} else {
|
||||||
void* tag = taosHashGet(tags, uid, sizeof(int64_t));
|
void* tag = taosHashGet(tags, uid, sizeof(int64_t));
|
||||||
ASSERT(tag);
|
ASSERT(tag);
|
||||||
STagVal tagVal = {0};
|
STagVal tagVal = {0};
|
||||||
tagVal.cid = pColInfo->info.colId;
|
tagVal.cid = pColInfo->info.colId;
|
||||||
const char* p = metaGetTableTagVal(tag, pColInfo->info.type, &tagVal);
|
const char* p = metaGetTableTagVal(tag, pColInfo->info.type, &tagVal);
|
||||||
|
|
||||||
if (p == NULL || (pColInfo->info.type == TSDB_DATA_TYPE_JSON && ((STag*)p)->nTag == 0)){
|
if (p == NULL || (pColInfo->info.type == TSDB_DATA_TYPE_JSON && ((STag*)p)->nTag == 0)) {
|
||||||
colDataAppend(pColInfo, i, p, true);
|
colDataAppend(pColInfo, i, p, true);
|
||||||
} else if (pColInfo->info.type == TSDB_DATA_TYPE_JSON) {
|
} else if (pColInfo->info.type == TSDB_DATA_TYPE_JSON) {
|
||||||
colDataAppend(pColInfo, i, p, false);
|
colDataAppend(pColInfo, i, p, false);
|
||||||
} else if (IS_VAR_DATA_TYPE(pColInfo->info.type)) {
|
} else if (IS_VAR_DATA_TYPE(pColInfo->info.type)) {
|
||||||
char *tmp = taosMemoryCalloc(tagVal.nData + VARSTR_HEADER_SIZE + 1, 1);
|
char* tmp = taosMemoryCalloc(tagVal.nData + VARSTR_HEADER_SIZE + 1, 1);
|
||||||
varDataSetLen(tmp, tagVal.nData);
|
varDataSetLen(tmp, tagVal.nData);
|
||||||
memcpy(tmp + VARSTR_HEADER_SIZE, tagVal.pData, tagVal.nData);
|
memcpy(tmp + VARSTR_HEADER_SIZE, tagVal.pData, tagVal.nData);
|
||||||
colDataAppend(pColInfo, i, tmp, false);
|
colDataAppend(pColInfo, i, tmp, false);
|
||||||
#if TAG_FILTER_DEBUG
|
#if TAG_FILTER_DEBUG
|
||||||
qDebug("tagfilter varch:%s", tmp+2);
|
qDebug("tagfilter varch:%s", tmp + 2);
|
||||||
#endif
|
#endif
|
||||||
taosMemoryFree(tmp);
|
taosMemoryFree(tmp);
|
||||||
} else {
|
} else {
|
||||||
colDataAppend(pColInfo, i, (const char*)&tagVal.i64, false);
|
colDataAppend(pColInfo, i, (const char*)&tagVal.i64, false);
|
||||||
#if TAG_FILTER_DEBUG
|
#if TAG_FILTER_DEBUG
|
||||||
if(pColInfo->info.type == TSDB_DATA_TYPE_INT){
|
if (pColInfo->info.type == TSDB_DATA_TYPE_INT) {
|
||||||
qDebug("tagfilter int:%d", *(int*)(&tagVal.i64));
|
qDebug("tagfilter int:%d", *(int*)(&tagVal.i64));
|
||||||
}else if(pColInfo->info.type == TSDB_DATA_TYPE_DOUBLE){
|
} else if (pColInfo->info.type == TSDB_DATA_TYPE_DOUBLE) {
|
||||||
qDebug("tagfilter double:%f", *(double *)(&tagVal.i64));
|
qDebug("tagfilter double:%f", *(double*)(&tagVal.i64));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -614,8 +616,8 @@ int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableLis
|
||||||
}
|
}
|
||||||
pResBlock->info.rows = rows;
|
pResBlock->info.rows = rows;
|
||||||
|
|
||||||
// int64_t st1 = taosGetTimestampUs();
|
// int64_t st1 = taosGetTimestampUs();
|
||||||
// qDebug("generate tag block rows:%d, cost:%ld us", rows, st1-st);
|
// qDebug("generate tag block rows:%d, cost:%ld us", rows, st1-st);
|
||||||
|
|
||||||
pBlockList = taosArrayInit(2, POINTER_BYTES);
|
pBlockList = taosArrayInit(2, POINTER_BYTES);
|
||||||
taosArrayPush(pBlockList, &pResBlock);
|
taosArrayPush(pBlockList, &pResBlock);
|
||||||
|
@ -629,7 +631,7 @@ int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableLis
|
||||||
break;
|
break;
|
||||||
case QUERY_NODE_COLUMN:
|
case QUERY_NODE_COLUMN:
|
||||||
case QUERY_NODE_OPERATOR:
|
case QUERY_NODE_OPERATOR:
|
||||||
case QUERY_NODE_FUNCTION:{
|
case QUERY_NODE_FUNCTION: {
|
||||||
SExprNode* expNode = (SExprNode*)pNode;
|
SExprNode* expNode = (SExprNode*)pNode;
|
||||||
code = createResultData(&expNode->resType, rows, &output);
|
code = createResultData(&expNode->resType, rows, &output);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -641,16 +643,16 @@ int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableLis
|
||||||
code = TSDB_CODE_OPS_NOT_SUPPORT;
|
code = TSDB_CODE_OPS_NOT_SUPPORT;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if(nodeType(pNode) == QUERY_NODE_COLUMN){
|
if (nodeType(pNode) == QUERY_NODE_COLUMN) {
|
||||||
SColumnNode* pSColumnNode = (SColumnNode*)pNode;
|
SColumnNode* pSColumnNode = (SColumnNode*)pNode;
|
||||||
SColumnInfoData* pColInfo = (SColumnInfoData*)taosArrayGet(pResBlock->pDataBlock, pSColumnNode->slotId);
|
SColumnInfoData* pColInfo = (SColumnInfoData*)taosArrayGet(pResBlock->pDataBlock, pSColumnNode->slotId);
|
||||||
code = colDataAssign(output.columnData, pColInfo, rows, NULL);
|
code = colDataAssign(output.columnData, pColInfo, rows, NULL);
|
||||||
}else if(nodeType(pNode) == QUERY_NODE_VALUE){
|
} else if (nodeType(pNode) == QUERY_NODE_VALUE) {
|
||||||
continue;
|
continue;
|
||||||
}else{
|
} else {
|
||||||
code = scalarCalculate(pNode, pBlockList, &output);
|
code = scalarCalculate(pNode, pBlockList, &output);
|
||||||
}
|
}
|
||||||
if(code != TSDB_CODE_SUCCESS){
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
releaseColInfoData(output.columnData);
|
releaseColInfoData(output.columnData);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -658,7 +660,7 @@ int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableLis
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t keyLen = 0;
|
int32_t keyLen = 0;
|
||||||
SNode* node;
|
SNode* node;
|
||||||
FOREACH(node, group) {
|
FOREACH(node, group) {
|
||||||
SExprNode* pExpr = (SExprNode*)node;
|
SExprNode* pExpr = (SExprNode*)node;
|
||||||
keyLen += pExpr->resType.bytes;
|
keyLen += pExpr->resType.bytes;
|
||||||
|
@ -672,12 +674,12 @@ int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableLis
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
for(int i = 0; i < rows; i++){
|
for (int i = 0; i < rows; i++) {
|
||||||
STableKeyInfo* info = taosArrayGet(pTableListInfo->pTableList, i);
|
STableKeyInfo* info = taosArrayGet(pTableListInfo->pTableList, i);
|
||||||
|
|
||||||
char* isNull = (char*)keyBuf;
|
char* isNull = (char*)keyBuf;
|
||||||
char* pStart = (char*)keyBuf + sizeof(int8_t) * LIST_LENGTH(group);
|
char* pStart = (char*)keyBuf + sizeof(int8_t) * LIST_LENGTH(group);
|
||||||
for(int j = 0; j < taosArrayGetSize(groupData); j++){
|
for (int j = 0; j < taosArrayGetSize(groupData); j++) {
|
||||||
SColumnInfoData* pValue = (SColumnInfoData*)taosArrayGetP(groupData, j);
|
SColumnInfoData* pValue = (SColumnInfoData*)taosArrayGetP(groupData, j);
|
||||||
|
|
||||||
if (colDataIsNull_s(pValue, i)) {
|
if (colDataIsNull_s(pValue, i)) {
|
||||||
|
@ -690,7 +692,7 @@ int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableLis
|
||||||
code = TSDB_CODE_QRY_JSON_IN_GROUP_ERROR;
|
code = TSDB_CODE_QRY_JSON_IN_GROUP_ERROR;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if(tTagIsJsonNull(data)){
|
if (tTagIsJsonNull(data)) {
|
||||||
isNull[j] = 1;
|
isNull[j] = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -712,10 +714,10 @@ int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableLis
|
||||||
taosHashPut(pTableListInfo->map, &(info->uid), sizeof(uint64_t), &info->groupId, sizeof(uint64_t));
|
taosHashPut(pTableListInfo->map, &(info->uid), sizeof(uint64_t), &info->groupId, sizeof(uint64_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// int64_t st2 = taosGetTimestampUs();
|
// int64_t st2 = taosGetTimestampUs();
|
||||||
// qDebug("calculate tag block rows:%d, cost:%ld us", rows, st2-st1);
|
// qDebug("calculate tag block rows:%d, cost:%ld us", rows, st2-st1);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
taosMemoryFreeClear(keyBuf);
|
taosMemoryFreeClear(keyBuf);
|
||||||
taosHashCleanup(tags);
|
taosHashCleanup(tags);
|
||||||
taosHashCleanup(ctx.colHash);
|
taosHashCleanup(ctx.colHash);
|
||||||
|
@ -745,7 +747,7 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode,
|
||||||
SIndexMetaArg metaArg = {
|
SIndexMetaArg metaArg = {
|
||||||
.metaEx = metaHandle, .idx = tsdbGetIdx(metaHandle), .ivtIdx = tsdbGetIvtIdx(metaHandle), .suid = tableUid};
|
.metaEx = metaHandle, .idx = tsdbGetIdx(metaHandle), .ivtIdx = tsdbGetIvtIdx(metaHandle), .suid = tableUid};
|
||||||
|
|
||||||
// int64_t stt = taosGetTimestampUs();
|
// int64_t stt = taosGetTimestampUs();
|
||||||
SIdxFltStatus status = SFLT_NOT_INDEX;
|
SIdxFltStatus status = SFLT_NOT_INDEX;
|
||||||
code = doFilterTag(pTagIndexCond, &metaArg, res, &status);
|
code = doFilterTag(pTagIndexCond, &metaArg, res, &status);
|
||||||
if (code != 0 || status == SFLT_NOT_INDEX) {
|
if (code != 0 || status == SFLT_NOT_INDEX) {
|
||||||
|
@ -753,13 +755,13 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode,
|
||||||
code = TDB_CODE_SUCCESS;
|
code = TDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int64_t stt1 = taosGetTimestampUs();
|
// int64_t stt1 = taosGetTimestampUs();
|
||||||
// qDebug("generate table list, cost:%ld us", stt1-stt);
|
// qDebug("generate table list, cost:%ld us", stt1-stt);
|
||||||
}else if(!pTagCond){
|
} else if (!pTagCond) {
|
||||||
vnodeGetCtbIdList(pVnode, pScanNode->suid, res);
|
vnodeGetCtbIdList(pVnode, pScanNode->suid, res);
|
||||||
}
|
}
|
||||||
} else { // Create one table group.
|
} else { // Create one table group.
|
||||||
if(metaIsTableExist(metaHandle, tableUid)){
|
if (metaIsTableExist(metaHandle, tableUid)) {
|
||||||
taosArrayPush(res, &tableUid);
|
taosArrayPush(res, &tableUid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -767,7 +769,7 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode,
|
||||||
if (pTagCond) {
|
if (pTagCond) {
|
||||||
terrno = TDB_CODE_SUCCESS;
|
terrno = TDB_CODE_SUCCESS;
|
||||||
SColumnInfoData* pColInfoData = getColInfoResult(metaHandle, pListInfo->suid, res, pTagCond);
|
SColumnInfoData* pColInfoData = getColInfoResult(metaHandle, pListInfo->suid, res, pTagCond);
|
||||||
if(terrno != TDB_CODE_SUCCESS){
|
if (terrno != TDB_CODE_SUCCESS) {
|
||||||
colDataDestroy(pColInfoData);
|
colDataDestroy(pColInfoData);
|
||||||
taosMemoryFreeClear(pColInfoData);
|
taosMemoryFreeClear(pColInfoData);
|
||||||
taosArrayDestroy(res);
|
taosArrayDestroy(res);
|
||||||
|
@ -829,7 +831,7 @@ size_t getTableTagsBufLen(const SNodeList* pGroups) {
|
||||||
int32_t getGroupIdFromTagsVal(void* pMeta, uint64_t uid, SNodeList* pGroupNode, char* keyBuf, uint64_t* pGroupId) {
|
int32_t getGroupIdFromTagsVal(void* pMeta, uint64_t uid, SNodeList* pGroupNode, char* keyBuf, uint64_t* pGroupId) {
|
||||||
SMetaReader mr = {0};
|
SMetaReader mr = {0};
|
||||||
metaReaderInit(&mr, pMeta, 0);
|
metaReaderInit(&mr, pMeta, 0);
|
||||||
if(metaGetTableEntryByUid(&mr, uid) != 0){ // table not exist
|
if (metaGetTableEntryByUid(&mr, uid) != 0) { // table not exist
|
||||||
metaReaderClear(&mr);
|
metaReaderClear(&mr);
|
||||||
return TSDB_CODE_PAR_TABLE_NOT_EXIST;
|
return TSDB_CODE_PAR_TABLE_NOT_EXIST;
|
||||||
}
|
}
|
||||||
|
@ -987,7 +989,7 @@ static SResSchema createResSchema(int32_t type, int32_t bytes, int32_t slotId, i
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SColumn* createColumn(int32_t blockId, int32_t slotId, int32_t colId, SDataType* pType) {
|
static SColumn* createColumn(int32_t blockId, int32_t slotId, int32_t colId, SDataType* pType, EColumnType colType) {
|
||||||
SColumn* pCol = taosMemoryCalloc(1, sizeof(SColumn));
|
SColumn* pCol = taosMemoryCalloc(1, sizeof(SColumn));
|
||||||
if (pCol == NULL) {
|
if (pCol == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
@ -1001,7 +1003,7 @@ static SColumn* createColumn(int32_t blockId, int32_t slotId, int32_t colId, SDa
|
||||||
pCol->scale = pType->scale;
|
pCol->scale = pType->scale;
|
||||||
pCol->precision = pType->precision;
|
pCol->precision = pType->precision;
|
||||||
pCol->dataBlockId = blockId;
|
pCol->dataBlockId = blockId;
|
||||||
|
pCol->colType = colType;
|
||||||
return pCol;
|
return pCol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1045,7 +1047,8 @@ SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t*
|
||||||
SDataType* pType = &pColNode->node.resType;
|
SDataType* pType = &pColNode->node.resType;
|
||||||
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale,
|
||||||
pType->precision, pColNode->colName);
|
pType->precision, pColNode->colName);
|
||||||
pExp->base.pParam[0].pCol = createColumn(pColNode->dataBlockId, pColNode->slotId, pColNode->colId, pType);
|
pExp->base.pParam[0].pCol =
|
||||||
|
createColumn(pColNode->dataBlockId, pColNode->slotId, pColNode->colId, pType, pColNode->colType);
|
||||||
pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
|
pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN;
|
||||||
} else if (type == QUERY_NODE_VALUE) {
|
} else if (type == QUERY_NODE_VALUE) {
|
||||||
pExp->pExpr->nodeType = QUERY_NODE_VALUE;
|
pExp->pExpr->nodeType = QUERY_NODE_VALUE;
|
||||||
|
@ -1097,7 +1100,8 @@ SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t*
|
||||||
SColumnNode* pcn = (SColumnNode*)p1;
|
SColumnNode* pcn = (SColumnNode*)p1;
|
||||||
|
|
||||||
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
|
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
|
||||||
pExp->base.pParam[j].pCol = createColumn(pcn->dataBlockId, pcn->slotId, pcn->colId, &pcn->node.resType);
|
pExp->base.pParam[j].pCol =
|
||||||
|
createColumn(pcn->dataBlockId, pcn->slotId, pcn->colId, &pcn->node.resType, pcn->colType);
|
||||||
} else if (p1->type == QUERY_NODE_VALUE) {
|
} else if (p1->type == QUERY_NODE_VALUE) {
|
||||||
SValueNode* pvn = (SValueNode*)p1;
|
SValueNode* pvn = (SValueNode*)p1;
|
||||||
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
|
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
|
||||||
|
|
|
@ -148,20 +148,6 @@ static int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock,
|
||||||
static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
|
static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
|
||||||
static void doSetTableGroupOutputBuf(SOperatorInfo* pOperator, int32_t numOfOutput, uint64_t groupId);
|
static void doSetTableGroupOutputBuf(SOperatorInfo* pOperator, int32_t numOfOutput, uint64_t groupId);
|
||||||
|
|
||||||
// setup the output buffer for each operator
|
|
||||||
static bool hasNull(SColumn* pColumn, SColumnDataAgg* pStatis) {
|
|
||||||
if (TSDB_COL_IS_TAG(pColumn->flag) || TSDB_COL_IS_UD_COL(pColumn->flag) ||
|
|
||||||
pColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pStatis != NULL && pStatis->numOfNull == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static bool chkResultRowFromKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, char* pData,
|
static bool chkResultRowFromKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo, char* pData,
|
||||||
int16_t bytes, bool masterscan, uint64_t uid) {
|
int16_t bytes, bool masterscan, uint64_t uid) {
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#define GET_DEST_SLOT_ID(_p) ((_p)->pExpr->base.resSchema.slotId)
|
#define GET_DEST_SLOT_ID(_p) ((_p)->pExpr->base.resSchema.slotId)
|
||||||
|
|
||||||
static void doSetVal(SColumnInfoData* pDstColInfoData, int32_t rowIndex, const SGroupKeys* pKey);
|
static void doSetVal(SColumnInfoData* pDstColInfoData, int32_t rowIndex, const SGroupKeys* pKey);
|
||||||
|
static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnInfoData* pDstColInfoData, int32_t rowIndex);
|
||||||
|
|
||||||
static void setNullRow(SSDataBlock* pBlock, SFillInfo* pFillInfo, int32_t rowIndex) {
|
static void setNullRow(SSDataBlock* pBlock, SFillInfo* pFillInfo, int32_t rowIndex) {
|
||||||
for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
||||||
|
@ -43,9 +44,8 @@ static void setNullRow(SSDataBlock* pBlock, SFillInfo* pFillInfo, int32_t rowInd
|
||||||
int32_t dstSlotId = GET_DEST_SLOT_ID(pCol);
|
int32_t dstSlotId = GET_DEST_SLOT_ID(pCol);
|
||||||
SColumnInfoData* pDstColInfo = taosArrayGet(pBlock->pDataBlock, dstSlotId);
|
SColumnInfoData* pDstColInfo = taosArrayGet(pBlock->pDataBlock, dstSlotId);
|
||||||
if (pCol->notFillCol) {
|
if (pCol->notFillCol) {
|
||||||
if (pDstColInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfo, rowIndex);
|
||||||
colDataAppend(pDstColInfo, rowIndex, (const char*)&pFillInfo->currentKey, false);
|
if (!filled) {
|
||||||
} else {
|
|
||||||
SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal;
|
SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal;
|
||||||
SGroupKeys* pKey = taosArrayGet(p, i);
|
SGroupKeys* pKey = taosArrayGet(p, i);
|
||||||
doSetVal(pDstColInfo, rowIndex, pKey);
|
doSetVal(pDstColInfo, rowIndex, pKey);
|
||||||
|
@ -76,6 +76,35 @@ static void doSetUserSpecifiedValue(SColumnInfoData* pDst, SVariant* pVar, int32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//fill windows pseudo column, _wstart, _wend, _wduration and return true, otherwise return false
|
||||||
|
static bool fillIfWindowPseudoColumn(SFillInfo* pFillInfo, SFillColInfo* pCol, SColumnInfoData* pDstColInfoData, int32_t rowIndex) {
|
||||||
|
if (!pCol->notFillCol) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pCol->pExpr->pExpr->nodeType == QUERY_NODE_COLUMN) {
|
||||||
|
if (pCol->pExpr->base.numOfParams != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pCol->pExpr->base.pParam[0].pCol->colType == COLUMN_TYPE_WINDOW_START) {
|
||||||
|
colDataAppend(pDstColInfoData, rowIndex, (const char*)&pFillInfo->currentKey, false);
|
||||||
|
return true;
|
||||||
|
} else if (pCol->pExpr->base.pParam[0].pCol->colType == COLUMN_TYPE_WINDOW_END) {
|
||||||
|
//TODO: include endpoint
|
||||||
|
SInterval* pInterval = &pFillInfo->interval;
|
||||||
|
int32_t step = (pFillInfo->order == TSDB_ORDER_ASC) ? 1 : -1;
|
||||||
|
int64_t windowEnd =
|
||||||
|
taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision);
|
||||||
|
colDataAppend(pDstColInfoData, rowIndex, (const char*)&windowEnd, false);
|
||||||
|
return true;
|
||||||
|
} else if (pCol->pExpr->base.pParam[0].pCol->colType == COLUMN_TYPE_WINDOW_DURATION) {
|
||||||
|
//TODO: include endpoint
|
||||||
|
colDataAppend(pDstColInfoData, rowIndex, (const char*)&pFillInfo->interval.sliding, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* pSrcBlock, int64_t ts,
|
static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* pSrcBlock, int64_t ts,
|
||||||
bool outOfBound) {
|
bool outOfBound) {
|
||||||
SPoint point1, point2, point;
|
SPoint point1, point2, point;
|
||||||
|
@ -92,10 +121,8 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock*
|
||||||
SFillColInfo* pCol = &pFillInfo->pFillCol[i];
|
SFillColInfo* pCol = &pFillInfo->pFillCol[i];
|
||||||
|
|
||||||
SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol));
|
SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol));
|
||||||
|
bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfoData, index);
|
||||||
if (pDstColInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
if (!filled) {
|
||||||
colDataAppend(pDstColInfoData, index, (const char*)&pFillInfo->currentKey, false);
|
|
||||||
} else {
|
|
||||||
SGroupKeys* pKey = taosArrayGet(p, i);
|
SGroupKeys* pKey = taosArrayGet(p, i);
|
||||||
doSetVal(pDstColInfoData, index, pKey);
|
doSetVal(pDstColInfoData, index, pKey);
|
||||||
}
|
}
|
||||||
|
@ -106,10 +133,8 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock*
|
||||||
for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
|
||||||
SFillColInfo* pCol = &pFillInfo->pFillCol[i];
|
SFillColInfo* pCol = &pFillInfo->pFillCol[i];
|
||||||
SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol));
|
SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol));
|
||||||
|
bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstColInfoData, index);
|
||||||
if (pDstColInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
if (!filled) {
|
||||||
colDataAppend(pDstColInfoData, index, (const char*)&pFillInfo->currentKey, false);
|
|
||||||
} else {
|
|
||||||
SGroupKeys* pKey = taosArrayGet(p, i);
|
SGroupKeys* pKey = taosArrayGet(p, i);
|
||||||
doSetVal(pDstColInfoData, index, pKey);
|
doSetVal(pDstColInfoData, index, pKey);
|
||||||
}
|
}
|
||||||
|
@ -127,9 +152,8 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock*
|
||||||
int16_t type = pDstCol->info.type;
|
int16_t type = pDstCol->info.type;
|
||||||
|
|
||||||
if (pCol->notFillCol) {
|
if (pCol->notFillCol) {
|
||||||
if (type == TSDB_DATA_TYPE_TIMESTAMP) {
|
bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDstCol, index);
|
||||||
colDataAppend(pDstCol, index, (const char*)&pFillInfo->currentKey, false);
|
if (!filled) {
|
||||||
} else {
|
|
||||||
SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal;
|
SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal;
|
||||||
SGroupKeys* pKey = taosArrayGet(p, i);
|
SGroupKeys* pKey = taosArrayGet(p, i);
|
||||||
doSetVal(pDstCol, index, pKey);
|
doSetVal(pDstCol, index, pKey);
|
||||||
|
@ -170,9 +194,8 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock*
|
||||||
SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, slotId);
|
SColumnInfoData* pDst = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||||
|
|
||||||
if (pCol->notFillCol) {
|
if (pCol->notFillCol) {
|
||||||
if (pDst->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
bool filled = fillIfWindowPseudoColumn(pFillInfo, pCol, pDst, index);
|
||||||
colDataAppend(pDst, index, (const char*)&pFillInfo->currentKey, false);
|
if (!filled) {
|
||||||
} else {
|
|
||||||
SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal;
|
SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal;
|
||||||
SGroupKeys* pKey = taosArrayGet(p, i);
|
SGroupKeys* pKey = taosArrayGet(p, i);
|
||||||
doSetVal(pDst, index, pKey);
|
doSetVal(pDst, index, pKey);
|
||||||
|
|
|
@ -1947,8 +1947,8 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSessionAggOperator
|
||||||
if (gid != pRowSup->groupId || pInfo->winSup.prevTs == INT64_MIN) {
|
if (gid != pRowSup->groupId || pInfo->winSup.prevTs == INT64_MIN) {
|
||||||
doKeepNewWindowStartInfo(pRowSup, tsList, j, gid);
|
doKeepNewWindowStartInfo(pRowSup, tsList, j, gid);
|
||||||
doKeepTuple(pRowSup, tsList[j], gid);
|
doKeepTuple(pRowSup, tsList[j], gid);
|
||||||
} else if ((tsList[j] - pRowSup->prevTs >= 0) && tsList[j] - pRowSup->prevTs <= gap ||
|
} else if (((tsList[j] - pRowSup->prevTs >= 0) && (tsList[j] - pRowSup->prevTs <= gap)) ||
|
||||||
(pRowSup->prevTs - tsList[j] >= 0) && (pRowSup->prevTs - tsList[j] <= gap)) {
|
((pRowSup->prevTs - tsList[j] >= 0) && (pRowSup->prevTs - tsList[j] <= gap))) {
|
||||||
// The gap is less than the threshold, so it belongs to current session window that has been opened already.
|
// The gap is less than the threshold, so it belongs to current session window that has been opened already.
|
||||||
doKeepTuple(pRowSup, tsList[j], gid);
|
doKeepTuple(pRowSup, tsList[j], gid);
|
||||||
if (j == 0 && pRowSup->startRowIndex != 0) {
|
if (j == 0 && pRowSup->startRowIndex != 0) {
|
||||||
|
|
|
@ -44,12 +44,15 @@ static void setColumnInfo(SFunctionNode* pFunc, SColumnNode* pCol) {
|
||||||
pCol->colType = COLUMN_TYPE_TBNAME;
|
pCol->colType = COLUMN_TYPE_TBNAME;
|
||||||
break;
|
break;
|
||||||
case FUNCTION_TYPE_WSTART:
|
case FUNCTION_TYPE_WSTART:
|
||||||
|
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||||
|
pCol->colType = COLUMN_TYPE_WINDOW_START;
|
||||||
|
break;
|
||||||
case FUNCTION_TYPE_WEND:
|
case FUNCTION_TYPE_WEND:
|
||||||
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||||
pCol->colType = COLUMN_TYPE_WINDOW_PC;
|
pCol->colType = COLUMN_TYPE_WINDOW_END;
|
||||||
break;
|
break;
|
||||||
case FUNCTION_TYPE_WDURATION:
|
case FUNCTION_TYPE_WDURATION:
|
||||||
pCol->colType = COLUMN_TYPE_WINDOW_PC;
|
pCol->colType = COLUMN_TYPE_WINDOW_DURATION;
|
||||||
break;
|
break;
|
||||||
case FUNCTION_TYPE_GROUP_KEY:
|
case FUNCTION_TYPE_GROUP_KEY:
|
||||||
pCol->colType = COLUMN_TYPE_GROUP_KEY;
|
pCol->colType = COLUMN_TYPE_GROUP_KEY;
|
||||||
|
@ -784,7 +787,10 @@ static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
|
||||||
static EDealRes needFillValueImpl(SNode* pNode, void* pContext) {
|
static EDealRes needFillValueImpl(SNode* pNode, void* pContext) {
|
||||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||||
SColumnNode* pCol = (SColumnNode*)pNode;
|
SColumnNode* pCol = (SColumnNode*)pNode;
|
||||||
if (COLUMN_TYPE_WINDOW_PC != pCol->colType && COLUMN_TYPE_GROUP_KEY != pCol->colType) {
|
if (COLUMN_TYPE_WINDOW_START != pCol->colType &&
|
||||||
|
COLUMN_TYPE_WINDOW_END != pCol->colType &&
|
||||||
|
COLUMN_TYPE_WINDOW_DURATION != pCol->colType &&
|
||||||
|
COLUMN_TYPE_GROUP_KEY != pCol->colType) {
|
||||||
*(bool*)pContext = true;
|
*(bool*)pContext = true;
|
||||||
return DEAL_RES_END;
|
return DEAL_RES_END;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue