Merge branch '3.0' into feat/TD-27463-3.0
This commit is contained in:
commit
bf0205b54d
|
@ -262,6 +262,9 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf, c
|
|||
int32_t buildSubmitReqFromDataBlock(SSubmitReq2** pReq, const SSDataBlock* pDataBlocks, const STSchema* pTSchema, int64_t uid, int32_t vgId,
|
||||
tb_uid_t suid);
|
||||
|
||||
bool alreadyAddGroupId(char* ctbName);
|
||||
bool isAutoTableName(char* ctbName);
|
||||
void buildCtbNameAddGruopId(char* ctbName, uint64_t groupId);
|
||||
char* buildCtbNameByGroupId(const char* stbName, uint64_t groupId);
|
||||
int32_t buildCtbNameByGroupIdImpl(const char* stbName, uint64_t groupId, char* pBuf);
|
||||
|
||||
|
|
|
@ -189,7 +189,8 @@ typedef struct TsdReader {
|
|||
|
||||
typedef struct SStoreCacheReader {
|
||||
int32_t (*openReader)(void *pVnode, int32_t type, void *pTableIdList, int32_t numOfTables, int32_t numOfCols,
|
||||
SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr);
|
||||
SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr,
|
||||
SArray *pFuncTypeList);
|
||||
void *(*closeReader)(void *pReader);
|
||||
int32_t (*retrieveRows)(void *pReader, SSDataBlock *pResBlock, const int32_t *slotIds, const int32_t *dstSlotIds,
|
||||
SArray *pTableUidList);
|
||||
|
|
|
@ -149,6 +149,8 @@ void nodesRewriteExprPostOrder(SNode** pNode, FNodeRewriter rewriter, void* pCon
|
|||
void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
||||
|
||||
bool nodesEqualNode(const SNode* a, const SNode* b);
|
||||
bool nodeListNodeEqual(const SNodeList* a, const SNode* b);
|
||||
|
||||
bool nodesMatchNode(const SNode* pSub, const SNode* pNode);
|
||||
|
||||
SNode* nodesCloneNode(const SNode* pNode);
|
||||
|
|
|
@ -120,6 +120,7 @@ typedef struct SScanLogicNode {
|
|||
bool onlyMetaCtbIdx; // for tag scan with no tbname
|
||||
bool filesetDelimited; // returned blocks delimited by fileset
|
||||
bool isCountByTag; // true if selectstmt hasCountFunc & part by tag/tbname
|
||||
SArray* pFuncTypes; // for last, last_row
|
||||
} SScanLogicNode;
|
||||
|
||||
typedef struct SJoinLogicNode {
|
||||
|
@ -401,6 +402,7 @@ typedef struct SLastRowScanPhysiNode {
|
|||
bool groupSort;
|
||||
bool ignoreNull;
|
||||
SNodeList* pTargets;
|
||||
SArray* pFuncTypes;
|
||||
} SLastRowScanPhysiNode;
|
||||
|
||||
typedef SLastRowScanPhysiNode STableCountScanPhysiNode;
|
||||
|
|
|
@ -89,6 +89,7 @@ typedef struct SColumnNode {
|
|||
|
||||
typedef struct SColumnRefNode {
|
||||
ENodeType type;
|
||||
SDataType resType;
|
||||
char colName[TSDB_COL_NAME_LEN];
|
||||
} SColumnRefNode;
|
||||
|
||||
|
@ -532,6 +533,7 @@ int32_t nodesCollectColumnsFromNode(SNode* node, const char* pTableAlias, EColle
|
|||
|
||||
typedef bool (*FFuncClassifier)(int32_t funcId);
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList** pFuncs);
|
||||
int32_t nodesCollectSelectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList* pFuncs);
|
||||
|
||||
int32_t nodesCollectSpecialNodes(SSelectStmt* pSelect, ESqlClause clause, ENodeType type, SNodeList** pNodes);
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "systable.h"
|
||||
#include "tarray.h"
|
||||
#include "thash.h"
|
||||
#include "tlog.h"
|
||||
#include "tmsg.h"
|
||||
#include "tmsgcb.h"
|
||||
#include "systable.h"
|
||||
|
||||
typedef enum {
|
||||
JOB_TASK_STATUS_NULL = 0,
|
||||
|
@ -90,8 +90,7 @@ typedef struct SExecResult {
|
|||
void* res;
|
||||
} SExecResult;
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
#pragma pack(push, 1)
|
||||
typedef struct SCTableMeta {
|
||||
uint64_t uid;
|
||||
uint64_t suid;
|
||||
|
@ -100,8 +99,7 @@ typedef struct SCTableMeta {
|
|||
} SCTableMeta;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
#pragma pack(push, 1)
|
||||
typedef struct STableMeta {
|
||||
// BEGIN: KEEP THIS PART SAME WITH SCTableMeta
|
||||
uint64_t uid;
|
||||
|
@ -137,8 +135,8 @@ typedef struct SDBVgInfo {
|
|||
int8_t hashMethod;
|
||||
int32_t numOfTable; // DB's table num, unit is TSDB_TABLE_NUM_UNIT
|
||||
int64_t stateTs;
|
||||
SHashObj* vgHash; // key:vgId, value:SVgroupInfo
|
||||
SArray* vgArray; // SVgroupInfo
|
||||
SHashObj* vgHash; // key:vgId, value:SVgroupInfo
|
||||
SArray* vgArray; // SVgroupInfo
|
||||
} SDBVgInfo;
|
||||
|
||||
typedef struct SUseDbOutput {
|
||||
|
@ -173,6 +171,7 @@ typedef struct SDataBuf {
|
|||
void* pData;
|
||||
uint32_t len;
|
||||
void* handle;
|
||||
int64_t handleRefId;
|
||||
SEpSet* pEpSet;
|
||||
} SDataBuf;
|
||||
|
||||
|
@ -283,7 +282,7 @@ void getColumnTypeFromMeta(STableMeta* pMeta, char* pName, ETableColumnType*
|
|||
int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst);
|
||||
int32_t cloneSVreateTbReq(SVCreateTbReq* pSrc, SVCreateTbReq** pDst);
|
||||
void freeVgInfo(SDBVgInfo* vgInfo);
|
||||
void freeDbCfgInfo(SDbCfgInfo *pInfo);
|
||||
void freeDbCfgInfo(SDbCfgInfo* pInfo);
|
||||
|
||||
extern int32_t (*queryBuildMsg[TDMT_MAX])(void* input, char** msg, int32_t msgSize, int32_t* msgLen,
|
||||
void* (*mallocFp)(int64_t));
|
||||
|
@ -314,7 +313,9 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
|
|||
((_code) == TSDB_CODE_SYN_NOT_LEADER || (_code) == TSDB_CODE_SYN_RESTORING || (_code) == TSDB_CODE_SYN_INTERNAL_ERROR)
|
||||
#define SYNC_OTHER_LEADER_REDIRECT_ERROR(_code) ((_code) == TSDB_CODE_MNODE_NOT_FOUND)
|
||||
|
||||
#define NO_RET_REDIRECT_ERROR(_code) ((_code) == TSDB_CODE_RPC_BROKEN_LINK || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || (_code) == TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED)
|
||||
#define NO_RET_REDIRECT_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_RPC_BROKEN_LINK || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || \
|
||||
(_code) == TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED)
|
||||
|
||||
#define NEED_REDIRECT_ERROR(_code) \
|
||||
(NO_RET_REDIRECT_ERROR(_code) || SYNC_UNKNOWN_LEADER_REDIRECT_ERROR(_code) || \
|
||||
|
|
|
@ -62,9 +62,10 @@ typedef struct SStreamTask SStreamTask;
|
|||
typedef struct SStreamQueue SStreamQueue;
|
||||
typedef struct SStreamTaskSM SStreamTaskSM;
|
||||
|
||||
#define SSTREAM_TASK_VER 2
|
||||
#define SSTREAM_TASK_VER 3
|
||||
#define SSTREAM_TASK_INCOMPATIBLE_VER 1
|
||||
#define SSTREAM_TASK_NEED_CONVERT_VER 2
|
||||
#define SSTREAM_TASK_SUBTABLE_CHANGED_VER 3
|
||||
|
||||
enum {
|
||||
STREAM_STATUS__NORMAL = 0,
|
||||
|
@ -801,7 +802,7 @@ int32_t streamTaskCheckStatus(SStreamTask* pTask, int32_t upstreamTaskId, int32_
|
|||
int64_t* oldStage);
|
||||
int32_t streamTaskUpdateEpsetInfo(SStreamTask* pTask, SArray* pNodeList);
|
||||
void streamTaskResetUpstreamStageInfo(SStreamTask* pTask);
|
||||
bool streamTaskAllUpstreamClosed(SStreamTask* pTask);
|
||||
bool streamTaskIsAllUpstreamClosed(SStreamTask* pTask);
|
||||
bool streamTaskSetSchedStatusWait(SStreamTask* pTask);
|
||||
int8_t streamTaskSetSchedStatusActive(SStreamTask* pTask);
|
||||
int8_t streamTaskSetSchedStatusInactive(SStreamTask* pTask);
|
||||
|
@ -826,8 +827,7 @@ int32_t streamQueueGetNumOfItems(const SStreamQueue* pQueue);
|
|||
|
||||
// common
|
||||
int32_t streamRestoreParam(SStreamTask* pTask);
|
||||
int32_t streamResetParamForScanHistory(SStreamTask* pTask);
|
||||
void streamTaskPause(SStreamTask* pTask, SStreamMeta* pMeta);
|
||||
void streamTaskPause(SStreamMeta* pMeta, SStreamTask* pTask);
|
||||
void streamTaskResume(SStreamTask* pTask);
|
||||
int32_t streamTaskSetUpstreamInfo(SStreamTask* pTask, const SStreamTask* pUpstreamTask);
|
||||
void streamTaskUpdateUpstreamInfo(SStreamTask* pTask, int32_t nodeId, const SEpSet* pEpSet);
|
||||
|
@ -838,6 +838,7 @@ int32_t streamTaskReloadState(SStreamTask* pTask);
|
|||
void streamTaskCloseUpstreamInput(SStreamTask* pTask, int32_t taskId);
|
||||
void streamTaskOpenAllUpstreamInput(SStreamTask* pTask);
|
||||
int32_t streamTaskSetDb(SStreamMeta* pMeta, void* pTask, char* key);
|
||||
bool streamTaskIsSinkTask(const SStreamTask* pTask);
|
||||
|
||||
void streamTaskStatusInit(STaskStatusEntry* pEntry, const SStreamTask* pTask);
|
||||
void streamTaskStatusCopy(STaskStatusEntry* pDst, const STaskStatusEntry* pSrc);
|
||||
|
@ -872,7 +873,7 @@ int64_t streamMetaGetLatestCheckpointId(SStreamMeta* pMeta);
|
|||
void streamMetaNotifyClose(SStreamMeta* pMeta);
|
||||
void streamMetaStartHb(SStreamMeta* pMeta);
|
||||
bool streamMetaTaskInTimer(SStreamMeta* pMeta);
|
||||
int32_t streamMetaUpdateTaskDownstreamStatus(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t startTs,
|
||||
int32_t streamMetaAddTaskLaunchResult(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t startTs,
|
||||
int64_t endTs, bool ready);
|
||||
void streamMetaRLock(SStreamMeta* pMeta);
|
||||
void streamMetaRUnLock(SStreamMeta* pMeta);
|
||||
|
@ -885,6 +886,7 @@ int32_t streamMetaLoadAllTasks(SStreamMeta* pMeta);
|
|||
int32_t streamMetaStartAllTasks(SStreamMeta* pMeta);
|
||||
int32_t streamMetaStopAllTasks(SStreamMeta* pMeta);
|
||||
int32_t streamMetaStartOneTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId);
|
||||
bool streamMetaAllTasksReady(const SStreamMeta* pMeta);
|
||||
|
||||
// checkpoint
|
||||
int32_t streamProcessCheckpointSourceReq(SStreamTask* pTask, SStreamCheckpointSourceReq* pReq);
|
||||
|
|
|
@ -117,6 +117,8 @@ int32_t taosCompressFile(char *srcFileName, char *destFileName);
|
|||
|
||||
int32_t taosSetFileHandlesLimit();
|
||||
|
||||
int32_t taosLinkFile(char *src, char *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -285,8 +285,8 @@ int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtC
|
|||
|
||||
int32_t execLocalCmd(SRequestObj* pRequest, SQuery* pQuery) {
|
||||
SRetrieveTableRsp* pRsp = NULL;
|
||||
int8_t biMode = atomic_load_8(&pRequest->pTscObj->biMode);
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, biMode);
|
||||
int8_t biMode = atomic_load_8(&pRequest->pTscObj->biMode);
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, biMode);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pRsp) {
|
||||
code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, false, true);
|
||||
}
|
||||
|
@ -324,7 +324,8 @@ void asyncExecLocalCmd(SRequestObj* pRequest, SQuery* pQuery) {
|
|||
return;
|
||||
}
|
||||
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, atomic_load_8(&pRequest->pTscObj->biMode));
|
||||
int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp,
|
||||
atomic_load_8(&pRequest->pTscObj->biMode));
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pRsp) {
|
||||
code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, false, true);
|
||||
}
|
||||
|
@ -492,7 +493,8 @@ void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t
|
|||
pResInfo->userFields[i].bytes = pSchema[i].bytes;
|
||||
pResInfo->userFields[i].type = pSchema[i].type;
|
||||
|
||||
if (pSchema[i].type == TSDB_DATA_TYPE_VARCHAR || pSchema[i].type == TSDB_DATA_TYPE_VARBINARY || pSchema[i].type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
if (pSchema[i].type == TSDB_DATA_TYPE_VARCHAR || pSchema[i].type == TSDB_DATA_TYPE_VARBINARY ||
|
||||
pSchema[i].type == TSDB_DATA_TYPE_GEOMETRY) {
|
||||
pResInfo->userFields[i].bytes -= VARSTR_HEADER_SIZE;
|
||||
} else if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR || pSchema[i].type == TSDB_DATA_TYPE_JSON) {
|
||||
pResInfo->userFields[i].bytes = (pResInfo->userFields[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
||||
|
@ -1103,9 +1105,9 @@ static int32_t asyncExecSchQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaDat
|
|||
SSqlCallbackWrapper* pWrapper) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
pRequest->type = pQuery->msgType;
|
||||
SArray* pMnodeList = NULL;
|
||||
SQueryPlan* pDag = NULL;
|
||||
int64_t st = taosGetTimestampUs();
|
||||
SArray* pMnodeList = NULL;
|
||||
SQueryPlan* pDag = NULL;
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
if (!pRequest->parseOnly) {
|
||||
pMnodeList = taosArrayInit(4, sizeof(SQueryNodeLoad));
|
||||
|
@ -1278,7 +1280,7 @@ int32_t removeMeta(STscObj* pTscObj, SArray* tbList, bool isView) {
|
|||
if (isView) {
|
||||
for (int32_t i = 0; i < tbNum; ++i) {
|
||||
SName* pViewName = taosArrayGet(tbList, i);
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
tNameGetFullDbName(pViewName, dbFName);
|
||||
catalogRemoveViewMeta(pCatalog, dbFName, 0, pViewName->tname, 0);
|
||||
}
|
||||
|
@ -1510,8 +1512,12 @@ int32_t doProcessMsgFromServer(void* param) {
|
|||
|
||||
updateTargetEpSet(pSendInfo, pTscObj, pMsg, pEpSet);
|
||||
|
||||
SDataBuf buf = {
|
||||
.msgType = pMsg->msgType, .len = pMsg->contLen, .pData = NULL, .handle = pMsg->info.handle, .pEpSet = pEpSet};
|
||||
SDataBuf buf = {.msgType = pMsg->msgType,
|
||||
.len = pMsg->contLen,
|
||||
.pData = NULL,
|
||||
.handle = pMsg->info.handle,
|
||||
.handleRefId = pMsg->info.refId,
|
||||
.pEpSet = pEpSet};
|
||||
|
||||
if (pMsg->contLen > 0) {
|
||||
buf.pData = taosMemoryCalloc(1, pMsg->contLen);
|
||||
|
@ -2538,13 +2544,13 @@ static void fetchCallback(void* pResult, void* param, int32_t code) {
|
|||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pRequest->code = code;
|
||||
taosMemoryFreeClear(pResultInfo->pData);
|
||||
pRequest->body.fetchFp(((SSyncQueryParam *)pRequest->body.interParam)->userParam, pRequest, 0);
|
||||
pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pRequest->code != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFreeClear(pResultInfo->pData);
|
||||
pRequest->body.fetchFp(((SSyncQueryParam *)pRequest->body.interParam)->userParam, pRequest, 0);
|
||||
pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2565,12 +2571,12 @@ static void fetchCallback(void* pResult, void* param, int32_t code) {
|
|||
atomic_add_fetch_64((int64_t*)&pActivity->fetchBytes, pRequest->body.resInfo.payloadLen);
|
||||
}
|
||||
|
||||
pRequest->body.fetchFp(((SSyncQueryParam *)pRequest->body.interParam)->userParam, pRequest, pResultInfo->numOfRows);
|
||||
pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, pResultInfo->numOfRows);
|
||||
}
|
||||
|
||||
void taosAsyncFetchImpl(SRequestObj* pRequest, __taos_async_fn_t fp, void* param) {
|
||||
pRequest->body.fetchFp = fp;
|
||||
((SSyncQueryParam *)pRequest->body.interParam)->userParam = param;
|
||||
((SSyncQueryParam*)pRequest->body.interParam)->userParam = param;
|
||||
|
||||
SReqResultInfo* pResultInfo = &pRequest->body.resInfo;
|
||||
|
||||
|
@ -2611,7 +2617,7 @@ void taosAsyncFetchImpl(SRequestObj* pRequest, __taos_async_fn_t fp, void* param
|
|||
void doRequestCallback(SRequestObj* pRequest, int32_t code) {
|
||||
pRequest->inCallback = true;
|
||||
int64_t this = pRequest->self;
|
||||
pRequest->body.queryFp(((SSyncQueryParam *)pRequest->body.interParam)->userParam, pRequest, code);
|
||||
pRequest->body.queryFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, code);
|
||||
SRequestObj* pReq = acquireRequest(this);
|
||||
if (pReq != NULL) {
|
||||
pReq->inCallback = false;
|
||||
|
@ -2619,11 +2625,11 @@ void doRequestCallback(SRequestObj* pRequest, int32_t code) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t clientParseSql(void* param, const char* dbName, const char* sql, bool parseOnly, const char* effectiveUser, SParseSqlRes* pRes) {
|
||||
int32_t clientParseSql(void* param, const char* dbName, const char* sql, bool parseOnly, const char* effectiveUser,
|
||||
SParseSqlRes* pRes) {
|
||||
#ifndef TD_ENTERPRISE
|
||||
return TSDB_CODE_SUCCESS;
|
||||
#else
|
||||
return clientParseSqlImpl(param, dbName, sql, parseOnly, effectiveUser, pRes);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -57,10 +57,6 @@ void taos_cleanup(void) {
|
|||
|
||||
tscStopCrashReport();
|
||||
|
||||
int32_t id = clientReqRefPool;
|
||||
clientReqRefPool = -1;
|
||||
taosCloseRef(id);
|
||||
|
||||
hbMgrCleanUp();
|
||||
|
||||
catalogDestroy();
|
||||
|
@ -70,6 +66,12 @@ void taos_cleanup(void) {
|
|||
qCleanupKeywordsTable();
|
||||
nodesDestroyAllocatorSet();
|
||||
|
||||
cleanupTaskQueue();
|
||||
|
||||
int32_t id = clientReqRefPool;
|
||||
clientReqRefPool = -1;
|
||||
taosCloseRef(id);
|
||||
|
||||
id = clientConnRefPool;
|
||||
clientConnRefPool = -1;
|
||||
taosCloseRef(id);
|
||||
|
@ -77,8 +79,6 @@ void taos_cleanup(void) {
|
|||
rpcCleanup();
|
||||
tscDebug("rpc cleanup");
|
||||
|
||||
cleanupTaskQueue();
|
||||
|
||||
taosConvDestroy();
|
||||
|
||||
tscInfo("all local resources released");
|
||||
|
|
|
@ -2118,6 +2118,30 @@ _end:
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void buildCtbNameAddGruopId(char* ctbName, uint64_t groupId){
|
||||
char tmp[TSDB_TABLE_NAME_LEN] = {0};
|
||||
snprintf(tmp, TSDB_TABLE_NAME_LEN, "_%"PRIu64, groupId);
|
||||
ctbName[TSDB_TABLE_NAME_LEN - strlen(tmp) - 1] = 0; // put groupId to the end
|
||||
strcat(ctbName, tmp);
|
||||
}
|
||||
|
||||
bool isAutoTableName(char* ctbName){
|
||||
return (strlen(ctbName) == 34 && ctbName[0] == 't' && ctbName[1] == '_');
|
||||
}
|
||||
|
||||
bool alreadyAddGroupId(char* ctbName){
|
||||
size_t len = strlen(ctbName);
|
||||
size_t _location = len - 1;
|
||||
while(_location > 0){
|
||||
if(ctbName[_location] < '0' || ctbName[_location] > '9'){
|
||||
break;
|
||||
}
|
||||
_location--;
|
||||
}
|
||||
|
||||
return ctbName[_location] == '_' && len - 1 - _location > 15; //15 means the min length of groupid
|
||||
}
|
||||
|
||||
char* buildCtbNameByGroupId(const char* stbFullName, uint64_t groupId) {
|
||||
char* pBuf = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN + 1);
|
||||
if (!pBuf) {
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct SNodeEntry {
|
|||
|
||||
typedef struct SVgroupChangeInfo {
|
||||
SHashObj *pDBMap;
|
||||
SArray * pUpdateNodeList; // SArray<SNodeUpdateInfo>
|
||||
SArray *pUpdateNodeList; // SArray<SNodeUpdateInfo>
|
||||
} SVgroupChangeInfo;
|
||||
|
||||
static int32_t mndNodeCheckSentinel = 0;
|
||||
|
@ -89,8 +89,8 @@ static void freeCheckpointCandEntry(void *);
|
|||
static SSdbRaw *mndStreamActionEncode(SStreamObj *pStream);
|
||||
static SSdbRow *mndStreamActionDecode(SSdbRaw *pRaw);
|
||||
|
||||
SSdbRaw * mndStreamSeqActionEncode(SStreamObj *pStream);
|
||||
SSdbRow * mndStreamSeqActionDecode(SSdbRaw *pRaw);
|
||||
SSdbRaw *mndStreamSeqActionEncode(SStreamObj *pStream);
|
||||
SSdbRow *mndStreamSeqActionDecode(SSdbRaw *pRaw);
|
||||
static int32_t mndStreamSeqActionInsert(SSdb *pSdb, SStreamSeq *pStream);
|
||||
static int32_t mndStreamSeqActionDelete(SSdb *pSdb, SStreamSeq *pStream);
|
||||
static int32_t mndStreamSeqActionUpdate(SSdb *pSdb, SStreamSeq *pOldStream, SStreamSeq *pNewStream);
|
||||
|
@ -219,9 +219,9 @@ STREAM_ENCODE_OVER:
|
|||
|
||||
SSdbRow *mndStreamActionDecode(SSdbRaw *pRaw) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
SSdbRow * pRow = NULL;
|
||||
SSdbRow *pRow = NULL;
|
||||
SStreamObj *pStream = NULL;
|
||||
void * buf = NULL;
|
||||
void *buf = NULL;
|
||||
|
||||
int8_t sver = 0;
|
||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) {
|
||||
|
@ -301,7 +301,7 @@ static int32_t mndStreamActionUpdate(SSdb *pSdb, SStreamObj *pOldStream, SStream
|
|||
}
|
||||
|
||||
SStreamObj *mndAcquireStream(SMnode *pMnode, char *streamName) {
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStreamObj *pStream = sdbAcquire(pSdb, SDB_STREAM, streamName);
|
||||
if (pStream == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
|
||||
terrno = TSDB_CODE_MND_STREAM_NOT_EXIST;
|
||||
|
@ -356,7 +356,7 @@ static int32_t mndCheckCreateStreamReq(SCMCreateStreamReq *pCreate) {
|
|||
}
|
||||
|
||||
static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj, SCMCreateStreamReq *pCreate) {
|
||||
SNode * pAst = NULL;
|
||||
SNode *pAst = NULL;
|
||||
SQueryPlan *pPlan = NULL;
|
||||
|
||||
mInfo("stream:%s to create", pCreate->name);
|
||||
|
@ -595,7 +595,7 @@ int32_t mndPersistDropStreamLog(SMnode *pMnode, STrans *pTrans, SStreamObj *pStr
|
|||
|
||||
static int32_t mndCreateStbForStream(SMnode *pMnode, STrans *pTrans, const SStreamObj *pStream, const char *user) {
|
||||
SStbObj *pStb = NULL;
|
||||
SDbObj * pDb = NULL;
|
||||
SDbObj *pDb = NULL;
|
||||
|
||||
SMCreateStbReq createReq = {0};
|
||||
tstrncpy(createReq.name, pStream->targetSTbName, TSDB_TABLE_FNAME_LEN);
|
||||
|
@ -684,9 +684,10 @@ _OVER:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int32_t extractNodeEpset(SMnode *pMnode, SEpSet *pEpSet, bool* hasEpset, int32_t taskId, int32_t nodeId) {
|
||||
static int32_t extractNodeEpset(SMnode *pMnode, SEpSet *pEpSet, bool *hasEpset, int32_t taskId, int32_t nodeId) {
|
||||
*hasEpset = false;
|
||||
|
||||
pEpSet->numOfEps = 0;
|
||||
if (nodeId == SNODE_HANDLE) {
|
||||
SSnodeObj *pObj = NULL;
|
||||
void *pIter = NULL;
|
||||
|
@ -772,7 +773,7 @@ int32_t mndDropStreamTasks(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream)
|
|||
static int32_t checkForNumOfStreams(SMnode *pMnode, SStreamObj *pStreamObj) { // check for number of existed tasks
|
||||
int32_t numOfStream = 0;
|
||||
SStreamObj *pStream = NULL;
|
||||
void * pIter = NULL;
|
||||
void *pIter = NULL;
|
||||
|
||||
while ((pIter = sdbFetch(pMnode->pSdb, SDB_STREAM, pIter, (void **)&pStream)) != NULL) {
|
||||
if (pStream->sourceDbUid == pStreamObj->sourceDbUid) {
|
||||
|
@ -803,7 +804,7 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
|||
SMnode *pMnode = pReq->info.node;
|
||||
SStreamObj *pStream = NULL;
|
||||
SStreamObj streamObj = {0};
|
||||
char * sql = NULL;
|
||||
char *sql = NULL;
|
||||
int32_t sqlLen = 0;
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
@ -934,7 +935,7 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
_OVER:
|
||||
if (terrno != TSDB_CODE_SUCCESS && terrno != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
if (terrno != TSDB_CODE_SUCCESS && terrno != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("stream:%s, failed to create since %s", createStreamReq.name, terrstr());
|
||||
}
|
||||
|
||||
|
@ -950,8 +951,8 @@ _OVER:
|
|||
|
||||
int64_t mndStreamGenChkpId(SMnode *pMnode) {
|
||||
SStreamObj *pStream = NULL;
|
||||
void * pIter = NULL;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int64_t maxChkpId = 0;
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
|
@ -969,7 +970,7 @@ int64_t mndStreamGenChkpId(SMnode *pMnode) {
|
|||
|
||||
static int32_t mndProcessStreamCheckpointTmr(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
if (sdbGetSize(pSdb, SDB_STREAM) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -985,7 +986,7 @@ static int32_t mndProcessStreamCheckpointTmr(SRpcMsg *pReq) {
|
|||
|
||||
static int32_t mndProcessStreamRemainChkptTmr(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
if (sdbGetSize(pSdb, SDB_STREAM) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1026,7 +1027,7 @@ static int32_t mndBuildStreamCheckpointSourceReq2(void **pBuf, int32_t *pLen, in
|
|||
return -1;
|
||||
}
|
||||
|
||||
void * abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
|
||||
void *abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
|
||||
SEncoder encoder;
|
||||
tEncoderInit(&encoder, abuf, tlen);
|
||||
tEncodeStreamCheckpointSourceReq(&encoder, &req);
|
||||
|
@ -1080,7 +1081,7 @@ static int32_t mndProcessStreamCheckpointTrans(SMnode *pMnode, SStreamObj *pStre
|
|||
// 1. redo action: broadcast checkpoint source msg for all source vg
|
||||
int32_t totLevel = taosArrayGetSize(pStream->tasks);
|
||||
for (int32_t i = 0; i < totLevel; i++) {
|
||||
SArray * pLevel = taosArrayGetP(pStream->tasks, i);
|
||||
SArray *pLevel = taosArrayGetP(pStream->tasks, i);
|
||||
SStreamTask *p = taosArrayGetP(pLevel, 0);
|
||||
|
||||
if (p->info.taskLevel == TASK_LEVEL__SOURCE) {
|
||||
|
@ -1094,7 +1095,7 @@ static int32_t mndProcessStreamCheckpointTrans(SMnode *pMnode, SStreamObj *pStre
|
|||
goto _ERR;
|
||||
}
|
||||
|
||||
void * buf;
|
||||
void *buf;
|
||||
int32_t tlen;
|
||||
if (mndBuildStreamCheckpointSourceReq2(&buf, &tlen, pTask->info.nodeId, checkpointId, pTask->id.streamId,
|
||||
pTask->id.taskId, pTrans->id) < 0) {
|
||||
|
@ -1146,7 +1147,7 @@ static int32_t mndAddStreamCheckpointToTrans(STrans *pTrans, SStreamObj *pStream
|
|||
|
||||
int32_t totLevel = taosArrayGetSize(pStream->tasks);
|
||||
for (int32_t i = 0; i < totLevel; i++) {
|
||||
SArray * pLevel = taosArrayGetP(pStream->tasks, i);
|
||||
SArray *pLevel = taosArrayGetP(pStream->tasks, i);
|
||||
SStreamTask *pTask = taosArrayGetP(pLevel, 0);
|
||||
|
||||
if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) {
|
||||
|
@ -1163,7 +1164,7 @@ static int32_t mndAddStreamCheckpointToTrans(STrans *pTrans, SStreamObj *pStream
|
|||
return -1;
|
||||
}
|
||||
|
||||
void * buf;
|
||||
void *buf;
|
||||
int32_t tlen;
|
||||
if (mndBuildStreamCheckpointSourceReq2(&buf, &tlen, pTask->info.nodeId, chkptId, pTask->id.streamId,
|
||||
pTask->id.taskId, pTrans->id) < 0) {
|
||||
|
@ -1282,7 +1283,7 @@ static int32_t mndCheckNodeStatus(SMnode *pMnode) {
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(execInfo.pTaskList); ++i) {
|
||||
STaskId * p = taosArrayGet(execInfo.pTaskList, i);
|
||||
STaskId *p = taosArrayGet(execInfo.pTaskList, i);
|
||||
STaskStatusEntry *pEntry = taosHashGet(execInfo.pTaskMap, p, sizeof(*p));
|
||||
if (pEntry == NULL) {
|
||||
continue;
|
||||
|
@ -1301,9 +1302,9 @@ static int32_t mndCheckNodeStatus(SMnode *pMnode) {
|
|||
}
|
||||
|
||||
static int32_t mndProcessStreamDoCheckpoint(SRpcMsg *pReq) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
void * pIter = NULL;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SStreamObj *pStream = NULL;
|
||||
int32_t code = 0;
|
||||
|
||||
|
@ -1325,7 +1326,7 @@ static int32_t mndProcessStreamDoCheckpoint(SRpcMsg *pReq) {
|
|||
|
||||
static int32_t mndProcessStreamCheckpointInCandid(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
void * pIter = NULL;
|
||||
void *pIter = NULL;
|
||||
int32_t code = 0;
|
||||
|
||||
taosThreadMutexLock(&execInfo.lock);
|
||||
|
@ -1371,7 +1372,7 @@ static int32_t mndProcessStreamCheckpointInCandid(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
SMDropStreamReq dropReq = {0};
|
||||
|
@ -1528,7 +1529,7 @@ int32_t mndDropStreamByDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb) {
|
|||
}
|
||||
|
||||
int32_t mndGetNumOfStreams(SMnode *pMnode, char *dbName, int32_t *pNumOfStreams) {
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SDbObj *pDb = mndAcquireDb(pMnode, dbName);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||
|
@ -1536,7 +1537,7 @@ int32_t mndGetNumOfStreams(SMnode *pMnode, char *dbName, int32_t *pNumOfStreams)
|
|||
}
|
||||
|
||||
int32_t numOfStreams = 0;
|
||||
void * pIter = NULL;
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SStreamObj *pStream = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
|
@ -1555,8 +1556,8 @@ int32_t mndGetNumOfStreams(SMnode *pMnode, char *dbName, int32_t *pNumOfStreams)
|
|||
}
|
||||
|
||||
static int32_t mndRetrieveStream(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int32_t numOfRows = 0;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
|
@ -1731,7 +1732,7 @@ static int32_t setTaskAttrInResBlock(SStreamObj *pStream, SStreamTask *pTask, SS
|
|||
colDataSetVal(pColInfo, numOfRows, (const char *)vbuf, false);
|
||||
|
||||
// output queue
|
||||
// sprintf(buf, queueInfoStr, pe->outputQUsed, pe->outputRate);
|
||||
// sprintf(buf, queueInfoStr, pe->outputQUsed, pe->outputRate);
|
||||
// STR_TO_VARSTR(vbuf, buf);
|
||||
|
||||
// pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
|
@ -1767,8 +1768,8 @@ static int32_t getNumOfTasks(SArray *pTaskList) {
|
|||
}
|
||||
|
||||
static int32_t mndRetrieveStreamTask(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rowsCapacity) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int32_t numOfRows = 0;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
|
@ -1793,7 +1794,7 @@ static int32_t mndRetrieveStreamTask(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock
|
|||
int32_t numOfLevels = taosArrayGetSize(pLevel);
|
||||
for (int32_t j = 0; j < numOfLevels; j++) {
|
||||
SStreamTask *pTask = taosArrayGetP(pLevel, j);
|
||||
int32_t code = setTaskAttrInResBlock(pStream, pTask, pBlock, numOfRows);
|
||||
int32_t code = setTaskAttrInResBlock(pStream, pTask, pBlock, numOfRows);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
numOfRows++;
|
||||
}
|
||||
|
@ -1827,7 +1828,8 @@ static int32_t mndPauseStreamTask(SMnode *pMnode, STrans *pTrans, SStreamTask *p
|
|||
pReq->taskId = pTask->id.taskId;
|
||||
pReq->streamId = pTask->id.streamId;
|
||||
|
||||
SEpSet epset;
|
||||
SEpSet epset = {0};
|
||||
mDebug("pause node:%d, epset:%d", pTask->info.nodeId, epset.numOfEps);
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1873,12 +1875,14 @@ int32_t mndPauseAllStreamTasks(SMnode *pMnode, STrans *pTrans, SStreamObj *pStre
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndPersistStreamLog(STrans *pTrans, const SStreamObj *pStream, int8_t status) {
|
||||
SStreamObj streamObj = {0};
|
||||
memcpy(streamObj.name, pStream->name, TSDB_STREAM_FNAME_LEN);
|
||||
streamObj.status = status;
|
||||
static int32_t mndPersistStreamLog(STrans *pTrans, SStreamObj *pStream, int8_t status) {
|
||||
// SStreamObj streamObj = {0};
|
||||
// memcpy(streamObj.name, pStream->name, TSDB_STREAM_FNAME_LEN);
|
||||
taosWLockLatch(&pStream->lock);
|
||||
pStream->status = status;
|
||||
SSdbRaw *pCommitRaw = mndStreamActionEncode(pStream);
|
||||
|
||||
SSdbRaw *pCommitRaw = mndStreamActionEncode(&streamObj);
|
||||
taosWUnLockLatch(&pStream->lock);
|
||||
if (pCommitRaw == NULL) return -1;
|
||||
if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) {
|
||||
mError("stream trans:%d, failed to append commit log since %s", pTrans->id, terrstr());
|
||||
|
@ -1889,7 +1893,7 @@ static int32_t mndPersistStreamLog(STrans *pTrans, const SStreamObj *pStream, in
|
|||
}
|
||||
|
||||
static int32_t mndProcessPauseStreamReq(SRpcMsg *pReq) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
SMPauseStreamReq pauseReq = {0};
|
||||
|
@ -1993,7 +1997,7 @@ static int32_t mndResumeStreamTask(STrans *pTrans, SMnode *pMnode, SStreamTask *
|
|||
pReq->streamId = pTask->id.streamId;
|
||||
pReq->igUntreated = igUntreated;
|
||||
|
||||
SEpSet epset;
|
||||
SEpSet epset = {0};
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -2031,7 +2035,7 @@ int32_t mndResumeAllStreamTasks(STrans *pTrans, SMnode *pMnode, SStreamObj *pStr
|
|||
}
|
||||
|
||||
static int32_t mndProcessResumeStreamReq(SRpcMsg *pReq) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
SMResumeStreamReq pauseReq = {0};
|
||||
|
@ -2149,7 +2153,7 @@ static int32_t doBuildStreamTaskUpdateMsg(void **pBuf, int32_t *pLen, SVgroupCha
|
|||
return -1;
|
||||
}
|
||||
|
||||
void * abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
|
||||
void *abuf = POINTER_SHIFT(buf, sizeof(SMsgHead));
|
||||
SEncoder encoder;
|
||||
tEncoderInit(&encoder, abuf, tlen);
|
||||
tEncodeStreamTaskUpdateMsg(&encoder, &req);
|
||||
|
@ -2216,7 +2220,7 @@ static int32_t createStreamUpdateTrans(SStreamObj *pStream, SVgroupChangeInfo *p
|
|||
for (int32_t k = 0; k < numOfTasks; ++k) {
|
||||
SStreamTask *pTask = taosArrayGetP(pLevel, k);
|
||||
|
||||
void * pBuf = NULL;
|
||||
void *pBuf = NULL;
|
||||
int32_t len = 0;
|
||||
streamTaskUpdateEpsetInfo(pTask, pInfo->pUpdateNodeList);
|
||||
doBuildStreamTaskUpdateMsg(&pBuf, &len, pInfo, pTask->info.nodeId, &pTask->id, pTrans->id);
|
||||
|
@ -2295,8 +2299,8 @@ static SVgroupChangeInfo mndFindChangedNodeInfo(SMnode *pMnode, const SArray *pP
|
|||
}
|
||||
|
||||
static SArray *mndTakeVgroupSnapshot(SMnode *pMnode, bool *allReady) {
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
void * pIter = NULL;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SVgObj *pVgroup = NULL;
|
||||
|
||||
*allReady = true;
|
||||
|
@ -2364,7 +2368,7 @@ static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChange
|
|||
STrans *pTrans = NULL;
|
||||
|
||||
// conflict check for nodeUpdate trans, here we randomly chose one stream to add into the trans pool
|
||||
while(1) {
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
if (pIter == NULL) {
|
||||
break;
|
||||
|
@ -2380,7 +2384,6 @@ static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChange
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
if (pIter == NULL) {
|
||||
|
@ -2442,9 +2445,9 @@ static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChange
|
|||
}
|
||||
|
||||
static SArray *extractNodeListFromStream(SMnode *pMnode) {
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStreamObj *pStream = NULL;
|
||||
void * pIter = NULL;
|
||||
void *pIter = NULL;
|
||||
|
||||
SHashObj *pHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
|
||||
while (1) {
|
||||
|
@ -2491,9 +2494,9 @@ static SArray *extractNodeListFromStream(SMnode *pMnode) {
|
|||
}
|
||||
|
||||
static void doExtractTasksFromStream(SMnode *pMnode) {
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStreamObj *pStream = NULL;
|
||||
void * pIter = NULL;
|
||||
void *pIter = NULL;
|
||||
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
|
@ -2545,7 +2548,7 @@ int32_t removeExpirednodeEntryAndTask(SArray *pNodeSnapshot) {
|
|||
|
||||
int32_t numOfTask = taosArrayGetSize(execInfo.pTaskList);
|
||||
for (int32_t i = 0; i < numOfTask; ++i) {
|
||||
STaskId * pId = taosArrayGet(execInfo.pTaskList, i);
|
||||
STaskId *pId = taosArrayGet(execInfo.pTaskList, i);
|
||||
STaskStatusEntry *pEntry = taosHashGet(execInfo.pTaskMap, pId, sizeof(*pId));
|
||||
|
||||
if (pEntry->nodeId == SNODE_HANDLE) continue;
|
||||
|
@ -2593,7 +2596,7 @@ static void killAllCheckpointTrans(SMnode *pMnode, SVgroupChangeInfo *pChangeInf
|
|||
char *pDb = (char *)pIter;
|
||||
|
||||
size_t len = 0;
|
||||
void * pKey = taosHashGetKey(pDb, &len);
|
||||
void *pKey = taosHashGetKey(pDb, &len);
|
||||
doKillCheckpointTrans(pMnode, pKey, len);
|
||||
}
|
||||
}
|
||||
|
@ -2673,7 +2676,7 @@ typedef struct SMStreamNodeCheckMsg {
|
|||
|
||||
static int32_t mndProcessNodeCheck(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
if (sdbGetSize(pSdb, SDB_STREAM) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -2697,7 +2700,7 @@ void saveStreamTasksInfo(SStreamObj *pStream, SStreamExecInfo *pExecNode) {
|
|||
SStreamTask *pTask = taosArrayGetP(pLevel, j);
|
||||
|
||||
STaskId id = {.streamId = pTask->id.streamId, .taskId = pTask->id.taskId};
|
||||
void * p = taosHashGet(pExecNode->pTaskMap, &id, sizeof(id));
|
||||
void *p = taosHashGet(pExecNode->pTaskMap, &id, sizeof(id));
|
||||
if (p == NULL) {
|
||||
STaskStatusEntry entry = {0};
|
||||
streamTaskStatusInit(&entry, pTask);
|
||||
|
@ -2721,7 +2724,7 @@ void removeStreamTasksInBuf(SStreamObj *pStream, SStreamExecInfo *pExecNode) {
|
|||
SStreamTask *pTask = taosArrayGetP(pLevel, j);
|
||||
|
||||
STaskId id = {.streamId = pTask->id.streamId, .taskId = pTask->id.taskId};
|
||||
void * p = taosHashGet(pExecNode->pTaskMap, &id, sizeof(id));
|
||||
void *p = taosHashGet(pExecNode->pTaskMap, &id, sizeof(id));
|
||||
if (p != NULL) {
|
||||
taosHashRemove(pExecNode->pTaskMap, &id, sizeof(id));
|
||||
|
||||
|
@ -2794,8 +2797,8 @@ int32_t createStreamResetStatusTrans(SMnode *pMnode, SStreamObj *pStream) {
|
|||
pReq->taskId = pTask->id.taskId;
|
||||
pReq->streamId = pTask->id.streamId;
|
||||
|
||||
SEpSet epset;
|
||||
bool hasEpset = false;
|
||||
SEpSet epset = {0};
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(pReq);
|
||||
|
@ -2839,7 +2842,7 @@ int32_t createStreamResetStatusTrans(SMnode *pMnode, SStreamObj *pStream) {
|
|||
return TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
void killTransImpl(SMnode* pMnode, int32_t transId, const char* pDbName) {
|
||||
void killTransImpl(SMnode *pMnode, int32_t transId, const char *pDbName) {
|
||||
STrans *pTrans = mndAcquireTrans(pMnode, transId);
|
||||
if (pTrans != NULL) {
|
||||
mInfo("kill active transId:%d in Db:%s", transId, pDbName);
|
||||
|
@ -2861,7 +2864,7 @@ int32_t doKillCheckpointTrans(SMnode *pMnode, const char *pDBName, size_t len) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
char* pDupDBName = strndup(pDBName, len);
|
||||
char *pDupDBName = strndup(pDBName, len);
|
||||
killTransImpl(pMnode, pTransInfo->transId, pDupDBName);
|
||||
taosMemoryFree(pDupDBName);
|
||||
|
||||
|
@ -2916,38 +2919,38 @@ static SStreamTask *mndGetStreamTask(STaskId *pId, SStreamObj *pStream) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//static bool needDropRelatedFillhistoryTask(STaskStatusEntry *pTaskEntry, SStreamExecInfo *pExecNode) {
|
||||
// if (pTaskEntry->status == TASK_STATUS__STREAM_SCAN_HISTORY && pTaskEntry->statusLastDuration >= 10) {
|
||||
// if (!pTaskEntry->inputQChanging && pTaskEntry->inputQUnchangeCounter > 10) {
|
||||
// int32_t numOfReady = 0;
|
||||
// int32_t numOfTotal = 0;
|
||||
// for (int32_t k = 0; k < taosArrayGetSize(pExecNode->pTaskList); ++k) {
|
||||
// STaskId *pId = taosArrayGet(pExecNode->pTaskList, k);
|
||||
// if (pTaskEntry->id.streamId == pId->streamId) {
|
||||
// numOfTotal++;
|
||||
// static bool needDropRelatedFillhistoryTask(STaskStatusEntry *pTaskEntry, SStreamExecInfo *pExecNode) {
|
||||
// if (pTaskEntry->status == TASK_STATUS__STREAM_SCAN_HISTORY && pTaskEntry->statusLastDuration >= 10) {
|
||||
// if (!pTaskEntry->inputQChanging && pTaskEntry->inputQUnchangeCounter > 10) {
|
||||
// int32_t numOfReady = 0;
|
||||
// int32_t numOfTotal = 0;
|
||||
// for (int32_t k = 0; k < taosArrayGetSize(pExecNode->pTaskList); ++k) {
|
||||
// STaskId *pId = taosArrayGet(pExecNode->pTaskList, k);
|
||||
// if (pTaskEntry->id.streamId == pId->streamId) {
|
||||
// numOfTotal++;
|
||||
//
|
||||
// if (pTaskEntry->id.taskId != pId->taskId) {
|
||||
// STaskStatusEntry *pEntry = taosHashGet(execInfo.pTaskMap, pId, sizeof(*pId));
|
||||
// if (pEntry->status == TASK_STATUS__READY) {
|
||||
// numOfReady++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (pTaskEntry->id.taskId != pId->taskId) {
|
||||
// STaskStatusEntry *pEntry = taosHashGet(execInfo.pTaskMap, pId, sizeof(*pId));
|
||||
// if (pEntry->status == TASK_STATUS__READY) {
|
||||
// numOfReady++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (numOfReady > 0) {
|
||||
// mDebug("stream:0x%" PRIx64
|
||||
// " %d tasks are ready, %d tasks in stream-scan-history for more than 50s, drop related fill-history task",
|
||||
// pTaskEntry->id.streamId, numOfReady, numOfTotal - numOfReady);
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (numOfReady > 0) {
|
||||
// mDebug("stream:0x%" PRIx64
|
||||
// " %d tasks are ready, %d tasks in stream-scan-history for more than 50s, drop related fill-history
|
||||
// task", pTaskEntry->id.streamId, numOfReady, numOfTotal - numOfReady);
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// currently only handle the sink task
|
||||
// 1. sink task, drop related fill-history task msg is missing
|
||||
|
@ -2977,7 +2980,7 @@ static int32_t mndDropRelatedFillhistoryTask(SMnode *pMnode, STaskStatusEntry *p
|
|||
|
||||
mDebug("build and send drop related fill-history task for task:0x%x", pTask->id.taskId);
|
||||
|
||||
SEpSet epset;
|
||||
SEpSet epset = {0};
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -3030,7 +3033,7 @@ static void updateStageInfo(STaskStatusEntry *pTaskEntry, int64_t stage) {
|
|||
}
|
||||
|
||||
int32_t mndProcessStreamHb(SRpcMsg *pReq) {
|
||||
SMnode * pMnode = pReq->info.node;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SStreamHbMsg req = {0};
|
||||
|
||||
bool checkpointFailed = false;
|
||||
|
@ -3150,8 +3153,8 @@ void freeCheckpointCandEntry(void *param) {
|
|||
taosMemoryFreeClear(pEntry->pName);
|
||||
}
|
||||
SStreamObj *mndGetStreamObj(SMnode *pMnode, int64_t streamId) {
|
||||
void * pIter = NULL;
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStreamObj *pStream = NULL;
|
||||
|
||||
while ((pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream)) != NULL) {
|
||||
|
|
|
@ -1831,10 +1831,12 @@ static int32_t mndAddIncVgroupReplicaToTrans(SMnode *pMnode, STrans *pTrans, SDb
|
|||
int32_t newDnodeId) {
|
||||
mInfo("vgId:%d, will add 1 vnode, replica:%d dnode:%d", pVgroup->vgId, pVgroup->replica, newDnodeId);
|
||||
|
||||
// assoc dnode
|
||||
SVnodeGid *pGid = &pVgroup->vnodeGid[pVgroup->replica];
|
||||
pVgroup->replica++;
|
||||
pGid->dnodeId = newDnodeId;
|
||||
pGid->syncState = TAOS_SYNC_STATE_OFFLINE;
|
||||
pGid->nodeRole = TAOS_SYNC_ROLE_LEARNER;
|
||||
|
||||
SSdbRaw *pVgRaw = mndVgroupActionEncode(pVgroup);
|
||||
if (pVgRaw == NULL) return -1;
|
||||
|
@ -1844,10 +1846,20 @@ static int32_t mndAddIncVgroupReplicaToTrans(SMnode *pMnode, STrans *pTrans, SDb
|
|||
}
|
||||
(void)sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
|
||||
|
||||
// learner
|
||||
for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
|
||||
if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId) != 0) return -1;
|
||||
}
|
||||
if (mndAddCreateVnodeAction(pMnode, pTrans, pDb, pVgroup, pGid) != 0) return -1;
|
||||
|
||||
// voter
|
||||
pGid->nodeRole = TAOS_SYNC_ROLE_VOTER;
|
||||
if (mndAddAlterVnodeTypeAction(pMnode, pTrans, pDb, pVgroup, pGid->dnodeId) != 0) return -1;
|
||||
for (int32_t i = 0; i < pVgroup->replica - 1; ++i) {
|
||||
if (mndAddAlterVnodeReplicaAction(pMnode, pTrans, pDb, pVgroup, pVgroup->vnodeGid[i].dnodeId) != 0) return -1;
|
||||
}
|
||||
|
||||
// confirm
|
||||
if (mndAddAlterVnodeConfirmAction(pMnode, pTrans, pDb, pVgroup) != 0) return -1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -175,7 +175,8 @@ void tsdbReaderSetNotifyCb(STsdbReader* pReader, TsdReaderNotifyCbFn not
|
|||
|
||||
int32_t tsdbReuseCacherowsReader(void *pReader, void *pTableIdList, int32_t numOfTables);
|
||||
int32_t tsdbCacherowsReaderOpen(void *pVnode, int32_t type, void *pTableIdList, int32_t numOfTables, int32_t numOfCols,
|
||||
SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr);
|
||||
SArray *pCidList, int32_t *pSlotIds, uint64_t suid, void **pReader, const char *idstr,
|
||||
SArray* pFuncTypeList);
|
||||
int32_t tsdbRetrieveCacheRows(void *pReader, SSDataBlock *pResBlock, const int32_t *slotIds, const int32_t *dstSlotIds,
|
||||
SArray *pTableUids);
|
||||
void *tsdbCacherowsReaderClose(void *pReader);
|
||||
|
|
|
@ -146,7 +146,7 @@ int32_t tqOffsetCommitFile(STqOffsetStore* pStore);
|
|||
|
||||
// tqSink
|
||||
int32_t tqBuildDeleteReq(STQ* pTq, const char* stbFullName, const SSDataBlock* pDataBlock, SBatchDeleteReq* deleteReq,
|
||||
const char* pIdStr);
|
||||
const char* pIdStr, bool newSubTableRule);
|
||||
void tqSinkDataIntoDstTable(SStreamTask* pTask, void* vnode, void* data);
|
||||
|
||||
// tqOffset
|
||||
|
@ -165,7 +165,7 @@ int32_t setDstTableDataPayload(uint64_t suid, const STSchema* pTSchema, int32_t
|
|||
int32_t doMergeExistedRows(SSubmitTbData* pExisted, const SSubmitTbData* pNew, const char* id);
|
||||
|
||||
SVCreateTbReq* buildAutoCreateTableReq(const char* stbFullName, int64_t suid, int32_t numOfCols,
|
||||
SSDataBlock* pDataBlock, SArray* pTagArray);
|
||||
SSDataBlock* pDataBlock, SArray* pTagArray, bool newSubTableRule);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -703,7 +703,7 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
|
|||
code = terrno;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
code = tqBuildDeleteReq(pSma->pVnode->pTq, NULL, output, &deleteReq, "");
|
||||
code = tqBuildDeleteReq(pSma->pVnode->pTq, NULL, output, &deleteReq, "", true);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
code = tdRSmaProcessDelReq(pSma, suid, pItem->level, &deleteReq);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
|
|
@ -188,7 +188,7 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
|
|||
if (pDataBlock->info.type == STREAM_DELETE_RESULT) {
|
||||
pDeleteReq->suid = suid;
|
||||
pDeleteReq->deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq));
|
||||
code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, pDeleteReq, "");
|
||||
code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, pDeleteReq, "", true);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
continue;
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
|
|||
SSubmitTbData tbData = {.suid = suid, .uid = 0, .sver = pTSchema->version, .flags = SUBMIT_REQ_AUTO_CREATE_TABLE,};
|
||||
|
||||
int32_t cid = taosArrayGetSize(pDataBlock->pDataBlock) + 1;
|
||||
tbData.pCreateTbReq = buildAutoCreateTableReq(stbFullName, suid, cid, pDataBlock, tagArray);
|
||||
tbData.pCreateTbReq = buildAutoCreateTableReq(stbFullName, suid, cid, pDataBlock, tagArray, true);
|
||||
|
||||
{
|
||||
uint64_t groupId = pDataBlock->info.id.groupId;
|
||||
|
|
|
@ -742,8 +742,6 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t nextProcessVer) {
|
|||
return code;
|
||||
}
|
||||
|
||||
streamTaskOpenAllUpstreamInput(pTask);
|
||||
|
||||
if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) {
|
||||
STaskId taskId = {0};
|
||||
if (pTask->info.fillHistory) {
|
||||
|
@ -1126,6 +1124,19 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
pRsp->info.handle = NULL;
|
||||
|
||||
SStreamCheckpointSourceReq req = {0};
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, (uint8_t*)msg, len);
|
||||
if (tDecodeStreamCheckpointSourceReq(&decoder, &req) < 0) {
|
||||
code = TSDB_CODE_MSG_DECODE_ERROR;
|
||||
tDecoderClear(&decoder);
|
||||
tqError("vgId:%d failed to decode checkpoint-source msg, code:%s", vgId, tstrerror(code));
|
||||
SRpcMsg rsp = {0};
|
||||
buildCheckpointSourceRsp(&req, &pMsg->info, &rsp, 0);
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
return code;
|
||||
}
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
if (!vnodeIsRoleLeader(pTq->pVnode)) {
|
||||
tqDebug("vgId:%d not leader, ignore checkpoint-source msg, s-task:0x%x", vgId, req.taskId);
|
||||
SRpcMsg rsp = {0};
|
||||
|
@ -1142,19 +1153,6 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, (uint8_t*)msg, len);
|
||||
if (tDecodeStreamCheckpointSourceReq(&decoder, &req) < 0) {
|
||||
code = TSDB_CODE_MSG_DECODE_ERROR;
|
||||
tDecoderClear(&decoder);
|
||||
tqError("vgId:%d failed to decode checkpoint-source msg, code:%s", vgId, tstrerror(code));
|
||||
SRpcMsg rsp = {0};
|
||||
buildCheckpointSourceRsp(&req, &pMsg->info, &rsp, 0);
|
||||
tmsgSendRsp(&rsp); // error occurs
|
||||
return code;
|
||||
}
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, req.streamId, req.taskId);
|
||||
if (pTask == NULL) {
|
||||
tqError("vgId:%d failed to find s-task:0x%x, ignore checkpoint msg. it may have been destroyed already", vgId,
|
||||
|
|
|
@ -596,10 +596,12 @@ static int32_t doSetVal(SColumnInfoData* pColumnInfoData, int32_t rowIndex, SCol
|
|||
|
||||
if (IS_STR_DATA_TYPE(pColVal->type)) {
|
||||
char val[65535 + 2] = {0};
|
||||
if (pColVal->value.pData != NULL) {
|
||||
memcpy(varDataVal(val), pColVal->value.pData, pColVal->value.nData);
|
||||
if(COL_VAL_IS_VALUE(pColVal)){
|
||||
if (pColVal->value.pData != NULL) {
|
||||
memcpy(varDataVal(val), pColVal->value.pData, pColVal->value.nData);
|
||||
}
|
||||
varDataSetLen(val, pColVal->value.nData);
|
||||
code = colDataSetVal(pColumnInfoData, rowIndex, val, !COL_VAL_IS_VALUE(pColVal));
|
||||
code = colDataSetVal(pColumnInfoData, rowIndex, val, false);
|
||||
} else {
|
||||
colDataSetNULL(pColumnInfoData, rowIndex);
|
||||
}
|
||||
|
@ -869,22 +871,8 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
|||
sourceIdx++;
|
||||
} else if (pCol->cid == pColData->info.colId) {
|
||||
tColDataGetValue(pCol, i, &colVal);
|
||||
|
||||
if (IS_STR_DATA_TYPE(colVal.type)) {
|
||||
if (colVal.value.pData != NULL) {
|
||||
char val[65535 + 2];
|
||||
memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
|
||||
varDataSetLen(val, colVal.value.nData);
|
||||
if (colDataSetVal(pColData, curRow - lastRow, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
} else {
|
||||
colDataSetNULL(pColData, curRow - lastRow);
|
||||
}
|
||||
} else {
|
||||
if (colDataSetVal(pColData, curRow - lastRow, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
if(doSetVal(pColData, curRow - lastRow, &colVal) != TDB_CODE_SUCCESS){
|
||||
goto FAIL;
|
||||
}
|
||||
sourceIdx++;
|
||||
targetIdx++;
|
||||
|
@ -967,23 +955,10 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
|||
if (colVal.cid < pColData->info.colId) {
|
||||
sourceIdx++;
|
||||
} else if (colVal.cid == pColData->info.colId) {
|
||||
if (IS_STR_DATA_TYPE(colVal.type)) {
|
||||
if (colVal.value.pData != NULL) {
|
||||
char val[65535 + 2];
|
||||
memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
|
||||
varDataSetLen(val, colVal.value.nData);
|
||||
if (colDataSetVal(pColData, curRow - lastRow, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
} else {
|
||||
colDataSetNULL(pColData, curRow - lastRow);
|
||||
}
|
||||
} else {
|
||||
if (colDataSetVal(pColData, curRow - lastRow, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
if(doSetVal(pColData, curRow - lastRow, &colVal) != TDB_CODE_SUCCESS){
|
||||
goto FAIL;
|
||||
}
|
||||
sourceIdx++;
|
||||
sourceIdx++;
|
||||
targetIdx++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,10 +41,10 @@ static bool isValidDstChildTable(SMetaReader* pReader, int32_t vgId, const ch
|
|||
static int32_t initCreateTableMsg(SVCreateTbReq* pCreateTableReq, uint64_t suid, const char* stbFullName, int32_t numOfTags);
|
||||
static SArray* createDefaultTagColName();
|
||||
static void setCreateTableMsgTableName(SVCreateTbReq* pCreateTableReq, SSDataBlock* pDataBlock, const char* stbFullName,
|
||||
int64_t gid);
|
||||
int64_t gid, bool newSubTableRule);
|
||||
|
||||
int32_t tqBuildDeleteReq(STQ* pTq, const char* stbFullName, const SSDataBlock* pDataBlock, SBatchDeleteReq* deleteReq,
|
||||
const char* pIdStr) {
|
||||
const char* pIdStr, bool newSubTableRule) {
|
||||
int32_t totalRows = pDataBlock->info.rows;
|
||||
SColumnInfoData* pStartTsCol = taosArrayGet(pDataBlock->pDataBlock, START_TS_COLUMN_INDEX);
|
||||
SColumnInfoData* pEndTsCol = taosArrayGet(pDataBlock->pDataBlock, END_TS_COLUMN_INDEX);
|
||||
|
@ -68,6 +68,12 @@ int32_t tqBuildDeleteReq(STQ* pTq, const char* stbFullName, const SSDataBlock* p
|
|||
if (varTbName != NULL && varTbName != (void*)-1) {
|
||||
name = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN);
|
||||
memcpy(name, varDataVal(varTbName), varDataLen(varTbName));
|
||||
if(newSubTableRule &&
|
||||
!isAutoTableName(name) &&
|
||||
!alreadyAddGroupId(name) &&
|
||||
groupId != 0) {
|
||||
buildCtbNameAddGruopId(name, groupId);
|
||||
}
|
||||
} else if (stbFullName) {
|
||||
name = buildCtbNameByGroupId(stbFullName, groupId);
|
||||
} else {
|
||||
|
@ -173,9 +179,18 @@ SArray* createDefaultTagColName() {
|
|||
}
|
||||
|
||||
void setCreateTableMsgTableName(SVCreateTbReq* pCreateTableReq, SSDataBlock* pDataBlock, const char* stbFullName,
|
||||
int64_t gid) {
|
||||
int64_t gid, bool newSubTableRule) {
|
||||
if (pDataBlock->info.parTbName[0]) {
|
||||
pCreateTableReq->name = taosStrdup(pDataBlock->info.parTbName);
|
||||
if(newSubTableRule &&
|
||||
!isAutoTableName(pDataBlock->info.parTbName) &&
|
||||
!alreadyAddGroupId(pDataBlock->info.parTbName) &&
|
||||
gid != 0) {
|
||||
pCreateTableReq->name = taosMemoryCalloc(1, TSDB_TABLE_NAME_LEN);
|
||||
strcpy(pCreateTableReq->name, pDataBlock->info.parTbName);
|
||||
buildCtbNameAddGruopId(pCreateTableReq->name, gid);
|
||||
}else{
|
||||
pCreateTableReq->name = taosStrdup(pDataBlock->info.parTbName);
|
||||
}
|
||||
} else {
|
||||
pCreateTableReq->name = buildCtbNameByGroupId(stbFullName, gid);
|
||||
}
|
||||
|
@ -247,7 +262,7 @@ static int32_t doBuildAndSendCreateTableMsg(SVnode* pVnode, char* stbFullName, S
|
|||
ASSERT(gid == *(int64_t*)pGpIdData);
|
||||
}
|
||||
|
||||
setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, gid);
|
||||
setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, gid, pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER);
|
||||
|
||||
taosArrayPush(reqs.pArray, pCreateTbReq);
|
||||
tqDebug("s-task:%s build create table:%s msg complete", pTask->id.idStr, pCreateTbReq->name);
|
||||
|
@ -357,7 +372,8 @@ int32_t doBuildAndSendDeleteMsg(SVnode* pVnode, char* stbFullName, SSDataBlock*
|
|||
int64_t suid) {
|
||||
SBatchDeleteReq deleteReq = {.suid = suid, .deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq))};
|
||||
|
||||
int32_t code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, &deleteReq, pTask->id.idStr);
|
||||
int32_t code = tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, &deleteReq, pTask->id.idStr,
|
||||
pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -411,7 +427,7 @@ bool isValidDstChildTable(SMetaReader* pReader, int32_t vgId, const char* ctbNam
|
|||
}
|
||||
|
||||
SVCreateTbReq* buildAutoCreateTableReq(const char* stbFullName, int64_t suid, int32_t numOfCols,
|
||||
SSDataBlock* pDataBlock, SArray* pTagArray) {
|
||||
SSDataBlock* pDataBlock, SArray* pTagArray, bool newSubTableRule) {
|
||||
SVCreateTbReq* pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
|
||||
if (pCreateTbReq == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -436,7 +452,7 @@ SVCreateTbReq* buildAutoCreateTableReq(const char* stbFullName, int64_t suid, in
|
|||
pCreateTbReq->ctb.tagName = createDefaultTagColName();
|
||||
|
||||
// set table name
|
||||
setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, pDataBlock->info.id.groupId);
|
||||
setCreateTableMsgTableName(pCreateTbReq, pDataBlock, stbFullName, pDataBlock->info.id.groupId, newSubTableRule);
|
||||
return pCreateTbReq;
|
||||
}
|
||||
|
||||
|
@ -637,6 +653,7 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
|
|||
tqDebug("s-task:%s vgId:%d, gropuId:%" PRIu64 " datablock table name is null, set name:%s", id, vgId, groupId,
|
||||
dstTableName);
|
||||
} else {
|
||||
tstrncpy(dstTableName, pTableSinkInfo->name.data, pTableSinkInfo->name.len + 1);
|
||||
if (pTableSinkInfo->uid != 0) {
|
||||
tqDebug("s-task:%s write %d rows into groupId:%" PRIu64 " dstTable:%s(uid:%" PRIu64 ")", id, numOfRows, groupId,
|
||||
dstTableName, pTableSinkInfo->uid);
|
||||
|
@ -649,10 +666,17 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
|
|||
if (dstTableName[0] == 0) {
|
||||
memset(dstTableName, 0, TSDB_TABLE_NAME_LEN);
|
||||
buildCtbNameByGroupIdImpl(stbFullName, groupId, dstTableName);
|
||||
}else{
|
||||
if(pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER &&
|
||||
!isAutoTableName(dstTableName) &&
|
||||
!alreadyAddGroupId(dstTableName) &&
|
||||
groupId != 0) {
|
||||
buildCtbNameAddGruopId(dstTableName, groupId);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t nameLen = strlen(dstTableName);
|
||||
pTableSinkInfo = taosMemoryCalloc(1, sizeof(STableSinkInfo) + nameLen);
|
||||
pTableSinkInfo = taosMemoryCalloc(1, sizeof(STableSinkInfo) + nameLen + 1);
|
||||
if (pTableSinkInfo == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -690,7 +714,7 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
|
|||
|
||||
pTableData->flags = SUBMIT_REQ_AUTO_CREATE_TABLE;
|
||||
pTableData->pCreateTbReq =
|
||||
buildAutoCreateTableReq(stbFullName, suid, pTSchema->numOfCols + 1, pDataBlock, pTagArray);
|
||||
buildAutoCreateTableReq(stbFullName, suid, pTSchema->numOfCols + 1, pDataBlock, pTagArray, pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER);
|
||||
taosArrayDestroy(pTagArray);
|
||||
|
||||
if (pTableData->pCreateTbReq == NULL) {
|
||||
|
@ -719,7 +743,7 @@ int32_t setDstTableDataUid(SVnode* pVnode, SStreamTask* pTask, SSDataBlock* pDat
|
|||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return TDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t setDstTableDataPayload(uint64_t suid, const STSchema *pTSchema, int32_t blockIndex, SSDataBlock* pDataBlock,
|
||||
|
|
|
@ -76,33 +76,6 @@ int32_t tqStreamOneTaskStartAsync(SStreamMeta* pMeta, SMsgCb* cb, int64_t stream
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqUpdateNodeEpsetAsync(SStreamMeta* pMeta, SMsgCb* cb, int64_t streamId, int32_t taskId) {
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
if (numOfTasks == 0) {
|
||||
tqDebug("vgId:%d no stream tasks existed to run", vgId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SStreamTaskRunReq* pRunReq = rpcMallocCont(sizeof(SStreamTaskRunReq));
|
||||
if (pRunReq == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tqError("vgId:%d failed to create msg to start task:0x%x, code:%s", vgId, taskId, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d update s-task:0x%x nodeEpset async", vgId, taskId);
|
||||
pRunReq->head.vgId = vgId;
|
||||
pRunReq->streamId = streamId;
|
||||
pRunReq->taskId = taskId;
|
||||
pRunReq->reqType = STREAM_EXEC_T_UPDATE_TASK_EPSET;
|
||||
|
||||
SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)};
|
||||
tmsgPutToQueue(cb, STREAM_QUEUE, &msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqStreamTaskProcessUpdateReq(SStreamMeta* pMeta, SMsgCb* cb, SRpcMsg* pMsg, bool restored) {
|
||||
int32_t vgId = pMeta->vgId;
|
||||
char* msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||
|
@ -526,7 +499,7 @@ int32_t tqStreamTaskProcessCheckRsp(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLe
|
|||
streamMetaRUnLock(pMeta);
|
||||
|
||||
if (hasHistoryTask) {
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, fId.streamId, fId.taskId, initTs, now, false);
|
||||
streamMetaAddTaskLaunchResult(pMeta, fId.streamId, fId.taskId, initTs, now, false);
|
||||
}
|
||||
|
||||
tqError("vgId:%d not leader, task:0x%x not handle the check rsp, downstream:0x%x (vgId:%d)", vgId,
|
||||
|
@ -539,7 +512,7 @@ int32_t tqStreamTaskProcessCheckRsp(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLe
|
|||
code = terrno = TSDB_CODE_STREAM_TASK_NOT_EXIST;
|
||||
}
|
||||
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, rsp.streamId, rsp.upstreamTaskId, initTs, now, false);
|
||||
streamMetaAddTaskLaunchResult(pMeta, rsp.streamId, rsp.upstreamTaskId, initTs, now, false);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -553,13 +526,13 @@ int32_t tqStreamTaskProcessCheckRsp(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLe
|
|||
streamMetaRUnLock(pMeta);
|
||||
|
||||
if (hasHistoryTask) {
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, fId.streamId, fId.taskId, initTs, now, false);
|
||||
streamMetaAddTaskLaunchResult(pMeta, fId.streamId, fId.taskId, initTs, now, false);
|
||||
}
|
||||
} else {
|
||||
streamMetaRUnLock(pMeta);
|
||||
}
|
||||
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, rsp.streamId, rsp.upstreamTaskId, initTs, now, false);
|
||||
streamMetaAddTaskLaunchResult(pMeta, rsp.streamId, rsp.upstreamTaskId, initTs, now, false);
|
||||
tqError("tq failed to locate the stream task:0x%" PRIx64 "-0x%x (vgId:%d), it may have been destroyed or stopped",
|
||||
rsp.streamId, rsp.upstreamTaskId, vgId);
|
||||
|
||||
|
@ -728,10 +701,6 @@ int32_t tqStreamTaskResetStatus(SStreamMeta* pMeta, int32_t* numOfTasks) {
|
|||
STaskId id = {.streamId = pTaskId->streamId, .taskId = pTaskId->taskId};
|
||||
SStreamTask** pTask = taosHashGet(pMeta->pTasksMap, &id, sizeof(id));
|
||||
streamTaskResetStatus(*pTask);
|
||||
|
||||
// if ((*pTask)->info.fillHistory == 1) {
|
||||
// streamResetParamForScanHistory(*pTask);
|
||||
// }
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -844,8 +813,8 @@ int32_t tqStreamTaskProcessRunReq(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLead
|
|||
if (pTask != NULL) { // even in halt status, the data in inputQ must be processed
|
||||
char* p = NULL;
|
||||
if (streamTaskReadyToRun(pTask, &p)) {
|
||||
tqDebug("vgId:%d s-task:%s start to process block from inputQ, next checked ver:%" PRId64, vgId, pTask->id.idStr,
|
||||
pTask->chkInfo.nextProcessVer);
|
||||
tqDebug("vgId:%d s-task:%s status:%s start to process block from inputQ, next checked ver:%" PRId64, vgId, pTask->id.idStr,
|
||||
p, pTask->chkInfo.nextProcessVer);
|
||||
streamExecTask(pTask);
|
||||
} else {
|
||||
int8_t status = streamTaskSetSchedStatusInactive(pTask);
|
||||
|
@ -864,23 +833,31 @@ int32_t tqStreamTaskProcessRunReq(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLead
|
|||
|
||||
int32_t tqStartTaskCompleteCallback(SStreamMeta* pMeta) {
|
||||
STaskStartInfo* pStartInfo = &pMeta->startInfo;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
streamMetaWLock(pMeta);
|
||||
if (pStartInfo->taskStarting == 1) {
|
||||
tqDebug("vgId:%d already in start tasks procedure in other thread, restartCounter:%d, do nothing", vgId,
|
||||
pMeta->startInfo.restartCount);
|
||||
} else { // not in starting procedure
|
||||
if (pStartInfo->restartCount > 0) {
|
||||
bool allReady = streamMetaAllTasksReady(pMeta);
|
||||
|
||||
if ((pStartInfo->restartCount > 0) && (!allReady)) {
|
||||
// if all tasks are ready now, do NOT restart again, and reset the value of pStartInfo->restartCount
|
||||
pStartInfo->restartCount -= 1;
|
||||
tqDebug("vgId:%d role:%d need to restart all tasks again, restartCounter:%d", vgId, pMeta->role,
|
||||
pStartInfo->restartCount);
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
restartStreamTasks(pMeta, (pMeta->role == NODE_ROLE_LEADER));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
tqDebug("vgId:%d start all tasks completed in callbackFn", pMeta->vgId);
|
||||
if (pStartInfo->restartCount == 0) {
|
||||
tqDebug("vgId:%d start all tasks completed in callbackFn, restartCount is 0", pMeta->vgId);
|
||||
} else if (allReady) {
|
||||
pStartInfo->restartCount = 0;
|
||||
tqDebug("vgId:%d all tasks are ready, reset restartCounter 0, not restart tasks", vgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -922,7 +899,7 @@ int32_t tqStreamTaskProcessTaskPauseReq(SStreamMeta* pMeta, char* pMsg){
|
|||
}
|
||||
|
||||
tqDebug("s-task:%s receive pause msg from mnode", pTask->id.idStr);
|
||||
streamTaskPause(pTask, pMeta);
|
||||
streamTaskPause(pMeta, pTask);
|
||||
|
||||
SStreamTask* pHistoryTask = NULL;
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
|
@ -939,7 +916,7 @@ int32_t tqStreamTaskProcessTaskPauseReq(SStreamMeta* pMeta, char* pMsg){
|
|||
|
||||
tqDebug("s-task:%s fill-history task handle paused along with related stream task", pHistoryTask->id.idStr);
|
||||
|
||||
streamTaskPause(pHistoryTask, pMeta);
|
||||
streamTaskPause(pMeta, pHistoryTask);
|
||||
streamMetaReleaseTask(pMeta, pHistoryTask);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "cos.h"
|
||||
#include "functionMgt.h"
|
||||
#include "tsdb.h"
|
||||
#include "tsdbDataFileRW.h"
|
||||
#include "tsdbReadUtil.h"
|
||||
|
@ -894,19 +895,56 @@ static int32_t tsdbCacheLoadFromRaw(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArr
|
|||
}
|
||||
|
||||
int num_keys = TARRAY_SIZE(remainCols);
|
||||
int16_t *aCols = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
int16_t *slotIds = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
|
||||
int16_t *lastColIds = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
int16_t *lastSlotIds = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
int16_t *lastrowColIds = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
int16_t *lastrowSlotIds = taosMemoryMalloc(num_keys * sizeof(int16_t));
|
||||
SArray* lastTmpColArray = NULL;
|
||||
SArray* lastTmpIndexArray = NULL;
|
||||
SArray* lastrowTmpColArray = NULL;
|
||||
SArray* lastrowTmpIndexArray = NULL;
|
||||
|
||||
int lastIndex = 0;
|
||||
int lastrowIndex = 0;
|
||||
|
||||
for (int i = 0; i < num_keys; ++i) {
|
||||
SIdxKey *idxKey = taosArrayGet(remainCols, i);
|
||||
aCols[i] = idxKey->key.cid;
|
||||
slotIds[i] = pr->pSlotIds[idxKey->idx];
|
||||
if (idxKey->key.ltype == CACHESCAN_RETRIEVE_LAST >> 3) {
|
||||
if(NULL == lastTmpIndexArray) {
|
||||
lastTmpIndexArray = taosArrayInit(num_keys, sizeof(int32_t));
|
||||
}
|
||||
taosArrayPush(lastTmpIndexArray, &(i));
|
||||
lastColIds[lastIndex] = idxKey->key.cid;
|
||||
lastSlotIds[lastIndex] = pr->pSlotIds[idxKey->idx];
|
||||
lastIndex++;
|
||||
} else {
|
||||
if(NULL == lastrowTmpIndexArray) {
|
||||
lastrowTmpIndexArray = taosArrayInit(num_keys, sizeof(int32_t));
|
||||
}
|
||||
taosArrayPush(lastrowTmpIndexArray, &(i));
|
||||
lastrowColIds[lastrowIndex] = idxKey->key.cid;
|
||||
lastrowSlotIds[lastrowIndex] = pr->pSlotIds[idxKey->idx];
|
||||
lastrowIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ltype) {
|
||||
mergeLastCid(uid, pTsdb, &pTmpColArray, pr, aCols, num_keys, slotIds);
|
||||
} else {
|
||||
mergeLastRowCid(uid, pTsdb, &pTmpColArray, pr, aCols, num_keys, slotIds);
|
||||
pTmpColArray = taosArrayInit(lastIndex + lastrowIndex, sizeof(SLastCol));
|
||||
|
||||
if(lastTmpIndexArray != NULL) {
|
||||
mergeLastCid(uid, pTsdb, &lastTmpColArray, pr, lastColIds, lastIndex, lastSlotIds);
|
||||
for(int i = 0; i < taosArrayGetSize(lastTmpColArray); i++) {
|
||||
taosArrayInsert(pTmpColArray, *(int32_t*)taosArrayGet(lastTmpIndexArray, i), taosArrayGet(lastTmpColArray, i));
|
||||
}
|
||||
}
|
||||
|
||||
if(lastrowTmpIndexArray != NULL) {
|
||||
mergeLastCid(uid, pTsdb, &lastrowTmpColArray, pr, lastrowColIds, lastrowIndex, lastrowSlotIds);
|
||||
for(int i = 0; i < taosArrayGetSize(lastrowTmpColArray); i++) {
|
||||
taosArrayInsert(pTmpColArray, *(int32_t*)taosArrayGet(lastrowTmpIndexArray, i), taosArrayGet(lastrowTmpColArray, i));
|
||||
}
|
||||
}
|
||||
|
||||
SLRUCache *pCache = pTsdb->lruCache;
|
||||
|
@ -965,9 +1003,18 @@ static int32_t tsdbCacheLoadFromRaw(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArr
|
|||
rocksMayWrite(pTsdb, false, true, false);
|
||||
}
|
||||
|
||||
taosArrayDestroy(lastrowTmpIndexArray);
|
||||
taosArrayDestroy(lastrowTmpColArray);
|
||||
taosArrayDestroy(lastTmpIndexArray);
|
||||
taosArrayDestroy(lastTmpColArray);
|
||||
|
||||
taosMemoryFree(lastColIds);
|
||||
taosMemoryFree(lastSlotIds);
|
||||
taosMemoryFree(lastrowColIds);
|
||||
taosMemoryFree(lastrowSlotIds);
|
||||
|
||||
taosArrayDestroy(pTmpColArray);
|
||||
|
||||
taosMemoryFree(aCols);
|
||||
taosMemoryFree(slotIds);
|
||||
|
||||
return code;
|
||||
|
@ -1057,6 +1104,15 @@ int32_t tsdbCacheGetBatch(STsdb *pTsdb, tb_uid_t uid, SArray *pLastArray, SCache
|
|||
int16_t cid = ((int16_t *)TARRAY_DATA(pCidList))[i];
|
||||
|
||||
SLastKey *key = &(SLastKey){.ltype = ltype, .uid = uid, .cid = cid};
|
||||
// for select last_row, last case
|
||||
int32_t funcType = FUNCTION_TYPE_CACHE_LAST;
|
||||
if (pr->pFuncTypeList != NULL && taosArrayGetSize(pr->pFuncTypeList) > i) {
|
||||
funcType = ((int32_t *)TARRAY_DATA(pr->pFuncTypeList))[i];
|
||||
}
|
||||
if (((pr->type & CACHESCAN_RETRIEVE_LAST) == CACHESCAN_RETRIEVE_LAST) && FUNCTION_TYPE_CACHE_LAST_ROW == funcType) {
|
||||
int8_t tempType = CACHESCAN_RETRIEVE_LAST_ROW | (pr->type ^ CACHESCAN_RETRIEVE_LAST);
|
||||
key->ltype = (tempType & CACHESCAN_RETRIEVE_LAST) >> 3;
|
||||
}
|
||||
|
||||
LRUHandle *h = taosLRUCacheLookup(pCache, key, ROCKS_KEY_LEN);
|
||||
if (h) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "functionMgt.h"
|
||||
#include "taoserror.h"
|
||||
#include "tarray.h"
|
||||
#include "tcommon.h"
|
||||
|
@ -33,31 +34,69 @@ static void setFirstLastResColToNull(SColumnInfoData* pCol, int32_t row) {
|
|||
taosMemoryFree(buf);
|
||||
}
|
||||
|
||||
static void saveOneRowForLastRaw(SLastCol* pColVal, SCacheRowsReader* pReader, const int32_t slotId,
|
||||
SColumnInfoData* pColInfoData, int32_t numOfRows) {
|
||||
SColVal* pVal = &pColVal->colVal;
|
||||
|
||||
// allNullRow = false;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
if (!COL_VAL_IS_VALUE(&pColVal->colVal)) {
|
||||
colDataSetNULL(pColInfoData, numOfRows);
|
||||
} else {
|
||||
varDataSetLen(pReader->transferBuf[slotId], pVal->value.nData);
|
||||
|
||||
memcpy(varDataVal(pReader->transferBuf[slotId]), pVal->value.pData, pVal->value.nData);
|
||||
colDataSetVal(pColInfoData, numOfRows, pReader->transferBuf[slotId], false);
|
||||
}
|
||||
} else {
|
||||
colDataSetVal(pColInfoData, numOfRows, (const char*)&pVal->value.val, !COL_VAL_IS_VALUE(pVal));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* pReader, const int32_t* slotIds,
|
||||
const int32_t* dstSlotIds, void** pRes, const char* idStr) {
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
// bool allNullRow = true;
|
||||
|
||||
if (HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST)) {
|
||||
|
||||
uint64_t ts = TSKEY_MIN;
|
||||
SFirstLastRes* p = NULL;
|
||||
col_id_t colId = -1;
|
||||
|
||||
SArray* funcTypeBlockArray = taosArrayInit(pReader->numOfCols, sizeof(int32_t));
|
||||
for (int32_t i = 0; i < pReader->numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotIds[i]);
|
||||
int32_t funcType = FUNCTION_TYPE_CACHE_LAST;
|
||||
if (pReader->pFuncTypeList != NULL && taosArrayGetSize(pReader->pFuncTypeList) > i) {
|
||||
funcType = *(int32_t*)taosArrayGet(pReader->pFuncTypeList, i);
|
||||
}
|
||||
taosArrayInsert(funcTypeBlockArray, dstSlotIds[i], taosArrayGet(pReader->pFuncTypeList, i));
|
||||
|
||||
if (slotIds[i] == -1) {
|
||||
if (FUNCTION_TYPE_CACHE_LAST_ROW == funcType) {
|
||||
colDataSetNULL(pColInfoData, numOfRows);
|
||||
continue;
|
||||
}
|
||||
setFirstLastResColToNull(pColInfoData, numOfRows);
|
||||
continue;
|
||||
}
|
||||
int32_t slotId = slotIds[i];
|
||||
SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, i);
|
||||
colId = pColVal->colVal.cid;
|
||||
|
||||
if (FUNCTION_TYPE_CACHE_LAST_ROW == funcType) {
|
||||
saveOneRowForLastRaw(pColVal, pReader, slotId, pColInfoData, numOfRows);
|
||||
continue;
|
||||
}
|
||||
|
||||
p = (SFirstLastRes*)varDataVal(pRes[i]);
|
||||
|
||||
p->ts = pColVal->ts;
|
||||
ts = p->ts;
|
||||
p->isNull = !COL_VAL_IS_VALUE(&pColVal->colVal);
|
||||
// allNullRow = p->isNull & allNullRow;
|
||||
|
||||
if (!p->isNull) {
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
varDataSetLen(p->buf, pColVal->colVal.value.nData);
|
||||
|
@ -77,6 +116,13 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
}
|
||||
for (int32_t idx = 0; idx < taosArrayGetSize(pBlock->pDataBlock); ++idx) {
|
||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, idx);
|
||||
if (idx < funcTypeBlockArray->size) {
|
||||
int32_t funcType = *(int32_t*)taosArrayGet(funcTypeBlockArray, idx);
|
||||
if (FUNCTION_TYPE_CACHE_LAST_ROW == funcType) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCol->info.colId == PRIMARYKEY_TIMESTAMP_COL_ID && pCol->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
if (ts == TSKEY_MIN) {
|
||||
colDataSetNULL(pCol, numOfRows);
|
||||
|
@ -95,6 +141,7 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
|
||||
// pBlock->info.rows += allNullRow ? 0 : 1;
|
||||
++pBlock->info.rows;
|
||||
taosArrayDestroy(funcTypeBlockArray);
|
||||
} else if (HASTYPE(pReader->type, CACHESCAN_RETRIEVE_LAST_ROW)) {
|
||||
for (int32_t i = 0; i < pReader->numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotIds[i]);
|
||||
|
@ -105,21 +152,8 @@ static int32_t saveOneRow(SArray* pRow, SSDataBlock* pBlock, SCacheRowsReader* p
|
|||
continue;
|
||||
}
|
||||
SLastCol* pColVal = (SLastCol*)taosArrayGet(pRow, i);
|
||||
SColVal* pVal = &pColVal->colVal;
|
||||
|
||||
// allNullRow = false;
|
||||
if (IS_VAR_DATA_TYPE(pColVal->colVal.type)) {
|
||||
if (!COL_VAL_IS_VALUE(&pColVal->colVal)) {
|
||||
colDataSetNULL(pColInfoData, numOfRows);
|
||||
} else {
|
||||
varDataSetLen(pReader->transferBuf[slotId], pVal->value.nData);
|
||||
|
||||
memcpy(varDataVal(pReader->transferBuf[slotId]), pVal->value.pData, pVal->value.nData);
|
||||
colDataSetVal(pColInfoData, numOfRows, pReader->transferBuf[slotId], false);
|
||||
}
|
||||
} else {
|
||||
colDataSetVal(pColInfoData, numOfRows, (const char*)&pVal->value.val, !COL_VAL_IS_VALUE(pVal));
|
||||
}
|
||||
saveOneRowForLastRaw(pColVal, pReader, slotId, pColInfoData, numOfRows);
|
||||
}
|
||||
|
||||
// pBlock->info.rows += allNullRow ? 0 : 1;
|
||||
|
@ -175,7 +209,8 @@ int32_t tsdbReuseCacherowsReader(void* reader, void* pTableIdList, int32_t numOf
|
|||
}
|
||||
|
||||
int32_t tsdbCacherowsReaderOpen(void* pVnode, int32_t type, void* pTableIdList, int32_t numOfTables, int32_t numOfCols,
|
||||
SArray* pCidList, int32_t* pSlotIds, uint64_t suid, void** pReader, const char* idstr) {
|
||||
SArray* pCidList, int32_t* pSlotIds, uint64_t suid, void** pReader, const char* idstr,
|
||||
SArray* pFuncTypeList) {
|
||||
*pReader = NULL;
|
||||
SCacheRowsReader* p = taosMemoryCalloc(1, sizeof(SCacheRowsReader));
|
||||
if (p == NULL) {
|
||||
|
@ -190,6 +225,7 @@ int32_t tsdbCacherowsReaderOpen(void* pVnode, int32_t type, void* pTableIdList,
|
|||
p->numOfCols = numOfCols;
|
||||
p->pCidList = pCidList;
|
||||
p->pSlotIds = pSlotIds;
|
||||
p->pFuncTypeList = pFuncTypeList;
|
||||
|
||||
if (numOfTables == 0) {
|
||||
*pReader = p;
|
||||
|
@ -391,7 +427,10 @@ int32_t tsdbRetrieveCacheRows(void* pReader, SSDataBlock* pResBlock, const int32
|
|||
if (!COL_VAL_IS_VALUE(&p->colVal)) {
|
||||
hasNotNullRow = false;
|
||||
}
|
||||
continue;
|
||||
// For all of cols is null, the last null col of last table will be save
|
||||
if (i != pr->numOfTables - 1 || k != pr->numOfCols - 1 || hasRes) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
hasRes = true;
|
||||
|
|
|
@ -4100,9 +4100,9 @@ void tsdbReaderClose2(STsdbReader* pReader) {
|
|||
size_t numOfTables = tSimpleHashGetSize(pReader->status.pTableMap);
|
||||
if (pReader->status.pTableMap != NULL) {
|
||||
destroyAllBlockScanInfo(pReader->status.pTableMap);
|
||||
clearBlockScanInfoBuf(&pReader->blockInfoBuf);
|
||||
pReader->status.pTableMap = NULL;
|
||||
}
|
||||
clearBlockScanInfoBuf(&pReader->blockInfoBuf);
|
||||
|
||||
if (pReader->pFileReader != NULL) {
|
||||
tsdbDataFileReaderClose(&pReader->pFileReader);
|
||||
|
|
|
@ -348,6 +348,7 @@ typedef struct SCacheRowsReader {
|
|||
STsdbReadSnap* pReadSnap;
|
||||
char* idstr;
|
||||
int64_t lastTs;
|
||||
SArray* pFuncTypeList;
|
||||
} SCacheRowsReader;
|
||||
|
||||
int32_t tsdbCacheGetBatch(STsdb* pTsdb, tb_uid_t uid, SArray* pLastArray, SCacheRowsReader* pr, int8_t ltype);
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef struct SColMatchItem {
|
|||
int32_t dstSlotId;
|
||||
bool needOutput;
|
||||
SDataType dataType;
|
||||
int32_t funcType;
|
||||
} SColMatchItem;
|
||||
|
||||
typedef struct SColMatchInfo {
|
||||
|
|
|
@ -273,6 +273,7 @@ SSDataBlock* getAggregateResult(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
int32_t doAggregateImpl(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
for (int32_t k = 0; k < pOperator->exprSupp.numOfExprs; ++k) {
|
||||
if (functionNeedToExecute(&pCtx[k])) {
|
||||
// todo add a dummy funtion to avoid process check
|
||||
|
@ -280,7 +281,13 @@ int32_t doAggregateImpl(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx) {
|
|||
continue;
|
||||
}
|
||||
|
||||
int32_t code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
if ((&pCtx[k])->input.pData[0] == NULL) {
|
||||
code = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
|
||||
qError("%s aggregate function error happens, input data is NULL.", GET_TASKID(pOperator->pTaskInfo));
|
||||
} else {
|
||||
code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s aggregate function error happens, code: %s", GET_TASKID(pOperator->pTaskInfo), tstrerror(code));
|
||||
return code;
|
||||
|
@ -562,7 +569,12 @@ void applyAggFunctionOnPartialTuples(SExecTaskInfo* taskInfo, SqlFunctionCtx* pC
|
|||
} else {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (functionNeedToExecute(&pCtx[k]) && pCtx[k].fpSet.process != NULL) {
|
||||
code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
if ((&pCtx[k])->input.pData[0] == NULL) {
|
||||
code = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
|
||||
qError("%s apply functions error, input data is NULL.", GET_TASKID(taskInfo));
|
||||
} else {
|
||||
code = pCtx[k].fpSet.process(&pCtx[k]);
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s apply functions error, code: %s", GET_TASKID(taskInfo), tstrerror(code));
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "tmsg.h"
|
||||
|
||||
#include "executorInt.h"
|
||||
#include "functionMgt.h"
|
||||
#include "operator.h"
|
||||
#include "querytask.h"
|
||||
#include "tcompare.h"
|
||||
|
@ -44,6 +45,7 @@ typedef struct SCacheRowsScanInfo {
|
|||
SArray* pCidList;
|
||||
int32_t indexOfBufferedRes;
|
||||
STableListInfo* pTableList;
|
||||
SArray* pFuncTypeList;
|
||||
} SCacheRowsScanInfo;
|
||||
|
||||
static SSDataBlock* doScanCache(SOperatorInfo* pOperator);
|
||||
|
@ -105,9 +107,15 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe
|
|||
}
|
||||
|
||||
SArray* pCidList = taosArrayInit(numOfCols, sizeof(int16_t));
|
||||
pInfo->pFuncTypeList = taosArrayInit(taosArrayGetSize(pScanNode->pFuncTypes), sizeof(int32_t));
|
||||
taosArrayAddAll(pInfo->pFuncTypeList, pScanNode->pFuncTypes);
|
||||
|
||||
for (int i = 0; i < TARRAY_SIZE(pInfo->matchInfo.pList); ++i) {
|
||||
SColMatchItem* pColInfo = taosArrayGet(pInfo->matchInfo.pList, i);
|
||||
taosArrayPush(pCidList, &pColInfo->colId);
|
||||
if (pInfo->pFuncTypeList != NULL && taosArrayGetSize(pInfo->pFuncTypeList) > i) {
|
||||
pColInfo->funcType = *(int32_t*)taosArrayGet(pInfo->pFuncTypeList, i);
|
||||
}
|
||||
}
|
||||
pInfo->pCidList = pCidList;
|
||||
|
||||
|
@ -132,7 +140,7 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe
|
|||
uint64_t suid = tableListGetSuid(pTableListInfo);
|
||||
code = pInfo->readHandle.api.cacheFn.openReader(pInfo->readHandle.vnode, pInfo->retrieveType, pList, totalTables,
|
||||
taosArrayGetSize(pInfo->matchInfo.pList), pCidList, pInfo->pSlotIds,
|
||||
suid, &pInfo->pLastrowReader, pTaskInfo->id.str);
|
||||
suid, &pInfo->pLastrowReader, pTaskInfo->id.str, pScanNode->pFuncTypes);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
@ -274,7 +282,7 @@ SSDataBlock* doScanCache(SOperatorInfo* pOperator) {
|
|||
if (NULL == pInfo->pLastrowReader) {
|
||||
code = pInfo->readHandle.api.cacheFn.openReader(pInfo->readHandle.vnode, pInfo->retrieveType, pList, num,
|
||||
taosArrayGetSize(pInfo->matchInfo.pList), pInfo->pCidList, pInfo->pSlotIds, suid, &pInfo->pLastrowReader,
|
||||
pTaskInfo->id.str);
|
||||
pTaskInfo->id.str, pInfo->pFuncTypeList);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pInfo->currentGroupIndex += 1;
|
||||
taosArrayClear(pInfo->pUidList);
|
||||
|
@ -333,6 +341,7 @@ void destroyCacheScanOperator(void* param) {
|
|||
taosMemoryFree(pInfo->pSlotIds);
|
||||
taosMemoryFree(pInfo->pDstSlotIds);
|
||||
taosArrayDestroy(pInfo->pCidList);
|
||||
taosArrayDestroy(pInfo->pFuncTypeList);
|
||||
taosArrayDestroy(pInfo->pUidList);
|
||||
taosArrayDestroy(pInfo->matchInfo.pList);
|
||||
tableListDestroy(pInfo->pTableList);
|
||||
|
@ -405,6 +414,8 @@ int32_t removeRedundantTsCol(SLastRowScanPhysiNode* pScanNode, SColMatchInfo* pC
|
|||
SSlotDescNode* pDesc = (SSlotDescNode*)nodesListGetNode(pList, slotId);
|
||||
if (pDesc->dataType.type != TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
taosArrayPush(pMatchInfo, pColInfo);
|
||||
} else if (FUNCTION_TYPE_CACHE_LAST_ROW == pColInfo->funcType){
|
||||
taosArrayPush(pMatchInfo, pColInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1343,7 +1343,6 @@ int32_t extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNod
|
|||
c.colId = pColNode->colId;
|
||||
c.srcSlotId = pColNode->slotId;
|
||||
c.dstSlotId = pNode->slotId;
|
||||
c.dataType = pColNode->node.resType;
|
||||
taosArrayPush(pList, &c);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -621,6 +621,10 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo
|
|||
} else {
|
||||
pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot);
|
||||
}
|
||||
|
||||
if(pRes == NULL) {
|
||||
st = taosGetTimestampUs();
|
||||
}
|
||||
|
||||
int32_t rowsThreshold = pTaskInfo->pSubplan->rowsThreshold;
|
||||
if (!pTaskInfo->pSubplan->dynamicRowThreshold || 4096 <= pTaskInfo->pSubplan->rowsThreshold) {
|
||||
|
|
|
@ -2893,6 +2893,14 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->twAggSup = (STimeWindowAggSupp){
|
||||
.waterMark = pSessionNode->window.watermark,
|
||||
.calTrigger = pSessionNode->window.triggerType,
|
||||
.maxTs = INT64_MIN,
|
||||
.minTs = INT64_MAX,
|
||||
.deleteMark = getDeleteMark(&pSessionNode->window, 0),
|
||||
};
|
||||
|
||||
code = initStreamAggSupporter(&pInfo->streamAggSup, pExpSup, numOfCols, pSessionNode->gap,
|
||||
pTaskInfo->streamInfo.pState, 0, 0, &pTaskInfo->storageAPI.stateStore, pHandle,
|
||||
&pInfo->twAggSup, GET_TASKID(pTaskInfo), &pTaskInfo->storageAPI);
|
||||
|
@ -2900,13 +2908,6 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPh
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->twAggSup = (STimeWindowAggSupp){
|
||||
.waterMark = pSessionNode->window.watermark,
|
||||
.calTrigger = pSessionNode->window.triggerType,
|
||||
.maxTs = INT64_MIN,
|
||||
.minTs = INT64_MAX,
|
||||
};
|
||||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
|
||||
pInfo->primaryTsIndex = ((SColumnNode*)pSessionNode->window.pTspk)->slotId;
|
||||
|
@ -3775,6 +3776,7 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
.calTrigger = pStateNode->window.triggerType,
|
||||
.maxTs = INT64_MIN,
|
||||
.minTs = INT64_MAX,
|
||||
.deleteMark = getDeleteMark(&pStateNode->window, 0),
|
||||
};
|
||||
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
|
|
|
@ -258,13 +258,24 @@ static int32_t addDbPrecisonParam(SNodeList** pList, uint8_t precision) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static SDataType* getSDataTypeFromNode(SNode* pNode) {
|
||||
if (pNode == NULL) return NULL;
|
||||
if (nodesIsExprNode(pNode)) {
|
||||
return &((SExprNode*)pNode)->resType;
|
||||
} else if (QUERY_NODE_COLUMN_REF == pNode->type) {
|
||||
return &((SColumnRefNode*)pNode)->resType;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// There is only one parameter of numeric type, and the return type is parameter type
|
||||
static int32_t translateInOutNum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
} else if (IS_NULL_TYPE(paraType)) {
|
||||
|
@ -281,7 +292,7 @@ static int32_t translateInNumOutDou(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -296,8 +307,8 @@ static int32_t translateIn2NumOutDou(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if ((!IS_NUMERIC_TYPE(para1Type) && !IS_NULL_TYPE(para1Type)) ||
|
||||
(!IS_NUMERIC_TYPE(para2Type) && !IS_NULL_TYPE(para2Type))) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -313,12 +324,12 @@ static int32_t translateInOutStr(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SExprNode* pPara1 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (TSDB_DATA_TYPE_VARBINARY == pPara1->resType.type || !IS_STR_DATA_TYPE(pPara1->resType.type)) {
|
||||
SDataType* pRestType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
if (TSDB_DATA_TYPE_VARBINARY == pRestType->type || !IS_STR_DATA_TYPE(pRestType->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType){.bytes = pPara1->resType.bytes, .type = pPara1->resType.type};
|
||||
pFunc->node.resType = (SDataType){.bytes = pRestType->bytes, .type = pRestType->type};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -327,8 +338,8 @@ static int32_t translateTrimStr(SFunctionNode* pFunc, char* pErrBuf, int32_t len
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SExprNode* pPara1 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (TSDB_DATA_TYPE_VARBINARY == pPara1->resType.type || !IS_STR_DATA_TYPE(pPara1->resType.type)) {
|
||||
SDataType* pRestType1 = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
if (TSDB_DATA_TYPE_VARBINARY == pRestType1->type || !IS_STR_DATA_TYPE(pRestType1->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -342,8 +353,8 @@ static int32_t translateTrimStr(SFunctionNode* pFunc, char* pErrBuf, int32_t len
|
|||
numOfSpaces = countTrailingSpaces(pValue, isLtrim);
|
||||
}
|
||||
|
||||
int32_t resBytes = pPara1->resType.bytes - numOfSpaces;
|
||||
pFunc->node.resType = (SDataType){.bytes = resBytes, .type = pPara1->resType.type};
|
||||
int32_t resBytes = pRestType1->bytes - numOfSpaces;
|
||||
pFunc->node.resType = (SDataType){.bytes = resBytes, .type = pRestType1->type};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -361,13 +372,13 @@ static int32_t translateLogarithm(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type) && !IS_NULL_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (2 == numOfParams) {
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_NUMERIC_TYPE(para2Type) && !IS_NULL_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -390,7 +401,7 @@ static int32_t translateSum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -413,7 +424,7 @@ static int32_t translateAvgPartial(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -427,7 +438,7 @@ static int32_t translateAvgMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (TSDB_DATA_TYPE_BINARY != paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -442,7 +453,7 @@ static int32_t translateStddevPartial(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -456,7 +467,7 @@ static int32_t translateStddevMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (TSDB_DATA_TYPE_BINARY != paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -515,7 +526,7 @@ static int32_t translatePercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -524,7 +535,7 @@ static int32_t translatePercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
SValueNode* pValue = (SValueNode*)nodesListGetNode(pFunc->pParameterList, i);
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -577,15 +588,15 @@ static int32_t translateApercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type) || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param2
|
||||
if (3 == numOfParams) {
|
||||
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
|
||||
uint8_t para3Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type;
|
||||
if (!IS_STR_DATA_TYPE(para3Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -624,15 +635,15 @@ static int32_t translateApercentileImpl(SFunctionNode* pFunc, char* pErrBuf, int
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type) || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param2
|
||||
if (3 == numOfParams) {
|
||||
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
|
||||
uint8_t para3Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type;
|
||||
if (!IS_STR_DATA_TYPE(para3Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -654,14 +665,14 @@ static int32_t translateApercentileImpl(SFunctionNode* pFunc, char* pErrBuf, int
|
|||
if (3 != numOfParams && 2 != numOfParams) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (TSDB_DATA_TYPE_BINARY != para1Type || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (3 == numOfParams) {
|
||||
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
|
||||
uint8_t para3Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type;
|
||||
if (!IS_STR_DATA_TYPE(para3Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -715,8 +726,8 @@ static int32_t translateTopBot(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type) || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -739,7 +750,7 @@ static int32_t translateTopBot(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
pValue->notReserved = true;
|
||||
|
||||
// set result type
|
||||
SDataType* pType = &((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
||||
SDataType* pType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
pFunc->node.resType = (SDataType){.bytes = pType->bytes, .type = pType->type};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -769,7 +780,7 @@ static int32_t translateSpread(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_TIMESTAMP_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -783,7 +794,7 @@ static int32_t translateSpreadImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (isPartial) {
|
||||
if (!IS_NUMERIC_TYPE(paraType) && !IS_TIMESTAMP_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -859,7 +870,7 @@ static int32_t translateElapsedImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_TIMESTAMP_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -867,6 +878,7 @@ static int32_t translateElapsedImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
// param1
|
||||
if (2 == numOfParams) {
|
||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
|
||||
if (QUERY_NODE_VALUE != nodeType(pParamNode1)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -875,7 +887,7 @@ static int32_t translateElapsedImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -893,7 +905,7 @@ static int32_t translateElapsedImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (TSDB_DATA_TYPE_BINARY != paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -934,7 +946,7 @@ static int32_t translateLeastSQR(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
|||
pValue->notReserved = true;
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1128,15 +1140,15 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param1 ~ param3
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
!IS_INTEGER_TYPE(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type)) {
|
||||
if (getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
!IS_INTEGER_TYPE(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 3))->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1186,15 +1198,15 @@ static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param1 ~ param3
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
!IS_INTEGER_TYPE(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type)) {
|
||||
if (getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
!IS_INTEGER_TYPE(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 3))->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1240,7 +1252,7 @@ static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type != TSDB_DATA_TYPE_BINARY) {
|
||||
if (getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type != TSDB_DATA_TYPE_BINARY) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1305,7 +1317,7 @@ static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1328,9 +1340,9 @@ static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
pValue->notReserved = true;
|
||||
}
|
||||
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BIGINT &&
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_DOUBLE)) {
|
||||
if (getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_BIGINT &&
|
||||
getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_DOUBLE)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1345,7 +1357,7 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1371,14 +1383,14 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
pValue->notReserved = true;
|
||||
}
|
||||
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BIGINT &&
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_DOUBLE)) {
|
||||
if (getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type != TSDB_DATA_TYPE_BINARY ||
|
||||
(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_BIGINT &&
|
||||
getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type != TSDB_DATA_TYPE_DOUBLE)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (numOfParams == 4 &&
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||
getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 3))->type != TSDB_DATA_TYPE_BIGINT) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1406,7 +1418,7 @@ static int32_t translateCsum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t resType;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -1433,8 +1445,7 @@ static int32_t translateMavg(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
// param1
|
||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
if (QUERY_NODE_VALUE != nodeType(pParamNode1)) {
|
||||
|
@ -1448,7 +1459,7 @@ static int32_t translateMavg(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_NUMERIC_TYPE(colType) || !IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1462,8 +1473,8 @@ static int32_t translateSample(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
uint8_t colType = pCol->resType.type;
|
||||
SDataType* pSDataType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
uint8_t colType = pSDataType->type;
|
||||
|
||||
// param1
|
||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
|
@ -1478,14 +1489,14 @@ static int32_t translateSample(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// set result type
|
||||
if (IS_STR_DATA_TYPE(colType)) {
|
||||
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
||||
pFunc->node.resType = (SDataType){.bytes = pSDataType->bytes, .type = colType};
|
||||
} else {
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[colType].bytes, .type = colType};
|
||||
}
|
||||
|
@ -1499,8 +1510,8 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
uint8_t colType = pCol->resType.type;
|
||||
SDataType* pSDataType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
uint8_t colType = pSDataType->type;
|
||||
|
||||
// param1 & param2
|
||||
for (int32_t i = 1; i < numOfParams; ++i) {
|
||||
|
@ -1520,7 +1531,7 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1528,7 +1539,7 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
|
||||
// set result type
|
||||
if (IS_STR_DATA_TYPE(colType)) {
|
||||
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
||||
pFunc->node.resType = (SDataType){.bytes = pSDataType->bytes, .type = colType};
|
||||
} else {
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[colType].bytes, .type = colType};
|
||||
}
|
||||
|
@ -1540,7 +1551,7 @@ static int32_t translateDerivative(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
|
||||
// param1
|
||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
|
@ -1582,7 +1593,7 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -1600,7 +1611,7 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
}
|
||||
|
||||
static int32_t translateIrateImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) {
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (isPartial) {
|
||||
if (3 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -1647,14 +1658,14 @@ static int32_t translateInterp(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
}
|
||||
|
||||
uint8_t nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if ((!IS_NUMERIC_TYPE(paraType) && !IS_BOOLEAN_TYPE(paraType)) || QUERY_NODE_VALUE == nodeType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (2 == numOfParams) {
|
||||
nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, 1));
|
||||
paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType) || QUERY_NODE_VALUE != nodeType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1728,26 +1739,26 @@ static int32_t translateFirstLast(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
|
||||
for (int32_t i = 0; i < numOfParams; ++i) {
|
||||
uint8_t nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, i));
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (IS_NULL_TYPE(paraType) && QUERY_NODE_VALUE == nodeType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
}
|
||||
|
||||
pFunc->node.resType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
||||
pFunc->node.resType = *getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateFirstLastImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) {
|
||||
// first(col_list) will be rewritten as first(col)
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
uint8_t paraType = ((SExprNode*)pPara)->resType.type;
|
||||
int32_t paraBytes = ((SExprNode*)pPara)->resType.bytes;
|
||||
uint8_t paraType = getSDataTypeFromNode(pPara)->type;
|
||||
int32_t paraBytes = getSDataTypeFromNode(pPara)->bytes;
|
||||
if (isPartial) {
|
||||
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||
for (int32_t i = 0; i < numOfParams; ++i) {
|
||||
uint8_t nodeType = nodeType(nodesListGetNode(pFunc->pParameterList, i));
|
||||
uint8_t pType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t pType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (IS_NULL_TYPE(pType) && QUERY_NODE_VALUE == nodeType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1802,7 +1813,7 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t colType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_INTEGER_TYPE(colType) && !IS_FLOAT_TYPE(colType) && TSDB_DATA_TYPE_BOOL != colType &&
|
||||
!IS_TIMESTAMP_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -1810,7 +1821,7 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
|
||||
// param1
|
||||
if (numOfParams == 2) {
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1854,7 +1865,7 @@ static int32_t translateLength(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (!IS_STR_DATA_TYPE(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type)) {
|
||||
if (!IS_STR_DATA_TYPE(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
|
@ -1885,7 +1896,7 @@ static int32_t translateConcatImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
/* For concat/concat_ws function, if params have NCHAR type, promote the final result to NCHAR */
|
||||
for (int32_t i = 0; i < numOfParams; ++i) {
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, i);
|
||||
uint8_t paraType = ((SExprNode*)pPara)->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(pPara)->type;
|
||||
if (TSDB_DATA_TYPE_VARBINARY == paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -1900,8 +1911,8 @@ static int32_t translateConcatImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
|
||||
for (int32_t i = 0; i < numOfParams; ++i) {
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, i);
|
||||
uint8_t paraType = ((SExprNode*)pPara)->resType.type;
|
||||
int32_t paraBytes = ((SExprNode*)pPara)->resType.bytes;
|
||||
uint8_t paraType = getSDataTypeFromNode(pPara)->type;
|
||||
int32_t paraBytes = getSDataTypeFromNode(pPara)->bytes;
|
||||
int32_t factor = 1;
|
||||
if (IS_NULL_TYPE(paraType)) {
|
||||
resultType = TSDB_DATA_TYPE_VARCHAR;
|
||||
|
@ -2009,7 +2020,7 @@ static int32_t translateToIso8601(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
}
|
||||
|
||||
// param0
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_INTEGER_TYPE(paraType) && !IS_TIMESTAMP_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2050,13 +2061,13 @@ static int32_t translateToUnixtimestamp(SFunctionNode* pFunc, char* pErrBuf, int
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (para1Type == TSDB_DATA_TYPE_VARBINARY || !IS_STR_DATA_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (2 == numOfParams) {
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2087,8 +2098,8 @@ static int32_t translateToTimestamp(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
if (LIST_LENGTH(pFunc->pParameterList) != 2) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if (!IS_STR_DATA_TYPE(para1Type) || !IS_STR_DATA_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2101,8 +2112,8 @@ static int32_t translateToChar(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
if (LIST_LENGTH(pFunc->pParameterList) != 2) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
// currently only support to_char(timestamp, str)
|
||||
if (!IS_STR_DATA_TYPE(para2Type) || !IS_TIMESTAMP_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -2117,8 +2128,8 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if ((!IS_STR_DATA_TYPE(para1Type) && !IS_INTEGER_TYPE(para1Type) && !IS_TIMESTAMP_TYPE(para1Type)) ||
|
||||
!IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -2136,7 +2147,7 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
}
|
||||
|
||||
if (3 == numOfParams) {
|
||||
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
|
||||
uint8_t para3Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type;
|
||||
if (!IS_INTEGER_TYPE(para3Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2171,14 +2182,14 @@ static int32_t translateTimeDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t le
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < 2; ++i) {
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type;
|
||||
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
|
||||
if (!IS_STR_DATA_TYPE(paraType) && !IS_INTEGER_TYPE(paraType) && !IS_TIMESTAMP_TYPE(paraType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
}
|
||||
|
||||
if (3 == numOfParams) {
|
||||
if (!IS_INTEGER_TYPE(((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type)) {
|
||||
if (!IS_INTEGER_TYPE(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
}
|
||||
|
@ -2226,7 +2237,7 @@ static int32_t translateInStrOutGeom(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (!IS_STR_DATA_TYPE(para1Type) && !IS_NULL_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2241,7 +2252,7 @@ static int32_t translateInGeomOutStr(SFunctionNode* pFunc, char* pErrBuf, int32_
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
if (para1Type != TSDB_DATA_TYPE_GEOMETRY && !IS_NULL_TYPE(para1Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
@ -2256,8 +2267,8 @@ static int32_t translateIn2NumOutGeom(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if ((!IS_NUMERIC_TYPE(para1Type) && !IS_NULL_TYPE(para1Type)) ||
|
||||
(!IS_NUMERIC_TYPE(para2Type) && !IS_NULL_TYPE(para2Type))) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -2273,8 +2284,8 @@ static int32_t translateIn2GeomOutBool(SFunctionNode* pFunc, char* pErrBuf, int3
|
|||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
|
||||
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
|
||||
if ((para1Type != TSDB_DATA_TYPE_GEOMETRY && !IS_NULL_TYPE(para1Type)) ||
|
||||
(para2Type != TSDB_DATA_TYPE_GEOMETRY && !IS_NULL_TYPE(para2Type))) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
|
|
@ -832,6 +832,7 @@ int32_t minmaxFunctionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
return code;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t setNullSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t rowIndex) {
|
||||
if (pCtx->subsidiaries.num <= 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -847,6 +848,7 @@ int32_t setNullSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t setSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, const STuplePos* pTuplePos, int32_t rowIndex) {
|
||||
if (pCtx->subsidiaries.num <= 0) {
|
||||
|
@ -2125,7 +2127,7 @@ bool getGroupKeyFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
|||
}
|
||||
|
||||
static FORCE_INLINE TSKEY getRowPTs(SColumnInfoData* pTsColInfo, int32_t rowIndex) {
|
||||
if (pTsColInfo == NULL) {
|
||||
if (pTsColInfo == NULL || pTsColInfo->pData == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -241,6 +241,29 @@ static SVgroupsInfo* vgroupsInfoClone(const SVgroupsInfo* pSrc) {
|
|||
return pDst;
|
||||
}
|
||||
|
||||
static SArray* functParamClone(const SArray* pSrc) {
|
||||
int32_t len = sizeof(SArray) + pSrc->capacity * pSrc->elemSize;
|
||||
|
||||
SArray* pDst = taosArrayInit(pSrc->capacity, pSrc->elemSize);
|
||||
if (NULL == pDst) {
|
||||
return NULL;
|
||||
}
|
||||
for (int i = 0; i < TARRAY_SIZE(pSrc); ++i) {
|
||||
SFunctParam* pFunctParam = taosArrayGet(pSrc, i);
|
||||
SFunctParam* pNewFunctParam = (SFunctParam*)taosArrayPush(pDst, pFunctParam);
|
||||
|
||||
if (NULL == pNewFunctParam) {
|
||||
return NULL;
|
||||
}
|
||||
pNewFunctParam->type = pFunctParam->type;
|
||||
pNewFunctParam->pCol = taosMemoryCalloc(1, sizeof(SColumn));
|
||||
memcpy(pNewFunctParam->pCol, pFunctParam->pCol, sizeof(SColumn));
|
||||
}
|
||||
|
||||
return pDst;
|
||||
}
|
||||
|
||||
|
||||
static int32_t realTableNodeCopy(const SRealTableNode* pSrc, SRealTableNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(table, tableNodeCopy);
|
||||
CLONE_OBJECT_FIELD(pMeta, tableMetaClone);
|
||||
|
@ -425,6 +448,7 @@ static int32_t logicScanCopy(const SScanLogicNode* pSrc, SScanLogicNode* pDst) {
|
|||
COPY_SCALAR_FIELD(onlyMetaCtbIdx);
|
||||
COPY_SCALAR_FIELD(filesetDelimited);
|
||||
COPY_SCALAR_FIELD(isCountByTag);
|
||||
CLONE_OBJECT_FIELD(pFuncTypes, functParamClone);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1786,6 +1786,24 @@ static int32_t jsonToPhysiTagScanNode(const SJson* pJson, void* pObj) {
|
|||
static const char* jkLastRowScanPhysiPlanGroupTags = "GroupTags";
|
||||
static const char* jkLastRowScanPhysiPlanGroupSort = "GroupSort";
|
||||
static const char* jkLastRowScanPhysiPlanTargets = "Targets";
|
||||
static const char* jkLastRowScanPhysiPlanFuncType = "FuncType";
|
||||
static const char* jkLastRowScanPhysiPlanFuncTypes = "FuncTypes";
|
||||
|
||||
static int32_t funcTypeToJson(const void* pObj, SJson* pJson) {
|
||||
const int32_t* pNode = (const int32_t*)pObj;
|
||||
|
||||
int32_t code = tjsonAddIntegerToObject(pJson, jkLastRowScanPhysiPlanFuncType, *pNode);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t jsonToFuncType(const SJson* pJson, void* pObj) {
|
||||
int32_t* pNode = (int32_t*)pObj;
|
||||
|
||||
int32_t code = tjsonGetIntValue(pJson, jkLastRowScanPhysiPlanFuncType, pNode);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int32_t physiLastRowScanNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SLastRowScanPhysiNode* pNode = (const SLastRowScanPhysiNode*)pObj;
|
||||
|
@ -1800,6 +1818,9 @@ static int32_t physiLastRowScanNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodeListToJson(pJson, jkLastRowScanPhysiPlanTargets, pNode->pTargets);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddTArray(pJson, jkLastRowScanPhysiPlanFuncTypes, funcTypeToJson, pNode->pFuncTypes);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1817,6 +1838,9 @@ static int32_t jsonToPhysiLastRowScanNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeList(pJson, jkLastRowScanPhysiPlanTargets, &pNode->pTargets);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonToTArray(pJson, jkLastRowScanPhysiPlanFuncTypes, jsonToFuncType, &pNode->pFuncTypes, sizeof(int32_t));
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -194,3 +194,21 @@ bool nodesEqualNode(const SNode* a, const SNode* b) {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nodeListNodeEqual(const SNodeList* a, const SNode* b) {
|
||||
if (NULL == a || NULL == b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LIST_LENGTH(a) < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SNode *na;
|
||||
FOREACH(na, a) {
|
||||
if (nodesEqualNode(na, b)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -65,10 +65,14 @@ typedef int32_t (*FSetObject)(STlv* pTlv, void* pObj);
|
|||
|
||||
static int32_t nodeToMsg(const void* pObj, STlvEncoder* pEncoder);
|
||||
static int32_t nodeListToMsg(const void* pObj, STlvEncoder* pEncoder);
|
||||
static int32_t SArrayToMsg(const void* pObj, STlvEncoder* pEncoder);
|
||||
|
||||
static int32_t msgToNode(STlvDecoder* pDecoder, void** pObj);
|
||||
static int32_t msgToNodeFromTlv(STlv* pTlv, void** pObj);
|
||||
static int32_t msgToNodeList(STlvDecoder* pDecoder, void** pObj);
|
||||
static int32_t msgToNodeListFromTlv(STlv* pTlv, void** pObj);
|
||||
static int32_t msgToSArray(STlv* pTlv, void** pObj);
|
||||
|
||||
|
||||
static int32_t initTlvEncoder(STlvEncoder* pEncoder) {
|
||||
pEncoder->allocSize = NODES_MSG_DEFAULT_LEN;
|
||||
|
@ -2053,7 +2057,8 @@ enum {
|
|||
PHY_LAST_ROW_SCAN_CODE_GROUP_TAGS,
|
||||
PHY_LAST_ROW_SCAN_CODE_GROUP_SORT,
|
||||
PHY_LAST_ROW_SCAN_CODE_IGNULL,
|
||||
PHY_LAST_ROW_SCAN_CODE_TARGETS
|
||||
PHY_LAST_ROW_SCAN_CODE_TARGETS,
|
||||
PHY_LAST_ROW_SCAN_CODE_FUNCTYPES
|
||||
};
|
||||
|
||||
static int32_t physiLastRowScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
|
@ -2072,6 +2077,9 @@ static int32_t physiLastRowScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeObj(pEncoder, PHY_LAST_ROW_SCAN_CODE_TARGETS, nodeListToMsg, pNode->pTargets);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeObj(pEncoder, PHY_LAST_ROW_SCAN_CODE_FUNCTYPES, SArrayToMsg, pNode->pFuncTypes);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2098,6 +2106,10 @@ static int32_t msgToPhysiLastRowScanNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
case PHY_LAST_ROW_SCAN_CODE_TARGETS:
|
||||
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pTargets);
|
||||
break;
|
||||
case PHY_LAST_ROW_SCAN_CODE_FUNCTYPES:
|
||||
code = msgToSArray(pTlv, (void**)&pNode->pFuncTypes);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -4391,6 +4403,31 @@ static int32_t nodeListToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
enum {
|
||||
SARRAY_CODE_CAPACITY = 1,
|
||||
SARRAY_CODE_ELEMSIZE,
|
||||
SARRAY_CODE_SIZE,
|
||||
SARRAY_CODE_PDATA
|
||||
};
|
||||
|
||||
static int32_t SArrayToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||
const SArray* pArray = (const SArray*)pObj;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI32(pEncoder, SARRAY_CODE_CAPACITY, pArray->capacity);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI32(pEncoder, SARRAY_CODE_ELEMSIZE, pArray->elemSize);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeI32(pEncoder, SARRAY_CODE_SIZE, pArray->size);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code && pArray->capacity * pArray->elemSize > 0 && pArray->pData != NULL) {
|
||||
code = tlvEncodeBinary(pEncoder, SARRAY_CODE_PDATA, pArray->pData, pArray->capacity * pArray->elemSize);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
static int32_t msgToNodeList(STlvDecoder* pDecoder, void** pObj) {
|
||||
SNodeList* pList = nodesMakeList();
|
||||
|
@ -4411,6 +4448,67 @@ static int32_t msgToNodeList(STlvDecoder* pDecoder, void** pObj) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t msgToSArray(STlv* pTlv, void** pObj){
|
||||
SArray* pArray = NULL;
|
||||
uint32_t capacity = 0;
|
||||
uint32_t elemSize = 0;
|
||||
uint32_t actualSize;
|
||||
int32_t decodeFieldNum = 0;;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
STlvDecoder decoder = {.bufSize = pTlv->len, .offset = 0, .pBuf = pTlv->value};
|
||||
STlv* pTlvTemp = NULL;
|
||||
STlv* pDataTlv = NULL;
|
||||
|
||||
tlvForEach(&decoder, pTlvTemp, code) {
|
||||
switch (pTlvTemp->type) {
|
||||
case SARRAY_CODE_CAPACITY:
|
||||
code = tlvDecodeI32(pTlvTemp, &capacity);
|
||||
break;
|
||||
case SARRAY_CODE_ELEMSIZE:
|
||||
code = tlvDecodeI32(pTlvTemp, &elemSize);
|
||||
break;
|
||||
case SARRAY_CODE_SIZE:
|
||||
code = tlvDecodeI32(pTlvTemp, &actualSize);
|
||||
break;
|
||||
case SARRAY_CODE_PDATA:
|
||||
if (decodeFieldNum < 3) {
|
||||
pDataTlv = pTlvTemp;
|
||||
break;
|
||||
}
|
||||
pArray = taosArrayInit(capacity, elemSize);
|
||||
if (NULL == pArray) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pArray->size = actualSize;
|
||||
if (TSDB_CODE_SUCCESS != code || pTlvTemp == NULL) {
|
||||
taosArrayDestroy(pArray);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
code = tlvDecodeBinary(pTlvTemp, pArray->pData);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
decodeFieldNum++;
|
||||
}
|
||||
|
||||
if (pDataTlv != NULL) {
|
||||
pArray = taosArrayInit(capacity, elemSize);
|
||||
if (NULL == pArray) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pArray->size = actualSize;
|
||||
if (TSDB_CODE_SUCCESS != code || pTlvTemp == NULL) {
|
||||
taosArrayDestroy(pArray);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
code = tlvDecodeBinary(pDataTlv, pArray->pData);
|
||||
}
|
||||
*pObj = pArray;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
static int32_t msgToNodeListFromTlv(STlv* pTlv, void** pObj) {
|
||||
STlvDecoder decoder = {.bufSize = pTlv->len, .offset = 0, .pBuf = pTlv->value};
|
||||
return msgToNodeList(&decoder, pObj);
|
||||
|
|
|
@ -295,7 +295,7 @@ SNode* nodesMakeNode(ENodeType type) {
|
|||
case QUERY_NODE_LEFT_VALUE:
|
||||
return makeNode(type, sizeof(SLeftValueNode));
|
||||
case QUERY_NODE_COLUMN_REF:
|
||||
return makeNode(type, sizeof(SColumnDefNode));
|
||||
return makeNode(type, sizeof(SColumnRefNode));
|
||||
case QUERY_NODE_WHEN_THEN:
|
||||
return makeNode(type, sizeof(SWhenThenNode));
|
||||
case QUERY_NODE_CASE_WHEN:
|
||||
|
@ -676,6 +676,8 @@ static void destroyTableCfg(STableCfg* pCfg) {
|
|||
|
||||
static void destroySmaIndex(void* pIndex) { taosMemoryFree(((STableIndexInfo*)pIndex)->expr); }
|
||||
|
||||
static void destroyFuncParam(void* pValue) { taosMemoryFree(((SFunctParam*)pValue)->pCol); }
|
||||
|
||||
static void destroyHintValue(EHintOption option, void* value) {
|
||||
switch (option) {
|
||||
default:
|
||||
|
@ -1177,6 +1179,7 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
nodesDestroyList(pLogicNode->pGroupTags);
|
||||
nodesDestroyList(pLogicNode->pTags);
|
||||
nodesDestroyNode(pLogicNode->pSubtable);
|
||||
taosArrayDestroyEx(pLogicNode->pFuncTypes, destroyFuncParam);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_LOGIC_PLAN_JOIN: {
|
||||
|
@ -1304,6 +1307,7 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
destroyScanPhysiNode((SScanPhysiNode*)pNode);
|
||||
nodesDestroyList(pPhyNode->pGroupTags);
|
||||
nodesDestroyList(pPhyNode->pTargets);
|
||||
taosArrayDestroy(pPhyNode->pFuncTypes);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
|
||||
|
@ -2115,6 +2119,7 @@ static EDealRes collectFuncs(SNode* pNode, void* pContext) {
|
|||
FOREACH(pn, pCxt->pFuncs) {
|
||||
if (nodesEqualNode(pn, pNode)) {
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFound) {
|
||||
|
@ -2137,6 +2142,20 @@ static int32_t funcNodeEqual(const void* pLeft, const void* pRight, size_t len)
|
|||
return nodesEqualNode(*(const SNode**)pLeft, *(const SNode**)pRight) ? 0 : 1;
|
||||
}
|
||||
|
||||
int32_t nodesCollectSelectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList* pFuncs) {
|
||||
if (NULL == pSelect || NULL == pFuncs) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
SCollectFuncsCxt cxt = {.errCode = TSDB_CODE_SUCCESS,
|
||||
.classifier = classifier,
|
||||
.tableAlias = tableAlias,
|
||||
.pFuncs = pFuncs};
|
||||
|
||||
nodesWalkSelectStmt(pSelect, clause, collectFuncs, &cxt);
|
||||
return cxt.errCode;
|
||||
}
|
||||
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList** pFuncs) {
|
||||
if (NULL == pSelect || NULL == pFuncs) {
|
||||
return TSDB_CODE_FAILED;
|
||||
|
|
|
@ -1088,17 +1088,16 @@ static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** p
|
|||
FOREACH(pNode, pProjectionList) {
|
||||
SExprNode* pExpr = (SExprNode*)pNode;
|
||||
if (0 == strcmp((*pCol)->colName, pExpr->userAlias)) {
|
||||
SColumnRefNode* pColRef = (SColumnRefNode*)nodesMakeNode(QUERY_NODE_COLUMN_REF);
|
||||
if (NULL == pColRef) {
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
strcpy(pColRef->colName, pExpr->aliasName);
|
||||
nodesDestroyNode(*(SNode**)pCol);
|
||||
*(SNode**)pCol = (SNode*)pColRef;
|
||||
*pFound = true;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
SNode* pNew = nodesCloneNode(pNode);
|
||||
if (NULL == pNew) {
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
nodesDestroyNode(*(SNode**)pCol);
|
||||
*(SNode**)pCol = (SNode*)pNew;
|
||||
*pFound = true;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
}
|
||||
*pFound = false;
|
||||
return DEAL_RES_CONTINUE;
|
||||
|
@ -2744,6 +2743,31 @@ static EDealRes doCheckAggColCoexist(SNode** pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t checkIsEmptyResult(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (pSelect->timeRange.skey > pSelect->timeRange.ekey
|
||||
&& !pSelect->hasCountFunc) {
|
||||
pSelect->isEmptyResult = true;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t resetSelectFuncNumWithoutDup(SSelectStmt* pSelect) {
|
||||
if (pSelect->selectFuncNum <= 1) return TSDB_CODE_SUCCESS;
|
||||
pSelect->selectFuncNum = 0;
|
||||
SNodeList* pNodeList = nodesMakeList();
|
||||
int32_t code = nodesCollectSelectFuncs(pSelect, SQL_CLAUSE_FROM, NULL, fmIsSelectFunc, pNodeList);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyList(pNodeList);
|
||||
return code;
|
||||
}
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pNodeList) {
|
||||
pSelect->selectFuncNum = calcSelectFuncNum((SFunctionNode*)pNode, pSelect->selectFuncNum);
|
||||
}
|
||||
nodesDestroyList(pNodeList);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (NULL != pSelect->pGroupByList || NULL != pSelect->pWindow ||
|
||||
(!pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc && !pSelect->hasInterpFunc)) {
|
||||
|
@ -2757,7 +2781,8 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
|||
if (!pSelect->isDistinct) {
|
||||
nodesRewriteExprs(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
|
||||
}
|
||||
if (1 == pSelect->selectFuncNum && !pSelect->hasOtherVectorFunc) {
|
||||
if (((!cxt.existCol && 0 < pSelect->selectFuncNum) || (cxt.existCol && 1 == pSelect->selectFuncNum) )
|
||||
&& !pSelect->hasOtherVectorFunc) {
|
||||
return rewriteColsToSelectValFunc(pCxt, pSelect);
|
||||
}
|
||||
if (cxt.existCol) {
|
||||
|
@ -3454,13 +3479,7 @@ static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pPro
|
|||
} else if (0 == pos || pos > LIST_LENGTH(pProjectionList)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT);
|
||||
} else {
|
||||
SColumnRefNode* pCol = (SColumnRefNode*)nodesMakeNode(QUERY_NODE_COLUMN_REF);
|
||||
if (NULL == pCol) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
strcpy(pCol->colName, ((SExprNode*)nodesListGetNode(pProjectionList, pos - 1))->aliasName);
|
||||
((SOrderByExprNode*)pNode)->pExpr = (SNode*)pCol;
|
||||
nodesDestroyNode(pExpr);
|
||||
// No longer using SColumnRefNode, processing in replaceOrderByAliasImpl function
|
||||
}
|
||||
} else {
|
||||
*pOther = true;
|
||||
|
@ -4405,9 +4424,6 @@ static int32_t translateWhere(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = getQueryTimeRange(pCxt, pSelect->pWhere, &pSelect->timeRange);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code && pSelect->timeRange.skey > pSelect->timeRange.ekey) {
|
||||
pSelect->isEmptyResult = true;
|
||||
}
|
||||
if (pSelect->pWhere != NULL) {
|
||||
setTableVgroupsFromEqualTbnameCond(pCxt, pSelect);
|
||||
}
|
||||
|
@ -4483,12 +4499,13 @@ typedef struct SReplaceOrderByAliasCxt {
|
|||
|
||||
static EDealRes replaceOrderByAliasImpl(SNode** pNode, void* pContext) {
|
||||
SReplaceOrderByAliasCxt* pCxt = pContext;
|
||||
if (QUERY_NODE_COLUMN_REF == nodeType(*pNode)) {
|
||||
SNodeList* pProjectionList = pCxt->pProjectionList;
|
||||
SNode* pProject = NULL;
|
||||
SNodeList* pProjectionList = pCxt->pProjectionList;
|
||||
SNode* pProject = NULL;
|
||||
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||
FOREACH(pProject, pProjectionList) {
|
||||
SExprNode* pExpr = (SExprNode*)pProject;
|
||||
if (0 == strcmp(((SColumnRefNode*)*pNode)->colName, pExpr->aliasName)) {
|
||||
if (0 == strcmp(((SColumnRefNode*)*pNode)->colName, pExpr->userAlias)
|
||||
&& nodeType(*pNode) == nodeType(pProject)) {
|
||||
SNode* pNew = nodesCloneNode(pProject);
|
||||
if (NULL == pNew) {
|
||||
pCxt->pTranslateCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -4500,7 +4517,29 @@ static EDealRes replaceOrderByAliasImpl(SNode** pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
}
|
||||
} else if (QUERY_NODE_ORDER_BY_EXPR == nodeType(*pNode)) {
|
||||
STranslateContext* pTransCxt = pCxt->pTranslateCxt;
|
||||
SNode* pExpr = ((SOrderByExprNode*)*pNode)->pExpr;
|
||||
if (QUERY_NODE_VALUE == nodeType(pExpr)) {
|
||||
SValueNode* pVal = (SValueNode*)pExpr;
|
||||
if (DEAL_RES_ERROR == translateValue(pTransCxt, pVal)) {
|
||||
return pTransCxt->errCode;
|
||||
}
|
||||
int32_t pos = getPositionValue(pVal);
|
||||
if ( 0 < pos && pos <= LIST_LENGTH(pProjectionList)) {
|
||||
SNode* pNew = nodesCloneNode(nodesListGetNode(pProjectionList, pos - 1));
|
||||
if (NULL == pNew) {
|
||||
pCxt->pTranslateCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
((SExprNode*)pNew)->orderAlias = true;
|
||||
((SOrderByExprNode*)*pNode)->pExpr = pNew;
|
||||
nodesDestroyNode(pExpr);
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -4573,6 +4612,10 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
|
|||
code = translateOrderBy(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkIsEmptyResult(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
resetSelectFuncNumWithoutDup(pSelect);
|
||||
code = checkAggColCoexist(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
|
@ -413,6 +413,28 @@ TEST_F(ParserSelectTest, semanticCheck) {
|
|||
|
||||
run("SELECT c1 FROM t1 order by COUNT(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
|
||||
run("SELECT COUNT(*) FROM t1 order by COUNT(*)");
|
||||
|
||||
run("SELECT COUNT(*) FROM t1 order by last(c2)");
|
||||
|
||||
run("SELECT c1 FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT ts FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT c2 FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT * FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT last(ts) FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT last(ts), ts, c1 FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT ts, last(ts) FROM t1 order by last(ts)");
|
||||
|
||||
run("SELECT first(ts), c2 FROM t1 order by last(c1)", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
|
||||
run("SELECT c1 FROM t1 order by concat(c2, 'abc')");
|
||||
|
||||
// TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
|
||||
run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION);
|
||||
|
||||
|
|
|
@ -2501,17 +2501,30 @@ static bool lastRowScanOptCheckColNum(int32_t lastColNum, col_id_t lastColId,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool lastRowScanOptCheckFuncList(SLogicNode* pNode, bool* hasOtherFunc) {
|
||||
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))))) &&
|
||||
FUNCTION_TYPE_SELECT_VALUE != funcType && FUNCTION_TYPE_GROUP_KEY != funcType) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool lastRowScanOptCheckFuncList(SLogicNode* pNode, int8_t cacheLastModel, bool* hasOtherFunc) {
|
||||
bool hasNonPKSelectFunc = false;
|
||||
SNode* pFunc = NULL;
|
||||
int32_t lastColNum = 0, selectNonPKColNum = 0;
|
||||
col_id_t lastColId = -1, selectNonPKColId = -1;
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(((SAggLogicNode*)pNode)->node.pChildren, 0);
|
||||
uint32_t needSplitFuncCount = 0;
|
||||
FOREACH(pFunc, ((SAggLogicNode*)pNode)->pAggFuncs) {
|
||||
SFunctionNode* pAggFunc = (SFunctionNode*)pFunc;
|
||||
SNode* pParam = nodesListGetNode(pAggFunc->pParameterList, 0);
|
||||
if (FUNCTION_TYPE_LAST == pAggFunc->funcType) {
|
||||
SNode* pPar = nodesListGetNode(pAggFunc->pParameterList, 0);
|
||||
if (QUERY_NODE_COLUMN == nodeType(pPar)) {
|
||||
SColumnNode* pCol = (SColumnNode*)pPar;
|
||||
if (QUERY_NODE_COLUMN == nodeType(pParam)) {
|
||||
SColumnNode* pCol = (SColumnNode*)pParam;
|
||||
if (pCol->colType != COLUMN_TYPE_COLUMN) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2520,13 +2533,18 @@ static bool lastRowScanOptCheckFuncList(SLogicNode* pNode, bool* hasOtherFunc) {
|
|||
lastColNum++;
|
||||
}
|
||||
}
|
||||
if (QUERY_NODE_VALUE == nodeType(nodesListGetNode(pAggFunc->pParameterList, 0))) {
|
||||
else if (QUERY_NODE_VALUE == nodeType(pParam) || QUERY_NODE_OPERATOR == nodeType(pParam)) {
|
||||
needSplitFuncCount++;
|
||||
*hasOtherFunc = true;
|
||||
}
|
||||
if (!lastRowScanOptCheckColNum(lastColNum, lastColId, selectNonPKColNum, selectNonPKColId)) {
|
||||
return false;
|
||||
}
|
||||
if (!lastRowScanOptCheckColNum(lastColNum, lastColId, selectNonPKColNum, selectNonPKColId))
|
||||
return false;
|
||||
if (TSDB_CACHE_MODEL_LAST_ROW == cacheLastModel) {
|
||||
needSplitFuncCount++;
|
||||
*hasOtherFunc = true;
|
||||
}
|
||||
} else if (FUNCTION_TYPE_SELECT_VALUE == pAggFunc->funcType) {
|
||||
SNode* pParam = nodesListGetNode(pAggFunc->pParameterList, 0);
|
||||
if (QUERY_NODE_COLUMN == nodeType(pParam)) {
|
||||
SColumnNode* pCol = (SColumnNode*)pParam;
|
||||
if (COLUMN_TYPE_COLUMN == pCol->colType && PRIMARYKEY_TIMESTAMP_COL_ID != pCol->colId) {
|
||||
|
@ -2548,15 +2566,21 @@ static bool lastRowScanOptCheckFuncList(SLogicNode* pNode, bool* hasOtherFunc) {
|
|||
}
|
||||
} else if (FUNCTION_TYPE_LAST_ROW != pAggFunc->funcType) {
|
||||
*hasOtherFunc = true;
|
||||
needSplitFuncCount++;
|
||||
} else if (FUNCTION_TYPE_LAST_ROW == pAggFunc->funcType && TSDB_CACHE_MODEL_LAST_VALUE == cacheLastModel) {
|
||||
*hasOtherFunc = true;
|
||||
needSplitFuncCount++;
|
||||
}
|
||||
}
|
||||
if (needSplitFuncCount >= ((SAggLogicNode*)pNode)->pAggFuncs->length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool lastRowScanOptCheckLastCache(SAggLogicNode* pAgg, SScanLogicNode* pScan) {
|
||||
// Only one of LAST and LASTROW can appear
|
||||
if (pAgg->hasLastRow == pAgg->hasLast || (!pAgg->hasLast && !pAgg->hasLastRow) || NULL != pAgg->pGroupKeys || NULL != pScan->node.pConditions ||
|
||||
if ((pAgg->hasLastRow == pAgg->hasLast && !pAgg->hasLastRow) || (!pAgg->hasLast && !pAgg->hasLastRow) || NULL != pAgg->pGroupKeys || NULL != pScan->node.pConditions ||
|
||||
!hasSuitableCache(pScan->cacheLastMode, pAgg->hasLastRow, pAgg->hasLast) ||
|
||||
IS_TSWINDOW_SPECIFIED(pScan->scanRange)) {
|
||||
return false;
|
||||
|
@ -2578,7 +2602,7 @@ static bool lastRowScanOptMayBeOptimized(SLogicNode* pNode) {
|
|||
}
|
||||
|
||||
bool hasOtherFunc = false;
|
||||
if (!lastRowScanOptCheckFuncList(pNode, &hasOtherFunc)) {
|
||||
if (!lastRowScanOptCheckFuncList(pNode, pScan->cacheLastMode, &hasOtherFunc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2593,6 +2617,7 @@ typedef struct SLastRowScanOptSetColDataTypeCxt {
|
|||
bool doAgg;
|
||||
SNodeList* pLastCols;
|
||||
SNodeList* pOtherCols;
|
||||
int32_t funcType;
|
||||
} SLastRowScanOptSetColDataTypeCxt;
|
||||
|
||||
static EDealRes lastRowScanOptSetColDataType(SNode* pNode, void* pContext) {
|
||||
|
@ -2615,7 +2640,7 @@ static EDealRes lastRowScanOptSetColDataType(SNode* pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static void lastRowScanOptSetLastTargets(SNodeList* pTargets, SNodeList* pLastCols, bool erase) {
|
||||
static void lastRowScanOptSetLastTargets(SNodeList* pTargets, SNodeList* pLastCols, SNodeList* pLastRowCols, bool erase) {
|
||||
SNode* pTarget = NULL;
|
||||
WHERE_EACH(pTarget, pTargets) {
|
||||
bool found = false;
|
||||
|
@ -2627,6 +2652,10 @@ static void lastRowScanOptSetLastTargets(SNodeList* pTargets, SNodeList* pLastCo
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!found && nodeListNodeEqual(pLastRowCols, pTarget)) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found && erase) {
|
||||
ERASE_NODE(pTargets);
|
||||
continue;
|
||||
|
@ -2635,7 +2664,7 @@ static void lastRowScanOptSetLastTargets(SNodeList* pTargets, SNodeList* pLastCo
|
|||
}
|
||||
}
|
||||
|
||||
static void lastRowScanOptRemoveUslessTargets(SNodeList* pTargets, SNodeList* pList1, SNodeList* pList2) {
|
||||
static void lastRowScanOptRemoveUslessTargets(SNodeList* pTargets, SNodeList* pList1, SNodeList* pList2, SNodeList* pList3) {
|
||||
SNode* pTarget = NULL;
|
||||
WHERE_EACH(pTarget, pTargets) {
|
||||
bool found = false;
|
||||
|
@ -2654,6 +2683,11 @@ static void lastRowScanOptRemoveUslessTargets(SNodeList* pTargets, SNodeList* pL
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && nodeListNodeEqual(pList3, pTarget)) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ERASE_NODE(pTargets);
|
||||
continue;
|
||||
|
@ -2662,6 +2696,33 @@ static void lastRowScanOptRemoveUslessTargets(SNodeList* pTargets, SNodeList* pL
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t lastRowScanBuildFuncTypes(SScanLogicNode* pScan, SColumnNode* pColNode, int32_t funcType) {
|
||||
SFunctParam* pFuncTypeParam = taosMemoryCalloc(1, sizeof(SFunctParam));
|
||||
if (NULL == pFuncTypeParam) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pFuncTypeParam->type = funcType;
|
||||
if (NULL == pScan->pFuncTypes) {
|
||||
pScan->pFuncTypes = taosArrayInit(pScan->pScanCols->length, sizeof(SFunctParam));
|
||||
if (NULL == pScan->pFuncTypes) {
|
||||
taosMemoryFree(pFuncTypeParam);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
pFuncTypeParam->pCol = taosMemoryCalloc(1, sizeof(SColumn));
|
||||
if (NULL == pFuncTypeParam->pCol) {
|
||||
taosMemoryFree(pFuncTypeParam);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pFuncTypeParam->pCol->colId = pColNode->colId;
|
||||
strcpy(pFuncTypeParam->pCol->name, pColNode->colName);
|
||||
taosArrayPush(pScan->pFuncTypes, pFuncTypeParam);
|
||||
|
||||
taosMemoryFree(pFuncTypeParam);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||
SAggLogicNode* pAgg = (SAggLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, lastRowScanOptMayBeOptimized);
|
||||
|
||||
|
@ -2673,10 +2734,16 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
SNode* pNode = NULL;
|
||||
SColumnNode* pPKTsCol = NULL;
|
||||
SColumnNode* pNonPKCol = NULL;
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
|
||||
pScan->scanType = SCAN_TYPE_LAST_ROW;
|
||||
pScan->igLastNull = pAgg->hasLast ? true : false;
|
||||
SArray* isDuplicateCol = taosArrayInit(pScan->pScanCols->length, sizeof(bool));
|
||||
SNodeList* pLastRowCols = NULL;
|
||||
|
||||
FOREACH(pNode, pAgg->pAggFuncs) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
int32_t funcType = pFunc->funcType;
|
||||
SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (FUNCTION_TYPE_LAST_ROW == funcType || FUNCTION_TYPE_LAST == funcType) {
|
||||
int32_t len = snprintf(pFunc->functionName, sizeof(pFunc->functionName),
|
||||
FUNCTION_TYPE_LAST_ROW == funcType ? "_cache_last_row" : "_cache_last");
|
||||
|
@ -2686,6 +2753,61 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
nodesClearList(cxt.pLastCols);
|
||||
return code;
|
||||
}
|
||||
cxt.funcType = pFunc->funcType;
|
||||
// add duplicate cols which be removed for both last_row, last
|
||||
if (pAgg->hasLast && pAgg->hasLastRow) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pParamNode)) {
|
||||
SNode* pColNode = NULL;
|
||||
int i = 0;
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FUNCTION_TYPE_LAST == funcType) {
|
||||
nodesWalkExpr(nodesListGetNode(pFunc->pParameterList, 0), lastRowScanOptSetColDataType, &cxt);
|
||||
nodesListErase(pFunc->pParameterList, nodesListGetCell(pFunc->pParameterList, 1));
|
||||
|
@ -2707,15 +2829,13 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
}
|
||||
}
|
||||
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
|
||||
pScan->scanType = SCAN_TYPE_LAST_ROW;
|
||||
pScan->igLastNull = pAgg->hasLast ? true : false;
|
||||
if (NULL != cxt.pLastCols) {
|
||||
cxt.doAgg = false;
|
||||
lastRowScanOptSetLastTargets(pScan->pScanCols, cxt.pLastCols, true);
|
||||
cxt.funcType = FUNCTION_TYPE_CACHE_LAST;
|
||||
lastRowScanOptSetLastTargets(pScan->pScanCols, cxt.pLastCols, pLastRowCols, true);
|
||||
nodesWalkExprs(pScan->pScanPseudoCols, lastRowScanOptSetColDataType, &cxt);
|
||||
lastRowScanOptSetLastTargets(pScan->node.pTargets, cxt.pLastCols, false);
|
||||
lastRowScanOptRemoveUslessTargets(pScan->node.pTargets, cxt.pLastCols, cxt.pOtherCols);
|
||||
lastRowScanOptSetLastTargets(pScan->node.pTargets, cxt.pLastCols, pLastRowCols, false);
|
||||
lastRowScanOptRemoveUslessTargets(pScan->node.pTargets, cxt.pLastCols, cxt.pOtherCols, pLastRowCols);
|
||||
if (pPKTsCol && pScan->node.pTargets->length == 1) {
|
||||
// when select last(ts),ts from ..., we add another ts to targets
|
||||
sprintf(pPKTsCol->colName, "#sel_val.%p", pPKTsCol);
|
||||
|
@ -2728,10 +2848,12 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic
|
|||
}
|
||||
nodesClearList(cxt.pLastCols);
|
||||
}
|
||||
|
||||
pAgg->hasLastRow = false;
|
||||
pAgg->hasLast = false;
|
||||
|
||||
pCxt->optimized = true;
|
||||
taosArrayDestroy(isDuplicateCol);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2749,7 +2871,7 @@ static bool splitCacheLastFuncOptMayBeOptimized(SLogicNode* pNode) {
|
|||
}
|
||||
|
||||
bool hasOtherFunc = false;
|
||||
if (!lastRowScanOptCheckFuncList(pNode, &hasOtherFunc)) {
|
||||
if (!lastRowScanOptCheckFuncList(pNode, pScan->cacheLastMode, &hasOtherFunc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2770,6 +2892,16 @@ static int32_t splitCacheLastFuncOptCreateAggLogicNode(SAggLogicNode** pNewAgg,
|
|||
|
||||
pNew->hasLastRow = false;
|
||||
pNew->hasLast = false;
|
||||
SNode* pFuncNode = NULL;
|
||||
FOREACH(pFuncNode, pFunc) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pFuncNode;
|
||||
if (FUNCTION_TYPE_LAST_ROW == pFunc->funcType) {
|
||||
pNew->hasLastRow = true;
|
||||
} else if (FUNCTION_TYPE_LAST == pFunc->funcType) {
|
||||
pNew->hasLast = true;
|
||||
}
|
||||
}
|
||||
|
||||
pNew->hasTimeLineFunc = pAgg->hasTimeLineFunc;
|
||||
pNew->hasGroupKeyOptimized = false;
|
||||
pNew->onlyHasKeepOrderFunc = pAgg->onlyHasKeepOrderFunc;
|
||||
|
@ -2894,21 +3026,31 @@ static int32_t splitCacheLastFuncOptimize(SOptimizeContext* pCxt, SLogicSubplan*
|
|||
if (NULL == pAgg) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
|
||||
SNode* pNode = NULL;
|
||||
SNodeList* pAggFuncList = NULL;
|
||||
|
||||
{
|
||||
bool hasLast = false;
|
||||
bool hasLastRow = false;
|
||||
WHERE_EACH(pNode, pAgg->pAggFuncs) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
int32_t funcType = pFunc->funcType;
|
||||
if (FUNCTION_TYPE_LAST_ROW != funcType && FUNCTION_TYPE_LAST != funcType &&
|
||||
FUNCTION_TYPE_SELECT_VALUE != funcType && FUNCTION_TYPE_GROUP_KEY != funcType) {
|
||||
|
||||
if (isNeedSplitCacheLastFunc(pFunc, pScan)) {
|
||||
nodesListMakeStrictAppend(&pAggFuncList, nodesCloneNode(pNode));
|
||||
ERASE_NODE(pAgg->pAggFuncs);
|
||||
continue;
|
||||
}
|
||||
if (FUNCTION_TYPE_LAST_ROW == funcType ) {
|
||||
hasLastRow = true;
|
||||
} else if (FUNCTION_TYPE_LAST == funcType) {
|
||||
hasLast = true;
|
||||
}
|
||||
WHERE_NEXT;
|
||||
}
|
||||
pAgg->hasLast = hasLast;
|
||||
pAgg->hasLastRow = hasLastRow;
|
||||
}
|
||||
|
||||
if (NULL == pAggFuncList) {
|
||||
|
|
|
@ -562,9 +562,36 @@ static int32_t createLastRowScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSu
|
|||
|
||||
pScan->groupSort = pScanLogicNode->groupSort;
|
||||
pScan->ignoreNull = pScanLogicNode->igLastNull;
|
||||
|
||||
vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode);
|
||||
|
||||
return createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, (SScanPhysiNode*)pScan, pPhyNode);
|
||||
int32_t code = createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, (SScanPhysiNode*)pScan, pPhyNode);
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && pScanLogicNode->pFuncTypes != NULL) {
|
||||
pScan->pFuncTypes = taosArrayInit(taosArrayGetSize(pScanLogicNode->pFuncTypes), sizeof(int32_t));
|
||||
if (NULL == pScan->pFuncTypes) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
SNode* pTargetNode = NULL;
|
||||
int funcTypeIndex = 0;
|
||||
FOREACH(pTargetNode, ((SScanPhysiNode*)pScan)->pScanCols) {
|
||||
if (((STargetNode*)pTargetNode)->pExpr->type != QUERY_NODE_COLUMN) {
|
||||
continue;
|
||||
}
|
||||
SColumnNode* pColNode = (SColumnNode*)((STargetNode*)pTargetNode)->pExpr;
|
||||
|
||||
for (int i = 0; i < TARRAY_SIZE(pScanLogicNode->pFuncTypes); ++i) {
|
||||
SFunctParam* pFunctParam = taosArrayGet(pScanLogicNode->pFuncTypes, i);
|
||||
if (pColNode->colId == pFunctParam->pCol->colId &&
|
||||
0 == strncmp(pColNode->colName, pFunctParam->pCol->name, strlen(pColNode->colName))) {
|
||||
taosArrayInsert(pScan->pFuncTypes, funcTypeIndex, &pFunctParam->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
funcTypeIndex++;
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t createTableCountScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan,
|
||||
|
|
|
@ -52,10 +52,10 @@ typedef enum {
|
|||
SCH_ALL,
|
||||
} SCH_POLICY;
|
||||
|
||||
#define SCHEDULE_DEFAULT_MAX_JOB_NUM 1000
|
||||
#define SCHEDULE_DEFAULT_MAX_TASK_NUM 1000
|
||||
#define SCHEDULE_DEFAULT_POLICY SCH_LOAD_SEQ
|
||||
#define SCHEDULE_DEFAULT_MAX_NODE_NUM 20
|
||||
#define SCHEDULE_DEFAULT_MAX_JOB_NUM 1000
|
||||
#define SCHEDULE_DEFAULT_MAX_TASK_NUM 1000
|
||||
#define SCHEDULE_DEFAULT_POLICY SCH_LOAD_SEQ
|
||||
#define SCHEDULE_DEFAULT_MAX_NODE_NUM 20
|
||||
|
||||
#define SCH_DEFAULT_TASK_TIMEOUT_USEC 5000000
|
||||
#define SCH_MAX_TASK_TIMEOUT_USEC 300000000
|
||||
|
@ -68,8 +68,9 @@ typedef struct SSchDebug {
|
|||
} SSchDebug;
|
||||
|
||||
typedef struct SSchTrans {
|
||||
void *pTrans;
|
||||
void *pHandle;
|
||||
void *pTrans;
|
||||
void *pHandle;
|
||||
int64_t pHandleId;
|
||||
} SSchTrans;
|
||||
|
||||
typedef struct SSchHbTrans {
|
||||
|
@ -299,7 +300,7 @@ typedef struct SSchJob {
|
|||
void *fetchRes; // TODO free it or not
|
||||
bool fetched;
|
||||
bool noMoreRetry;
|
||||
int64_t resNumOfRows; // from int32_t to int64_t
|
||||
int64_t resNumOfRows; // from int32_t to int64_t
|
||||
SSchResInfo userRes;
|
||||
char *sql;
|
||||
SQueryProfileSummary summary;
|
||||
|
@ -334,14 +335,15 @@ extern SSchedulerMgmt schMgmt;
|
|||
(!SCH_IS_DATA_BIND_QRY_TASK(_task)))
|
||||
|
||||
#define SCH_UPDATE_REDIRECT_CODE(job, _code) atomic_val_compare_exchange_32(&((job)->redirectCode), 0, _code)
|
||||
#define SCH_GET_REDIRECT_CODE(job, _code) (((!NO_RET_REDIRECT_ERROR(_code)) || (job)->redirectCode == 0) ? (_code) : (job)->redirectCode)
|
||||
#define SCH_GET_REDIRECT_CODE(job, _code) \
|
||||
(((!NO_RET_REDIRECT_ERROR(_code)) || (job)->redirectCode == 0) ? (_code) : (job)->redirectCode)
|
||||
|
||||
#define SCH_SET_TASK_STATUS(task, st) atomic_store_8(&(task)->status, st)
|
||||
#define SCH_GET_TASK_STATUS(task) atomic_load_8(&(task)->status)
|
||||
#define SCH_GET_TASK_STATUS_STR(task) jobTaskStatusStr(SCH_GET_TASK_STATUS(task))
|
||||
|
||||
#define SCH_TASK_ALREADY_LAUNCHED(task) (SCH_GET_TASK_STATUS(task) >= JOB_TASK_STATUS_EXEC)
|
||||
#define SCH_TASK_EXEC_DONE(task) (SCH_GET_TASK_STATUS(task) >= JOB_TASK_STATUS_PART_SUCC)
|
||||
#define SCH_TASK_EXEC_DONE(task) (SCH_GET_TASK_STATUS(task) >= JOB_TASK_STATUS_PART_SUCC)
|
||||
|
||||
#define SCH_GET_TASK_HANDLE(_task) ((_task) ? (_task)->handle : NULL)
|
||||
#define SCH_SET_TASK_HANDLE(_task, _handle) ((_task)->handle = (_handle))
|
||||
|
@ -362,8 +364,8 @@ extern SSchedulerMgmt schMgmt;
|
|||
#define SCH_JOB_NEED_FLOW_CTRL(_job) ((_job)->attr.needFlowCtrl)
|
||||
#define SCH_TASK_NEED_FLOW_CTRL(_job, _task) \
|
||||
(SCH_IS_DATA_BIND_QRY_TASK(_task) && SCH_JOB_NEED_FLOW_CTRL(_job) && SCH_IS_LEVEL_UNFINISHED((_task)->level))
|
||||
#define SCH_FETCH_TYPE(_pSrcTask) (SCH_IS_DATA_BIND_QRY_TASK(_pSrcTask) ? TDMT_SCH_FETCH : TDMT_SCH_MERGE_FETCH)
|
||||
#define SCH_TASK_NEED_FETCH(_task) ((_task)->plan->subplanType != SUBPLAN_TYPE_MODIFY)
|
||||
#define SCH_FETCH_TYPE(_pSrcTask) (SCH_IS_DATA_BIND_QRY_TASK(_pSrcTask) ? TDMT_SCH_FETCH : TDMT_SCH_MERGE_FETCH)
|
||||
#define SCH_TASK_NEED_FETCH(_task) ((_task)->plan->subplanType != SUBPLAN_TYPE_MODIFY)
|
||||
#define SCH_MULTI_LEVEL_LAUNCHED(_job) ((_job)->levelIdx != ((_job)->levelNum - 1))
|
||||
|
||||
#define SCH_SET_JOB_TYPE(_job, type) \
|
||||
|
@ -380,25 +382,26 @@ extern SSchedulerMgmt schMgmt;
|
|||
#define SCH_JOB_NEED_WAIT(_job) (!SCH_IS_QUERY_JOB(_job))
|
||||
#define SCH_JOB_NEED_DROP(_job) (SCH_IS_QUERY_JOB(_job))
|
||||
#define SCH_IS_EXPLAIN_JOB(_job) (EXPLAIN_MODE_ANALYZE == (_job)->attr.explainMode)
|
||||
#define SCH_NETWORK_ERR(_code) ((_code) == TSDB_CODE_RPC_BROKEN_LINK || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || (_code) == TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED)
|
||||
#define SCH_NETWORK_ERR(_code) \
|
||||
((_code) == TSDB_CODE_RPC_BROKEN_LINK || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || \
|
||||
(_code) == TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED)
|
||||
#define SCH_REDIRECT_MSGTYPE(_msgType) \
|
||||
((_msgType) == TDMT_SCH_LINK_BROKEN || (_msgType) == TDMT_SCH_QUERY || (_msgType) == TDMT_SCH_MERGE_QUERY || \
|
||||
(_msgType) == TDMT_SCH_FETCH || (_msgType) == TDMT_SCH_MERGE_FETCH)
|
||||
#define SCH_LOW_LEVEL_NETWORK_ERR(_job, _task, _code) \
|
||||
(SCH_NETWORK_ERR(_code) && ((_task)->level->level == (_job)->levelIdx))
|
||||
(SCH_NETWORK_ERR(_code) && ((_task)->level->level == (_job)->levelIdx))
|
||||
#define SCH_TOP_LEVEL_NETWORK_ERR(_job, _task, _code) \
|
||||
(SCH_NETWORK_ERR(_code) && ((_task)->level->level > (_job)->levelIdx))
|
||||
#define SCH_TASK_RETRY_NETWORK_ERR(_task, _code) \
|
||||
(SCH_NETWORK_ERR(_code) && (_task)->redirectCtx.inRedirect)
|
||||
(SCH_NETWORK_ERR(_code) && ((_task)->level->level > (_job)->levelIdx))
|
||||
#define SCH_TASK_RETRY_NETWORK_ERR(_task, _code) (SCH_NETWORK_ERR(_code) && (_task)->redirectCtx.inRedirect)
|
||||
|
||||
#define SCH_JOB_NEED_RETRY(_job, _task, _msgType, _code) \
|
||||
(SCH_REDIRECT_MSGTYPE(_msgType) && SCH_TOP_LEVEL_NETWORK_ERR(_job, _task, _code))
|
||||
#define SCH_TASKSET_NEED_RETRY(_job, _task, _msgType, _code) \
|
||||
(SCH_REDIRECT_MSGTYPE(_msgType) && \
|
||||
(NEED_SCHEDULER_REDIRECT_ERROR(_code) || SCH_LOW_LEVEL_NETWORK_ERR((_job), (_task), (_code)) || SCH_TASK_RETRY_NETWORK_ERR((_task), (_code))))
|
||||
#define SCH_JOB_NEED_RETRY(_job, _task, _msgType, _code) \
|
||||
(SCH_REDIRECT_MSGTYPE(_msgType) && SCH_TOP_LEVEL_NETWORK_ERR(_job, _task, _code))
|
||||
#define SCH_TASKSET_NEED_RETRY(_job, _task, _msgType, _code) \
|
||||
(SCH_REDIRECT_MSGTYPE(_msgType) && \
|
||||
(NEED_SCHEDULER_REDIRECT_ERROR(_code) || SCH_LOW_LEVEL_NETWORK_ERR((_job), (_task), (_code)) || \
|
||||
SCH_TASK_RETRY_NETWORK_ERR((_task), (_code))))
|
||||
#define SCH_TASK_NEED_RETRY(_msgType, _code) \
|
||||
((SCH_REDIRECT_MSGTYPE(_msgType) && SCH_NETWORK_ERR(_code)) || (_code) == TSDB_CODE_SCH_TIMEOUT_ERROR)
|
||||
|
||||
((SCH_REDIRECT_MSGTYPE(_msgType) && SCH_NETWORK_ERR(_code)) || (_code) == TSDB_CODE_SCH_TIMEOUT_ERROR)
|
||||
|
||||
#define SCH_IS_LEVEL_UNFINISHED(_level) ((_level)->taskLaunchedNum < (_level)->taskNum)
|
||||
#define SCH_GET_CUR_EP(_addr) (&(_addr)->epSet.eps[(_addr)->epSet.inUse])
|
||||
|
@ -488,50 +491,51 @@ extern SSchedulerMgmt schMgmt;
|
|||
|
||||
#define TD_RWLATCH_WRITE_FLAG_COPY 0x40000000
|
||||
|
||||
#define SCH_LOCK(type, _lock) \
|
||||
do { \
|
||||
if (SCH_READ == (type)) { \
|
||||
ASSERTS(atomic_load_32(_lock) >= 0, "invalid lock value before read lock"); \
|
||||
SCH_LOCK_DEBUG("SCH RLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH RLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32(_lock) > 0, "invalid lock value after read lock"); \
|
||||
} else { \
|
||||
ASSERTS(atomic_load_32(_lock) >= 0, "invalid lock value before write lock"); \
|
||||
SCH_LOCK_DEBUG("SCH WLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH WLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32(_lock) == TD_RWLATCH_WRITE_FLAG_COPY, "invalid lock value after write lock"); \
|
||||
} \
|
||||
#define SCH_LOCK(type, _lock) \
|
||||
do { \
|
||||
if (SCH_READ == (type)) { \
|
||||
ASSERTS(atomic_load_32(_lock) >= 0, "invalid lock value before read lock"); \
|
||||
SCH_LOCK_DEBUG("SCH RLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH RLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32(_lock) > 0, "invalid lock value after read lock"); \
|
||||
} else { \
|
||||
ASSERTS(atomic_load_32(_lock) >= 0, "invalid lock value before write lock"); \
|
||||
SCH_LOCK_DEBUG("SCH WLOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH WLOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32(_lock) == TD_RWLATCH_WRITE_FLAG_COPY, "invalid lock value after write lock"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SCH_UNLOCK(type, _lock) \
|
||||
do { \
|
||||
if (SCH_READ == (type)) { \
|
||||
ASSERTS(atomic_load_32((_lock)) > 0, "invalid lock value before read unlock"); \
|
||||
SCH_LOCK_DEBUG("SCH RULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRUnLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH RULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32((_lock)) >= 0, "invalid lock value after read unlock"); \
|
||||
} else { \
|
||||
ASSERTS(atomic_load_32((_lock)) & TD_RWLATCH_WRITE_FLAG_COPY, "invalid lock value before write unlock"); \
|
||||
SCH_LOCK_DEBUG("SCH WULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWUnLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH WULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32((_lock)) >= 0, "invalid lock value after write unlock"); \
|
||||
} \
|
||||
#define SCH_UNLOCK(type, _lock) \
|
||||
do { \
|
||||
if (SCH_READ == (type)) { \
|
||||
ASSERTS(atomic_load_32((_lock)) > 0, "invalid lock value before read unlock"); \
|
||||
SCH_LOCK_DEBUG("SCH RULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosRUnLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH RULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32((_lock)) >= 0, "invalid lock value after read unlock"); \
|
||||
} else { \
|
||||
ASSERTS(atomic_load_32((_lock)) & TD_RWLATCH_WRITE_FLAG_COPY, "invalid lock value before write unlock"); \
|
||||
SCH_LOCK_DEBUG("SCH WULOCK%p:%d, %s:%d B", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
taosWUnLockLatch(_lock); \
|
||||
SCH_LOCK_DEBUG("SCH WULOCK%p:%d, %s:%d E", (_lock), atomic_load_32(_lock), __FILE__, __LINE__); \
|
||||
ASSERTS(atomic_load_32((_lock)) >= 0, "invalid lock value after write unlock"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SCH_RESET_JOB_LEVEL_IDX(_job) do { \
|
||||
(_job)->levelIdx = (_job)->levelNum - 1; \
|
||||
SCH_JOB_DLOG("set job levelIdx to %d", (_job)->levelIdx); \
|
||||
} while (0)
|
||||
#define SCH_RESET_JOB_LEVEL_IDX(_job) \
|
||||
do { \
|
||||
(_job)->levelIdx = (_job)->levelNum - 1; \
|
||||
SCH_JOB_DLOG("set job levelIdx to %d", (_job)->levelIdx); \
|
||||
} while (0)
|
||||
|
||||
void schDeregisterTaskHb(SSchJob *pJob, SSchTask *pTask);
|
||||
void schCleanClusterHb(void *pTrans);
|
||||
int32_t schLaunchTask(SSchJob *job, SSchTask *task);
|
||||
int32_t schDelayLaunchTask(SSchJob *pJob, SSchTask *pTask);
|
||||
int32_t schBuildAndSendMsg(SSchJob *job, SSchTask *task, SQueryNodeAddr *addr, int32_t msgType, void* param);
|
||||
int32_t schBuildAndSendMsg(SSchJob *job, SSchTask *task, SQueryNodeAddr *addr, int32_t msgType, void *param);
|
||||
SSchJob *schAcquireJob(int64_t refId);
|
||||
int32_t schReleaseJob(int64_t refId);
|
||||
void schFreeFlowCtrl(SSchJob *pJob);
|
||||
|
|
|
@ -505,7 +505,7 @@ int32_t schHandleLinkBrokenCallback(void *param, SDataBuf *pMsg, int32_t code) {
|
|||
taosMemoryFree(pMsg->pEpSet);
|
||||
|
||||
SSchHbCallbackParam *hbParam = (SSchHbCallbackParam *)param;
|
||||
SSchTrans trans = {.pTrans = hbParam->pTrans, .pHandle = NULL};
|
||||
SSchTrans trans = {.pTrans = hbParam->pTrans, .pHandle = NULL, .pHandleId = 0};
|
||||
SCH_ERR_RET(schUpdateHbConnection(&hbParam->nodeEpId, &trans));
|
||||
|
||||
SCH_ERR_RET(schBuildAndSendHbMsg(&hbParam->nodeEpId, NULL));
|
||||
|
@ -537,6 +537,7 @@ int32_t schHandleHbCallback(void *param, SDataBuf *pMsg, int32_t code) {
|
|||
SSchTrans trans = {0};
|
||||
trans.pTrans = pParam->pTrans;
|
||||
trans.pHandle = pMsg->handle;
|
||||
trans.pHandleId = pMsg->handleRefId;
|
||||
|
||||
SCH_ERR_JRET(schUpdateHbConnection(&rsp.epId, &trans));
|
||||
SCH_ERR_JRET(schProcessOnTaskStatusRsp(&rsp.epId, rsp.taskStatus));
|
||||
|
|
|
@ -42,7 +42,7 @@ char *schDumpEpSet(SEpSet *pEpSet) {
|
|||
}
|
||||
|
||||
int32_t maxSize = 1024;
|
||||
char *str = taosMemoryMalloc(maxSize);
|
||||
char *str = taosMemoryMalloc(maxSize);
|
||||
if (NULL == str) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ char *schGetOpStr(SCH_OP_TYPE type) {
|
|||
}
|
||||
|
||||
void schFreeHbTrans(SSchHbTrans *pTrans) {
|
||||
rpcReleaseHandle(pTrans->trans.pHandle, TAOS_CONN_CLIENT);
|
||||
rpcReleaseHandle((void *)pTrans->trans.pHandleId, TAOS_CONN_CLIENT);
|
||||
|
||||
schFreeRpcCtx(&pTrans->rpcCtx);
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ int32_t schEnsureHbConnection(SSchJob *pJob, SSchTask *pTask) {
|
|||
if (!tsEnableQueryHb) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx);
|
||||
SQueryNodeEpId epId = {0};
|
||||
|
||||
|
@ -234,7 +234,8 @@ int32_t schUpdateHbConnection(SQueryNodeEpId *epId, SSchTrans *trans) {
|
|||
hb = taosHashGet(schMgmt.hbConnections, epId, sizeof(SQueryNodeEpId));
|
||||
if (NULL == hb) {
|
||||
SCH_UNLOCK(SCH_READ, &schMgmt.hbLock);
|
||||
qInfo("taosHashGet hb connection not exists, nodeId:%d, fqdn:%s, port:%d", epId->nodeId, epId->ep.fqdn, epId->ep.port);
|
||||
qInfo("taosHashGet hb connection not exists, nodeId:%d, fqdn:%s, port:%d", epId->nodeId, epId->ep.fqdn,
|
||||
epId->ep.port);
|
||||
SCH_ERR_RET(TSDB_CODE_APP_ERROR);
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ int32_t streamTaskSendCheckpointSourceRsp(SStreamTask* pTask);
|
|||
void streamTaskSetCheckpointFailedId(SStreamTask* pTask);
|
||||
int32_t streamTaskGetNumOfDownstream(const SStreamTask* pTask);
|
||||
int32_t streamTaskInitTokenBucket(STokenBucket* pBucket, int32_t numCap, int32_t numRate, float quotaRate, const char*);
|
||||
STaskId streamTaskExtractKey(const SStreamTask* pTask);
|
||||
STaskId streamTaskGetTaskId(const SStreamTask* pTask);
|
||||
void streamTaskInitForLaunchHTask(SHistoryTaskInfo* pInfo);
|
||||
void streamTaskSetRetryInfoForLaunch(SHistoryTaskInfo* pInfo);
|
||||
int32_t streamTaskBuildScanhistoryRspMsg(SStreamTask* pTask, SStreamScanHistoryFinishReq* pReq, void** pBuffer,
|
||||
|
|
|
@ -300,28 +300,6 @@ int32_t streamProcessRetrieveReq(SStreamTask* pTask, SStreamRetrieveReq* pReq, S
|
|||
|
||||
void streamTaskInputFail(SStreamTask* pTask) { atomic_store_8(&pTask->inputq.status, TASK_INPUT_STATUS__FAILED); }
|
||||
|
||||
void streamTaskOpenAllUpstreamInput(SStreamTask* pTask) {
|
||||
int32_t num = taosArrayGetSize(pTask->upstreamInfo.pList);
|
||||
if (num == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SStreamChildEpInfo* pInfo = taosArrayGetP(pTask->upstreamInfo.pList, i);
|
||||
pInfo->dataAllowed = true;
|
||||
}
|
||||
|
||||
pTask->upstreamInfo.numOfClosed = 0;
|
||||
stDebug("s-task:%s opening up inputQ from upstream tasks", pTask->id.idStr);
|
||||
}
|
||||
|
||||
void streamTaskCloseUpstreamInput(SStreamTask* pTask, int32_t taskId) {
|
||||
SStreamChildEpInfo* pInfo = streamTaskGetUpstreamTaskEpInfo(pTask, taskId);
|
||||
if (pInfo != NULL) {
|
||||
pInfo->dataAllowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
SStreamChildEpInfo* streamTaskGetUpstreamTaskEpInfo(SStreamTask* pTask, int32_t taskId) {
|
||||
int32_t num = taosArrayGetSize(pTask->upstreamInfo.pList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
|
|
|
@ -41,6 +41,8 @@ void destroyRocksdbCfInst(RocksdbCfInst* inst);
|
|||
int32_t getCfIdx(const char* cfName);
|
||||
STaskDbWrapper* taskDbOpenImpl(char* key, char* statePath, char* dbPath);
|
||||
|
||||
int32_t backendCopyFiles(char* src, char* dst);
|
||||
|
||||
void destroyCompactFilteFactory(void* arg);
|
||||
void destroyCompactFilte(void* arg);
|
||||
const char* compactFilteFactoryName(void* arg);
|
||||
|
@ -218,7 +220,7 @@ int32_t rebuildDirFromCheckpoint(const char* path, int64_t chkpId, char** dst) {
|
|||
taosRemoveDir(state);
|
||||
}
|
||||
taosMkDir(state);
|
||||
code = copyFiles(chkp, state);
|
||||
code = backendCopyFiles(chkp, state);
|
||||
stInfo("copy snap file from %s to %s", chkp, state);
|
||||
if (code != 0) {
|
||||
stError("failed to restart stream backend from %s, reason: %s", chkp, tstrerror(TAOS_SYSTEM_ERROR(errno)));
|
||||
|
@ -334,7 +336,7 @@ int32_t rebuildFromRemoteChkp_rsync(char* key, char* chkpPath, int64_t chkpId, c
|
|||
if (code != 0) {
|
||||
return code;
|
||||
}
|
||||
code = copyFiles(chkpPath, defaultPath);
|
||||
code = backendCopyFiles(chkpPath, defaultPath);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -359,7 +361,7 @@ int32_t rebuildFromRemoteChkp_s3(char* key, char* chkpPath, int64_t chkpId, char
|
|||
|
||||
if (code == 0) {
|
||||
taosMkDir(defaultPath);
|
||||
code = copyFiles(chkpPath, defaultPath);
|
||||
code = backendCopyFiles(chkpPath, defaultPath);
|
||||
}
|
||||
|
||||
if (code != 0) {
|
||||
|
@ -382,6 +384,121 @@ int32_t rebuildFromRemoteChkp(char* key, char* chkpPath, int64_t chkpId, char* d
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t copyFiles_create(char* src, char* dst, int8_t type) {
|
||||
// create and copy file
|
||||
int32_t err = taosCopyFile(src, dst);
|
||||
|
||||
if (errno == EXDEV || errno == ENOTSUP) {
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int32_t copyFiles_hardlink(char* src, char* dst, int8_t type) {
|
||||
// same fs and hard link
|
||||
return taosLinkFile(src, dst);
|
||||
}
|
||||
|
||||
int32_t backendFileCopyFilesImpl(char* src, char* dst) {
|
||||
const char* current = "CURRENT";
|
||||
size_t currLen = strlen(current);
|
||||
|
||||
int32_t code = 0;
|
||||
int32_t sLen = strlen(src);
|
||||
int32_t dLen = strlen(dst);
|
||||
char* srcName = taosMemoryCalloc(1, sLen + 64);
|
||||
char* dstName = taosMemoryCalloc(1, dLen + 64);
|
||||
// copy file to dst
|
||||
|
||||
TdDirPtr pDir = taosOpenDir(src);
|
||||
if (pDir == NULL) {
|
||||
taosMemoryFree(srcName);
|
||||
taosMemoryFree(dstName);
|
||||
errno = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
TdDirEntryPtr de = NULL;
|
||||
while ((de = taosReadDir(pDir)) != NULL) {
|
||||
char* name = taosGetDirEntryName(de);
|
||||
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue;
|
||||
|
||||
sprintf(srcName, "%s%s%s", src, TD_DIRSEP, name);
|
||||
sprintf(dstName, "%s%s%s", dst, TD_DIRSEP, name);
|
||||
|
||||
if (strncmp(name, current, strlen(name) <= currLen ? strlen(name) : currLen) == 0) {
|
||||
code = copyFiles_create(srcName, dstName, 0);
|
||||
if (code != 0) {
|
||||
stError("failed to copy file, detail: %s to %s reason: %s", srcName, dstName,
|
||||
tstrerror(TAOS_SYSTEM_ERROR(code)));
|
||||
goto _ERROR;
|
||||
}
|
||||
} else {
|
||||
code = copyFiles_hardlink(srcName, dstName, 0);
|
||||
if (code != 0) {
|
||||
stError("failed to hard line file, detail: %s to %s, reason: %s", srcName, dstName,
|
||||
tstrerror(TAOS_SYSTEM_ERROR(code)));
|
||||
goto _ERROR;
|
||||
}
|
||||
}
|
||||
memset(srcName, 0, sLen + 64);
|
||||
memset(dstName, 0, dLen + 64);
|
||||
}
|
||||
|
||||
taosMemoryFreeClear(srcName);
|
||||
taosMemoryFreeClear(dstName);
|
||||
taosCloseDir(&pDir);
|
||||
errno = 0;
|
||||
return 0;
|
||||
_ERROR:
|
||||
taosMemoryFreeClear(srcName);
|
||||
taosMemoryFreeClear(dstName);
|
||||
taosCloseDir(&pDir);
|
||||
errno = 0;
|
||||
return -1;
|
||||
}
|
||||
int32_t backendCopyFiles(char* src, char* dst) {
|
||||
return backendFileCopyFilesImpl(src, dst);
|
||||
// // opt later, just hard link
|
||||
// int32_t sLen = strlen(src);
|
||||
// int32_t dLen = strlen(dst);
|
||||
// char* srcName = taosMemoryCalloc(1, sLen + 64);
|
||||
// char* dstName = taosMemoryCalloc(1, dLen + 64);
|
||||
|
||||
// TdDirPtr pDir = taosOpenDir(src);
|
||||
// if (pDir == NULL) {
|
||||
// taosMemoryFree(srcName);
|
||||
// taosMemoryFree(dstName);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// TdDirEntryPtr de = NULL;
|
||||
// while ((de = taosReadDir(pDir)) != NULL) {
|
||||
// char* name = taosGetDirEntryName(de);
|
||||
// if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue;
|
||||
|
||||
// sprintf(srcName, "%s%s%s", src, TD_DIRSEP, name);
|
||||
// sprintf(dstName, "%s%s%s", dst, TD_DIRSEP, name);
|
||||
// // if (!taosDirEntryIsDir(de)) {
|
||||
// // // code = taosCopyFile(srcName, dstName);
|
||||
// // if (code == -1) {
|
||||
// // goto _err;
|
||||
// // }
|
||||
// // }
|
||||
// return backendFileCopyFilesImpl(src, dst);
|
||||
|
||||
// memset(srcName, 0, sLen + 64);
|
||||
// memset(dstName, 0, dLen + 64);
|
||||
// }
|
||||
|
||||
// _err:
|
||||
// taosMemoryFreeClear(srcName);
|
||||
// taosMemoryFreeClear(dstName);
|
||||
// taosCloseDir(&pDir);
|
||||
// return code >= 0 ? 0 : -1;
|
||||
|
||||
// return 0;
|
||||
}
|
||||
int32_t rebuildFromLocalChkp(char* key, char* chkpPath, int64_t chkpId, char* defaultPath) {
|
||||
int32_t code = -1;
|
||||
int32_t len = strlen(defaultPath) + 32;
|
||||
|
@ -396,7 +513,7 @@ int32_t rebuildFromLocalChkp(char* key, char* chkpPath, int64_t chkpId, char* de
|
|||
taosRemoveDir(tmp);
|
||||
}
|
||||
taosMkDir(defaultPath);
|
||||
code = copyFiles(chkpPath, defaultPath);
|
||||
code = backendCopyFiles(chkpPath, defaultPath);
|
||||
if (code != 0) {
|
||||
stError("failed to restart stream backend from %s, reason: %s", chkpPath, tstrerror(TAOS_SYSTEM_ERROR(errno)));
|
||||
} else {
|
||||
|
|
|
@ -185,6 +185,11 @@ int32_t streamProcessCheckpointBlock(SStreamTask* pTask, SStreamDataBlock* pBloc
|
|||
int64_t checkpointId = pDataBlock->info.version;
|
||||
const char* id = pTask->id.idStr;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t vgId = pTask->pMeta->vgId;
|
||||
|
||||
stDebug("s-task:%s vgId:%d start to handle the checkpoint block, checkpointId:%" PRId64 " ver:%" PRId64
|
||||
", current checkpointingId:%" PRId64,
|
||||
id, vgId, pTask->chkInfo.checkpointId, pTask->chkInfo.checkpointVer, checkpointId);
|
||||
|
||||
// set task status
|
||||
if (streamTaskGetStatus(pTask)->state != TASK_STATUS__CK) {
|
||||
|
@ -294,11 +299,8 @@ int32_t streamSaveTaskCheckpointInfo(SStreamTask* p, int64_t checkpointId) {
|
|||
int32_t code = 0;
|
||||
SCheckpointInfo* pCKInfo = &p->chkInfo;
|
||||
|
||||
if (p->info.fillHistory == 1) {
|
||||
return code;
|
||||
}
|
||||
|
||||
if (p->info.taskLevel > TASK_LEVEL__SINK) {
|
||||
// fill-history task, rsma task, and sink task will not generate the checkpoint
|
||||
if ((p->info.fillHistory == 1) || (p->info.taskLevel > TASK_LEVEL__SINK)) {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -333,7 +335,7 @@ int32_t streamSaveTaskCheckpointInfo(SStreamTask* p, int64_t checkpointId) {
|
|||
vgId, id, p->info.taskLevel, checkpointId, pCKInfo->checkpointVer, pCKInfo->nextProcessVer, pStatus->name);
|
||||
|
||||
// save the task if not sink task
|
||||
if (p->info.taskLevel != TASK_LEVEL__SINK) {
|
||||
if (p->info.taskLevel <= TASK_LEVEL__SINK) {
|
||||
streamMetaWLock(pMeta);
|
||||
|
||||
code = streamMetaSaveTask(pMeta, p);
|
||||
|
@ -451,16 +453,17 @@ int32_t streamTaskUploadChkp(SStreamTask* pTask, int64_t chkpId, char* taskId) {
|
|||
return streamMetaAsyncExec(pTask->pMeta, doUploadChkp, arg, NULL);
|
||||
}
|
||||
int32_t streamTaskBuildCheckpoint(SStreamTask* pTask) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int64_t startTs = pTask->chkInfo.startTs;
|
||||
int64_t ckId = pTask->chkInfo.checkpointingId;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int64_t startTs = pTask->chkInfo.startTs;
|
||||
int64_t ckId = pTask->chkInfo.checkpointingId;
|
||||
const char* id = pTask->id.idStr;
|
||||
|
||||
// sink task do not need to save the status, and generated the checkpoint
|
||||
if (pTask->info.taskLevel != TASK_LEVEL__SINK) {
|
||||
stDebug("s-task:%s level:%d start gen checkpoint", pTask->id.idStr, pTask->info.taskLevel);
|
||||
stDebug("s-task:%s level:%d start gen checkpoint, checkpointId:%" PRId64, id, pTask->info.taskLevel, ckId);
|
||||
code = streamBackendDoCheckpoint(pTask->pBackend, ckId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
stError("s-task:%s gen checkpoint:%" PRId64 " failed, code:%s", pTask->id.idStr, ckId, tstrerror(terrno));
|
||||
stError("s-task:%s gen checkpoint:%" PRId64 " failed, code:%s", id, ckId, tstrerror(terrno));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,39 +477,38 @@ int32_t streamTaskBuildCheckpoint(SStreamTask* pTask) {
|
|||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
// todo: let's retry send rsp to upstream/mnode
|
||||
stError("s-task:%s failed to send checkpoint rsp to upstream, checkpointId:%" PRId64 ", code:%s", pTask->id.idStr,
|
||||
ckId, tstrerror(code));
|
||||
stError("s-task:%s failed to send checkpoint rsp to upstream, checkpointId:%" PRId64 ", code:%s", id, ckId,
|
||||
tstrerror(code));
|
||||
}
|
||||
}
|
||||
|
||||
// clear the checkpoint info, and commit the newest checkpoint info if all works are done successfully
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
code = streamSaveTaskCheckpointInfo(pTask, ckId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
stError("s-task:%s commit taskInfo failed, checkpoint:%" PRId64 " failed, code:%s", pTask->id.idStr, ckId,
|
||||
tstrerror(code));
|
||||
} else {
|
||||
code = streamTaskUploadChkp(pTask, ckId, (char*)pTask->id.idStr);
|
||||
if (code != 0) {
|
||||
stError("s-task:%s failed to upload checkpoint:%" PRId64 " failed", pTask->id.idStr, ckId);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
code = streamTaskUploadChkp(pTask, ckId, (char*)id);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
stError("s-task:%s failed to upload checkpoint:%" PRId64 " failed", id, ckId);
|
||||
}
|
||||
} else {
|
||||
stError("s-task:%s commit taskInfo failed, checkpoint:%" PRId64 " failed, code:%s", id, ckId, tstrerror(code));
|
||||
}
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) { // clear the checkpoint info if failed
|
||||
// clear the checkpoint info if failed
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosThreadMutexLock(&pTask->lock);
|
||||
streamTaskClearCheckInfo(pTask, false);
|
||||
code = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_CHECKPOINT_DONE);
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
||||
streamTaskSetCheckpointFailedId(pTask);
|
||||
stDebug("s-task:%s clear checkpoint flag since gen checkpoint failed, checkpointId:%" PRId64, pTask->id.idStr,
|
||||
ckId);
|
||||
stDebug("s-task:%s clear checkpoint flag since gen checkpoint failed, checkpointId:%" PRId64, id, ckId);
|
||||
}
|
||||
|
||||
double el = (taosGetTimestampMs() - startTs) / 1000.0;
|
||||
stInfo("s-task:%s vgId:%d level:%d, checkpointId:%" PRId64 " ver:%" PRId64 " elapsed time:%.2f Sec, %s ",
|
||||
pTask->id.idStr, pTask->pMeta->vgId, pTask->info.taskLevel, ckId, pTask->chkInfo.checkpointVer, el,
|
||||
stInfo("s-task:%s vgId:%d level:%d, checkpointId:%" PRId64 " ver:%" PRId64 " elapsed time:%.2f Sec, %s ", id,
|
||||
pTask->pMeta->vgId, pTask->info.taskLevel, ckId, pTask->chkInfo.checkpointVer, el,
|
||||
(code == TSDB_CODE_SUCCESS) ? "succ" : "failed");
|
||||
|
||||
return code;
|
||||
|
|
|
@ -547,25 +547,21 @@ int32_t streamSearchAndAddBlock(SStreamTask* pTask, SStreamDispatchReq* pReqs, S
|
|||
memcpy(pDataBlock->info.parTbName, pBln->parTbName, strlen(pBln->parTbName));
|
||||
}
|
||||
} else {
|
||||
char* ctbName = taosMemoryCalloc(1, TSDB_TABLE_FNAME_LEN);
|
||||
if (ctbName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char ctbName[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
if (pDataBlock->info.parTbName[0]) {
|
||||
snprintf(ctbName, TSDB_TABLE_NAME_LEN, "%s.%s", pTask->outputInfo.shuffleDispatcher.dbInfo.db,
|
||||
pDataBlock->info.parTbName);
|
||||
if(pTask->ver >= SSTREAM_TASK_SUBTABLE_CHANGED_VER &&
|
||||
!isAutoTableName(pDataBlock->info.parTbName) &&
|
||||
!alreadyAddGroupId(pDataBlock->info.parTbName) &&
|
||||
groupId != 0){
|
||||
buildCtbNameAddGruopId(pDataBlock->info.parTbName, groupId);
|
||||
}
|
||||
} else {
|
||||
buildCtbNameByGroupIdImpl(pTask->outputInfo.shuffleDispatcher.stbFullName, groupId, pDataBlock->info.parTbName);
|
||||
snprintf(ctbName, TSDB_TABLE_NAME_LEN, "%s.%s", pTask->outputInfo.shuffleDispatcher.dbInfo.db,
|
||||
pDataBlock->info.parTbName);
|
||||
}
|
||||
|
||||
snprintf(ctbName, TSDB_TABLE_NAME_LEN, "%s.%s", pTask->outputInfo.shuffleDispatcher.dbInfo.db, pDataBlock->info.parTbName);
|
||||
/*uint32_t hashValue = MurmurHash3_32(ctbName, strlen(ctbName));*/
|
||||
SUseDbRsp* pDbInfo = &pTask->outputInfo.shuffleDispatcher.dbInfo;
|
||||
hashValue =
|
||||
taosGetTbHashVal(ctbName, strlen(ctbName), pDbInfo->hashMethod, pDbInfo->hashPrefix, pDbInfo->hashSuffix);
|
||||
taosMemoryFree(ctbName);
|
||||
hashValue = taosGetTbHashVal(ctbName, strlen(ctbName), pDbInfo->hashMethod, pDbInfo->hashPrefix, pDbInfo->hashSuffix);
|
||||
SBlockName bln = {0};
|
||||
bln.hashValue = hashValue;
|
||||
memcpy(bln.parTbName, pDataBlock->info.parTbName, strlen(pDataBlock->info.parTbName));
|
||||
|
|
|
@ -713,7 +713,13 @@ bool streamTaskReadyToRun(const SStreamTask* pTask, char** pStatus) {
|
|||
*pStatus = pState->name;
|
||||
}
|
||||
|
||||
return (st == TASK_STATUS__READY || st == TASK_STATUS__SCAN_HISTORY || st == TASK_STATUS__CK);
|
||||
// pause & halt will still run for sink tasks.
|
||||
if (streamTaskIsSinkTask(pTask)) {
|
||||
return (st == TASK_STATUS__READY || st == TASK_STATUS__SCAN_HISTORY || st == TASK_STATUS__CK ||
|
||||
st == TASK_STATUS__PAUSE || st == TASK_STATUS__HALT);
|
||||
} else {
|
||||
return (st == TASK_STATUS__READY || st == TASK_STATUS__SCAN_HISTORY || st == TASK_STATUS__CK);
|
||||
}
|
||||
}
|
||||
|
||||
static void doStreamExecTaskHelper(void* param, void* tmrId) {
|
||||
|
|
|
@ -47,6 +47,12 @@ struct SMetaHbInfo {
|
|||
int64_t hbStart;
|
||||
};
|
||||
|
||||
typedef struct STaskInitTs {
|
||||
int64_t start;
|
||||
int64_t end;
|
||||
bool success;
|
||||
} STaskInitTs;
|
||||
|
||||
SMetaRefMgt gMetaRefMgt;
|
||||
|
||||
void metaRefMgtInit();
|
||||
|
@ -174,10 +180,8 @@ int32_t streamMetaCheckBackendCompatible(SStreamMeta* pMeta) {
|
|||
}
|
||||
if (info.msgVer <= SSTREAM_TASK_INCOMPATIBLE_VER) {
|
||||
ret = STREAM_STATA_NO_COMPATIBLE;
|
||||
} else if (info.msgVer == SSTREAM_TASK_NEED_CONVERT_VER) {
|
||||
} else if (info.msgVer >= SSTREAM_TASK_NEED_CONVERT_VER) {
|
||||
ret = STREAM_STATA_NEED_CONVERT;
|
||||
} else if (info.msgVer == SSTREAM_TASK_VER) {
|
||||
ret = STREAM_STATA_COMPATIBLE;
|
||||
}
|
||||
tDecoderClear(&decoder);
|
||||
break;
|
||||
|
@ -581,7 +585,7 @@ int32_t streamMetaRemoveTask(SStreamMeta* pMeta, STaskId* pTaskId) {
|
|||
int32_t streamMetaRegisterTask(SStreamMeta* pMeta, int64_t ver, SStreamTask* pTask, bool* pAdded) {
|
||||
*pAdded = false;
|
||||
|
||||
STaskId id = streamTaskExtractKey(pTask);
|
||||
STaskId id = streamTaskGetTaskId(pTask);
|
||||
void* p = taosHashGet(pMeta->pTasksMap, &id, sizeof(id));
|
||||
if (p != NULL) {
|
||||
return 0;
|
||||
|
@ -871,7 +875,7 @@ int32_t streamMetaLoadAllTasks(SStreamMeta* pMeta) {
|
|||
int32_t taskId = pTask->id.taskId;
|
||||
tFreeStreamTask(pTask);
|
||||
|
||||
STaskId id = streamTaskExtractKey(pTask);
|
||||
STaskId id = streamTaskGetTaskId(pTask);
|
||||
taosArrayPush(pRecycleList, &id);
|
||||
|
||||
int32_t total = taosArrayGetSize(pRecycleList);
|
||||
|
@ -1302,28 +1306,28 @@ void streamMetaResetStartInfo(STaskStartInfo* pStartInfo) {
|
|||
}
|
||||
|
||||
void streamMetaRLock(SStreamMeta* pMeta) {
|
||||
stTrace("vgId:%d meta-rlock", pMeta->vgId);
|
||||
// stTrace("vgId:%d meta-rlock", pMeta->vgId);
|
||||
taosThreadRwlockRdlock(&pMeta->lock);
|
||||
}
|
||||
|
||||
void streamMetaRUnLock(SStreamMeta* pMeta) {
|
||||
stTrace("vgId:%d meta-runlock", pMeta->vgId);
|
||||
// stTrace("vgId:%d meta-runlock", pMeta->vgId);
|
||||
int32_t code = taosThreadRwlockUnlock(&pMeta->lock);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
stError("vgId:%d meta-runlock failed, code:%d", pMeta->vgId, code);
|
||||
} else {
|
||||
stDebug("vgId:%d meta-runlock completed", pMeta->vgId);
|
||||
// stDebug("vgId:%d meta-runlock completed", pMeta->vgId);
|
||||
}
|
||||
}
|
||||
|
||||
void streamMetaWLock(SStreamMeta* pMeta) {
|
||||
stTrace("vgId:%d meta-wlock", pMeta->vgId);
|
||||
// stTrace("vgId:%d meta-wlock", pMeta->vgId);
|
||||
taosThreadRwlockWrlock(&pMeta->lock);
|
||||
stTrace("vgId:%d meta-wlock completed", pMeta->vgId);
|
||||
// stTrace("vgId:%d meta-wlock completed", pMeta->vgId);
|
||||
}
|
||||
|
||||
void streamMetaWUnLock(SStreamMeta* pMeta) {
|
||||
stTrace("vgId:%d meta-wunlock", pMeta->vgId);
|
||||
// stTrace("vgId:%d meta-wunlock", pMeta->vgId);
|
||||
taosThreadRwlockUnlock(&pMeta->lock);
|
||||
}
|
||||
|
||||
|
@ -1407,6 +1411,80 @@ void streamMetaUpdateStageRole(SStreamMeta* pMeta, int64_t stage, bool isLeader)
|
|||
}
|
||||
}
|
||||
|
||||
int32_t streamMetaStartAllTasks(SStreamMeta* pMeta) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
stInfo("vgId:%d start to check all %d stream task(s) downstream status", vgId, numOfTasks);
|
||||
if (numOfTasks == 0) {
|
||||
stInfo("vgId:%d start tasks completed", pMeta->vgId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SArray* pTaskList = NULL;
|
||||
streamMetaWLock(pMeta);
|
||||
pTaskList = taosArrayDup(pMeta->pTaskList, NULL);
|
||||
taosHashClear(pMeta->startInfo.pReadyTaskSet);
|
||||
taosHashClear(pMeta->startInfo.pFailedTaskSet);
|
||||
pMeta->startInfo.startTs = taosGetTimestampMs();
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
// broadcast the check downstream tasks msg
|
||||
int64_t now = taosGetTimestampMs();
|
||||
|
||||
for (int32_t i = 0; i < numOfTasks; ++i) {
|
||||
SStreamTaskId* pTaskId = taosArrayGet(pTaskList, i);
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pTaskId->streamId, pTaskId->taskId);
|
||||
if (pTask == NULL) {
|
||||
stError("vgId:%d failed to acquire task:0x%x during start tasks", pMeta->vgId, pTaskId->taskId);
|
||||
streamMetaAddTaskLaunchResult(pMeta, pTaskId->streamId, pTaskId->taskId, 0, now, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
// todo: may be we should find the related fill-history task and set it failed.
|
||||
|
||||
// fill-history task can only be launched by related stream tasks.
|
||||
STaskExecStatisInfo* pInfo = &pTask->execInfo;
|
||||
if (pTask->info.fillHistory == 1) {
|
||||
stDebug("s-task:%s fill-history task wait related stream task start", pTask->id.idStr);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pTask->status.downstreamReady == 1) {
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
stDebug("s-task:%s downstream ready, no need to check downstream, check only related fill-history task",
|
||||
pTask->id.idStr);
|
||||
streamLaunchFillHistoryTask(pTask);
|
||||
}
|
||||
|
||||
streamMetaAddTaskLaunchResult(pMeta, pTaskId->streamId, pTaskId->taskId, pInfo->init, pInfo->start, true);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t ret = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_INIT);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
stError("vgId:%d failed to handle event:%d", pMeta->vgId, TASK_EVENT_INIT);
|
||||
code = ret;
|
||||
|
||||
streamMetaAddTaskLaunchResult(pMeta, pTaskId->streamId, pTaskId->taskId, pInfo->init, pInfo->start, false);
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
STaskId* pId = &pTask->hTaskInfo.id;
|
||||
streamMetaAddTaskLaunchResult(pMeta, pId->streamId, pId->taskId, pInfo->init, pInfo->start, false);
|
||||
}
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
}
|
||||
|
||||
stInfo("vgId:%d start tasks completed", pMeta->vgId);
|
||||
taosArrayDestroy(pTaskList);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t streamMetaStopAllTasks(SStreamMeta* pMeta) {
|
||||
streamMetaRLock(pMeta);
|
||||
|
||||
|
@ -1438,78 +1516,21 @@ int32_t streamMetaStopAllTasks(SStreamMeta* pMeta) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t streamMetaStartAllTasks(SStreamMeta* pMeta) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
bool streamMetaAllTasksReady(const SStreamMeta* pMeta) {
|
||||
int32_t num = taosArrayGetSize(pMeta->pTaskList);
|
||||
for(int32_t i = 0; i < num; ++i) {
|
||||
STaskId* pTaskId = taosArrayGet(pMeta->pTaskList, i);
|
||||
SStreamTask** ppTask = taosHashGet(pMeta->pTasksMap, pTaskId, sizeof(*pTaskId));
|
||||
if (ppTask == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
stInfo("vgId:%d start to check all %d stream task(s) downstream status", vgId, numOfTasks);
|
||||
if (numOfTasks == 0) {
|
||||
stInfo("vgId:%d start tasks completed", pMeta->vgId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
if ((*ppTask)->status.downstreamReady == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SArray* pTaskList = NULL;
|
||||
streamMetaWLock(pMeta);
|
||||
pTaskList = taosArrayDup(pMeta->pTaskList, NULL);
|
||||
taosHashClear(pMeta->startInfo.pReadyTaskSet);
|
||||
taosHashClear(pMeta->startInfo.pFailedTaskSet);
|
||||
pMeta->startInfo.startTs = taosGetTimestampMs();
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
// broadcast the check downstream tasks msg
|
||||
int64_t now = taosGetTimestampMs();
|
||||
|
||||
for (int32_t i = 0; i < numOfTasks; ++i) {
|
||||
SStreamTaskId* pTaskId = taosArrayGet(pTaskList, i);
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pTaskId->streamId, pTaskId->taskId);
|
||||
if (pTask == NULL) {
|
||||
stError("vgId:%d failed to acquire task:0x%x during start tasks", pMeta->vgId, pTaskId->taskId);
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, pTaskId->streamId, pTaskId->taskId, 0, now, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
// todo: may be we should find the related fill-history task and set it failed.
|
||||
|
||||
// fill-history task can only be launched by related stream tasks.
|
||||
STaskExecStatisInfo* pInfo = &pTask->execInfo;
|
||||
if (pTask->info.fillHistory == 1) {
|
||||
stDebug("s-task:%s fill-history task wait related stream task start", pTask->id.idStr);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pTask->status.downstreamReady == 1) {
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
stDebug("s-task:%s downstream ready, no need to check downstream, check only related fill-history task",
|
||||
pTask->id.idStr);
|
||||
streamLaunchFillHistoryTask(pTask);
|
||||
}
|
||||
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, pTaskId->streamId, pTaskId->taskId, pInfo->init, pInfo->start, true);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t ret = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_INIT);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
stError("vgId:%d failed to handle event:%d", pMeta->vgId, TASK_EVENT_INIT);
|
||||
code = ret;
|
||||
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, pTaskId->streamId, pTaskId->taskId, pInfo->init, pInfo->start, false);
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
STaskId* pId = &pTask->hTaskInfo.id;
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, pId->streamId, pId->taskId, pInfo->init, pInfo->start, false);
|
||||
}
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
}
|
||||
|
||||
stInfo("vgId:%d start tasks completed", pMeta->vgId);
|
||||
taosArrayDestroy(pTaskList);
|
||||
return code;
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t streamMetaStartOneTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId) {
|
||||
|
@ -1519,7 +1540,7 @@ int32_t streamMetaStartOneTask(SStreamMeta* pMeta, int64_t streamId, int32_t tas
|
|||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, streamId, taskId);
|
||||
if (pTask == NULL) {
|
||||
stError("vgId:%d failed to acquire task:0x%x during start tasks", pMeta->vgId, taskId);
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, streamId, taskId, 0, taosGetTimestampMs(), false);
|
||||
streamMetaAddTaskLaunchResult(pMeta, streamId, taskId, 0, taosGetTimestampMs(), false);
|
||||
return TSDB_CODE_STREAM_TASK_IVLD_STATUS;
|
||||
}
|
||||
|
||||
|
@ -1538,13 +1559,83 @@ int32_t streamMetaStartOneTask(SStreamMeta* pMeta, int64_t streamId, int32_t tas
|
|||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
stError("vgId:%d failed to handle event:%d", pMeta->vgId, TASK_EVENT_INIT);
|
||||
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, streamId, taskId, pInfo->init, pInfo->start, false);
|
||||
streamMetaAddTaskLaunchResult(pMeta, streamId, taskId, pInfo->init, pInfo->start, false);
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
STaskId* pId = &pTask->hTaskInfo.id;
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, pId->streamId, pId->taskId, pInfo->init, pInfo->start, false);
|
||||
streamMetaAddTaskLaunchResult(pMeta, pId->streamId, pId->taskId, pInfo->init, pInfo->start, false);
|
||||
}
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void displayStatusInfo(SStreamMeta* pMeta, SHashObj* pTaskSet, bool succ) {
|
||||
int32_t vgId = pMeta->vgId;
|
||||
void* pIter = NULL;
|
||||
size_t keyLen = 0;
|
||||
|
||||
stInfo("vgId:%d %d tasks check-downstream completed %s", vgId, taosHashGetSize(pTaskSet),
|
||||
succ ? "success" : "failed");
|
||||
|
||||
while ((pIter = taosHashIterate(pTaskSet, pIter)) != NULL) {
|
||||
STaskInitTs* pInfo = pIter;
|
||||
void* key = taosHashGetKey(pIter, &keyLen);
|
||||
|
||||
SStreamTask** pTask1 = taosHashGet(pMeta->pTasksMap, key, sizeof(STaskId));
|
||||
if (pTask1 == NULL) {
|
||||
stInfo("s-task:0x%x is dropped already, %s", (int32_t)((STaskId*)key)->taskId, succ ? "success" : "failed");
|
||||
} else {
|
||||
stInfo("s-task:%s level:%d vgId:%d, init:%" PRId64 ", initEnd:%" PRId64 ", %s", (*pTask1)->id.idStr,
|
||||
(*pTask1)->info.taskLevel, vgId, pInfo->start, pInfo->end, pInfo->success ? "success" : "failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t streamMetaAddTaskLaunchResult(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t startTs,
|
||||
int64_t endTs, bool ready) {
|
||||
STaskStartInfo* pStartInfo = &pMeta->startInfo;
|
||||
STaskId id = {.streamId = streamId, .taskId = taskId};
|
||||
|
||||
streamMetaWLock(pMeta);
|
||||
|
||||
if (pStartInfo->taskStarting != 1) {
|
||||
int64_t el = endTs - startTs;
|
||||
qDebug("vgId:%d not start all task(s), not record status, s-task:0x%x launch succ:%d elapsed time:%" PRId64 "ms",
|
||||
pMeta->vgId, taskId, ready, el);
|
||||
streamMetaWUnLock(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SHashObj* pDst = ready ? pStartInfo->pReadyTaskSet : pStartInfo->pFailedTaskSet;
|
||||
|
||||
STaskInitTs initTs = {.start = startTs, .end = endTs, .success = ready};
|
||||
taosHashPut(pDst, &id, sizeof(id), &initTs, sizeof(STaskInitTs));
|
||||
|
||||
int32_t numOfTotal = streamMetaGetNumOfTasks(pMeta);
|
||||
int32_t numOfRecv = taosHashGetSize(pStartInfo->pReadyTaskSet) + taosHashGetSize(pStartInfo->pFailedTaskSet);
|
||||
|
||||
if (numOfRecv == numOfTotal) {
|
||||
pStartInfo->readyTs = taosGetTimestampMs();
|
||||
pStartInfo->elapsedTime = (pStartInfo->startTs != 0) ? pStartInfo->readyTs - pStartInfo->startTs : 0;
|
||||
|
||||
stDebug("vgId:%d all %d task(s) check downstream completed, last completed task:0x%x (succ:%d) startTs:%" PRId64
|
||||
", readyTs:%" PRId64 " total elapsed time:%.2fs",
|
||||
pMeta->vgId, numOfTotal, taskId, ready, pStartInfo->startTs, pStartInfo->readyTs,
|
||||
pStartInfo->elapsedTime / 1000.0);
|
||||
|
||||
// print the initialization elapsed time and info
|
||||
displayStatusInfo(pMeta, pStartInfo->pReadyTaskSet, true);
|
||||
displayStatusInfo(pMeta, pStartInfo->pFailedTaskSet, false);
|
||||
streamMetaResetStartInfo(pStartInfo);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
pStartInfo->completeFn(pMeta);
|
||||
} else {
|
||||
streamMetaWUnLock(pMeta);
|
||||
stDebug("vgId:%d recv check downstream results, s-task:0x%x succ:%d, received:%d, total:%d", pMeta->vgId, taskId,
|
||||
ready, numOfRecv, numOfTotal);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
|
@ -154,7 +154,6 @@ int32_t streamTaskGetDataFromInputQ(SStreamTask* pTask, SStreamQueueItem** pInpu
|
|||
*numOfBlocks = 0;
|
||||
*blockSize = 0;
|
||||
|
||||
// todo remove it
|
||||
// no available token in bucket for sink task, let's wait for a little bit
|
||||
if (taskLevel == TASK_LEVEL__SINK && (!streamTaskExtractAvailableToken(pTask->outputInfo.pTokenBucket, pTask->id.idStr))) {
|
||||
stDebug("s-task:%s no available token in bucket for sink data, wait for 10ms", id);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
typedef struct SLaunchHTaskInfo {
|
||||
SStreamMeta* pMeta;
|
||||
STaskId id;
|
||||
STaskId hTaskId;
|
||||
} SLaunchHTaskInfo;
|
||||
|
||||
typedef struct STaskRecheckInfo {
|
||||
|
@ -34,16 +35,11 @@ typedef struct STaskRecheckInfo {
|
|||
void* checkTimer;
|
||||
} STaskRecheckInfo;
|
||||
|
||||
typedef struct STaskInitTs {
|
||||
int64_t start;
|
||||
int64_t end;
|
||||
bool success;
|
||||
} STaskInitTs;
|
||||
|
||||
static int32_t streamSetParamForScanHistory(SStreamTask* pTask);
|
||||
static void streamTaskSetRangeStreamCalc(SStreamTask* pTask);
|
||||
static int32_t initScanHistoryReq(SStreamTask* pTask, SStreamScanHistoryReq* pReq, int8_t igUntreated);
|
||||
static SLaunchHTaskInfo* createHTaskLaunchInfo(SStreamMeta* pMeta, int64_t streamId, int32_t taskId);
|
||||
static SLaunchHTaskInfo* createHTaskLaunchInfo(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t hStreamId,
|
||||
int32_t hTaskId);
|
||||
static void tryLaunchHistoryTask(void* param, void* tmrId);
|
||||
static void doProcessDownstreamReadyRsp(SStreamTask* pTask);
|
||||
|
||||
|
@ -394,7 +390,7 @@ void doProcessDownstreamReadyRsp(SStreamTask* pTask) {
|
|||
|
||||
int64_t initTs = pTask->execInfo.init;
|
||||
int64_t startTs = pTask->execInfo.start;
|
||||
streamMetaUpdateTaskDownstreamStatus(pTask->pMeta, pTask->id.streamId, pTask->id.taskId, initTs, startTs, true);
|
||||
streamMetaAddTaskLaunchResult(pTask->pMeta, pTask->id.streamId, pTask->id.taskId, initTs, startTs, true);
|
||||
|
||||
// start the related fill-history task, when current task is ready
|
||||
// not invoke in success callback due to the deadlock.
|
||||
|
@ -492,12 +488,12 @@ int32_t streamProcessCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRs
|
|||
|
||||
int32_t startTs = pTask->execInfo.init;
|
||||
int64_t now = taosGetTimestampMs();
|
||||
streamMetaUpdateTaskDownstreamStatus(pTask->pMeta, pTask->id.streamId, pTask->id.taskId, startTs, now, false);
|
||||
streamMetaAddTaskLaunchResult(pTask->pMeta, pTask->id.streamId, pTask->id.taskId, startTs, now, false);
|
||||
|
||||
// automatically set the related fill-history task to be failed.
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
STaskId* pId = &pTask->hTaskInfo.id;
|
||||
streamMetaUpdateTaskDownstreamStatus(pTask->pMeta, pId->streamId, pId->taskId, startTs, now, false);
|
||||
streamMetaAddTaskLaunchResult(pTask->pMeta, pId->streamId, pId->taskId, startTs, now, false);
|
||||
}
|
||||
} else { // TASK_DOWNSTREAM_NOT_READY, let's retry in 100ms
|
||||
STaskRecheckInfo* pInfo = createRecheckInfo(pTask, pRsp);
|
||||
|
@ -544,15 +540,6 @@ int32_t streamSetParamForScanHistory(SStreamTask* pTask) {
|
|||
return qSetStreamOperatorOptionForScanHistory(pTask->exec.pExecutor);
|
||||
}
|
||||
|
||||
int32_t streamResetParamForScanHistory(SStreamTask* pTask) {
|
||||
stDebug("s-task:%s reset operator option for scan-history data", pTask->id.idStr);
|
||||
if (pTask->exec.pExecutor != NULL) {
|
||||
return qResetStreamOperatorOptionForScanHistory(pTask->exec.pExecutor);
|
||||
} else {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t streamRestoreParam(SStreamTask* pTask) {
|
||||
stDebug("s-task:%s restore operator param after scan-history", pTask->id.idStr);
|
||||
return qRestoreStreamOperatorOption(pTask->exec.pExecutor);
|
||||
|
@ -728,30 +715,79 @@ static void checkFillhistoryTaskStatus(SStreamTask* pTask, SStreamTask* pHTask)
|
|||
streamTaskHandleEvent(pHTask->status.pSM, TASK_EVENT_INIT_SCANHIST);
|
||||
}
|
||||
|
||||
static void noRetryLaunchFillHistoryTask(SStreamTask* pTask, SLaunchHTaskInfo* pInfo, int64_t now) {
|
||||
SStreamMeta* pMeta = pTask->pMeta;
|
||||
SHistoryTaskInfo* pHTaskInfo = &pTask->hTaskInfo;
|
||||
|
||||
int32_t ref = atomic_sub_fetch_32(&pTask->status.timerActive, 1);
|
||||
streamMetaAddTaskLaunchResult(pMeta, pInfo->hTaskId.streamId, pInfo->hTaskId.taskId, 0, now, false);
|
||||
|
||||
stError("s-task:%s max retry:%d reached, quit from retrying launch related fill-history task:0x%x, ref:%d",
|
||||
pTask->id.idStr, MAX_RETRY_LAUNCH_HISTORY_TASK, (int32_t)pHTaskInfo->id.taskId, ref);
|
||||
|
||||
pHTaskInfo->id.taskId = 0;
|
||||
pHTaskInfo->id.streamId = 0;
|
||||
}
|
||||
|
||||
static void doRetryLaunchFillHistoryTask(SStreamTask* pTask, SLaunchHTaskInfo* pInfo, int64_t now) {
|
||||
SStreamMeta* pMeta = pTask->pMeta;
|
||||
SHistoryTaskInfo* pHTaskInfo = &pTask->hTaskInfo;
|
||||
|
||||
if (streamTaskShouldStop(pTask)) { // record the failure
|
||||
int32_t ref = atomic_sub_fetch_32(&pTask->status.timerActive, 1);
|
||||
stDebug("s-task:0x%" PRIx64 " stopped, not launch rel history task:0x%" PRIx64 ", ref:%d", pInfo->id.taskId,
|
||||
pInfo->hTaskId.taskId, ref);
|
||||
|
||||
streamMetaAddTaskLaunchResult(pMeta, pInfo->hTaskId.streamId, pInfo->hTaskId.taskId, 0, now, false);
|
||||
taosMemoryFree(pInfo);
|
||||
} else {
|
||||
char* p = streamTaskGetStatus(pTask)->name;
|
||||
int32_t hTaskId = pHTaskInfo->id.taskId;
|
||||
|
||||
stDebug("s-task:%s status:%s failed to launch fill-history task:0x%x, retry launch:%dms, retryCount:%d",
|
||||
pTask->id.idStr, p, hTaskId, pHTaskInfo->waitInterval, pHTaskInfo->retryTimes);
|
||||
|
||||
taosTmrReset(tryLaunchHistoryTask, LAUNCH_HTASK_INTERVAL, pInfo, streamTimer, &pHTaskInfo->pTimer);
|
||||
}
|
||||
}
|
||||
|
||||
static void tryLaunchHistoryTask(void* param, void* tmrId) {
|
||||
SLaunchHTaskInfo* pInfo = param;
|
||||
SStreamMeta* pMeta = pInfo->pMeta;
|
||||
int64_t now = taosGetTimestampMs();
|
||||
|
||||
streamMetaWLock(pMeta);
|
||||
|
||||
SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &pInfo->id, sizeof(pInfo->id));
|
||||
if (ppTask) {
|
||||
if (ppTask == NULL || *ppTask == NULL) {
|
||||
stError("s-task:0x%x and rel fill-history task:0x%" PRIx64 " all have been destroyed, not launch",
|
||||
(int32_t)pInfo->id.taskId, pInfo->hTaskId.taskId);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
// already dropped, no need to set the failure info into the stream task meta.
|
||||
taosMemoryFree(pInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (streamTaskShouldStop(*ppTask)) {
|
||||
ASSERT((*ppTask)->status.timerActive >= 1);
|
||||
|
||||
if (streamTaskShouldStop(*ppTask)) {
|
||||
char* p = streamTaskGetStatus(*ppTask)->name;
|
||||
int32_t ref = atomic_sub_fetch_32(&(*ppTask)->status.timerActive, 1);
|
||||
stDebug("s-task:%s status:%s should stop, quit launch fill-history task timer, retry:%d, ref:%d",
|
||||
(*ppTask)->id.idStr, p, (*ppTask)->hTaskInfo.retryTimes, ref);
|
||||
char* p = streamTaskGetStatus(*ppTask)->name;
|
||||
int32_t ref = atomic_sub_fetch_32(&(*ppTask)->status.timerActive, 1);
|
||||
stDebug("s-task:%s status:%s should stop, quit launch fill-history task timer, retry:%d, ref:%d",
|
||||
(*ppTask)->id.idStr, p, (*ppTask)->hTaskInfo.retryTimes, ref);
|
||||
|
||||
taosMemoryFree(pInfo);
|
||||
streamMetaWUnLock(pMeta);
|
||||
return;
|
||||
}
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
// record the related fill-history task failed
|
||||
streamMetaAddTaskLaunchResult(pMeta, pInfo->hTaskId.streamId, pInfo->hTaskId.taskId, 0, now, false);
|
||||
taosMemoryFree(pInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTaskNoLock(pMeta, pInfo->id.streamId, pInfo->id.taskId);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pInfo->id.streamId, pInfo->id.taskId);
|
||||
if (pTask != NULL) {
|
||||
SHistoryTaskInfo* pHTaskInfo = &pTask->hTaskInfo;
|
||||
|
||||
|
@ -763,128 +799,153 @@ static void tryLaunchHistoryTask(void* param, void* tmrId) {
|
|||
}
|
||||
|
||||
if (pHTaskInfo->retryTimes > MAX_RETRY_LAUNCH_HISTORY_TASK) {
|
||||
int32_t ref = atomic_sub_fetch_32(&pTask->status.timerActive, 1);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
||||
stError("s-task:%s max retry:%d reached, quit from retrying launch related fill-history task:0x%x, ref:%d",
|
||||
pTask->id.idStr, MAX_RETRY_LAUNCH_HISTORY_TASK, (int32_t)pHTaskInfo->id.taskId, ref);
|
||||
|
||||
pHTaskInfo->id.taskId = 0;
|
||||
pHTaskInfo->id.streamId = 0;
|
||||
noRetryLaunchFillHistoryTask(pTask, pInfo, now);
|
||||
} else { // not reach the limitation yet, let's continue retrying launch related fill-history task.
|
||||
streamTaskSetRetryInfoForLaunch(pHTaskInfo);
|
||||
ASSERT(pTask->status.timerActive >= 1);
|
||||
|
||||
// abort the timer if intend to stop task
|
||||
SStreamTask* pHTask = streamMetaAcquireTask(pMeta, pHTaskInfo->id.streamId, pHTaskInfo->id.taskId);
|
||||
if (pHTask == NULL && (!streamTaskShouldStop(pTask))) {
|
||||
char* p = streamTaskGetStatus(pTask)->name;
|
||||
int32_t hTaskId = pHTaskInfo->id.taskId;
|
||||
|
||||
stDebug("s-task:%s status:%s failed to launch fill-history task:0x%x, retry launch:%dms, retryCount:%d",
|
||||
pTask->id.idStr, p, hTaskId, pHTaskInfo->waitInterval, pHTaskInfo->retryTimes);
|
||||
|
||||
taosTmrReset(tryLaunchHistoryTask, LAUNCH_HTASK_INTERVAL, pInfo, streamTimer, &pHTaskInfo->pTimer);
|
||||
if (pHTask == NULL) {
|
||||
doRetryLaunchFillHistoryTask(pTask, pInfo, now);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pHTask != NULL) {
|
||||
} else {
|
||||
checkFillhistoryTaskStatus(pTask, pHTask);
|
||||
streamMetaReleaseTask(pMeta, pHTask);
|
||||
}
|
||||
|
||||
// not in timer anymore
|
||||
int32_t ref = atomic_sub_fetch_32(&pTask->status.timerActive, 1);
|
||||
stDebug("s-task:0x%x fill-history task launch completed, retry times:%d, ref:%d", (int32_t)pInfo->id.taskId,
|
||||
pHTaskInfo->retryTimes, ref);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
// not in timer anymore
|
||||
int32_t ref = atomic_sub_fetch_32(&pTask->status.timerActive, 1);
|
||||
stDebug("s-task:0x%x fill-history task launch completed, retry times:%d, ref:%d", (int32_t)pInfo->id.taskId,
|
||||
pHTaskInfo->retryTimes, ref);
|
||||
}
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
} else {
|
||||
stError("s-task:0x%x failed to load task, it may have been destroyed, not launch related fill-history task",
|
||||
(int32_t)pInfo->id.taskId);
|
||||
streamMetaAddTaskLaunchResult(pMeta, pInfo->hTaskId.streamId, pInfo->hTaskId.taskId, 0, now, false);
|
||||
|
||||
int32_t ref = atomic_sub_fetch_32(&(*ppTask)->status.timerActive, 1);
|
||||
stError("s-task:0x%x rel fill-history task:0x%" PRIx64 " may have been destroyed, not launch, ref:%d",
|
||||
(int32_t)pInfo->id.taskId, pInfo->hTaskId.taskId, ref);
|
||||
}
|
||||
|
||||
taosMemoryFree(pInfo);
|
||||
}
|
||||
|
||||
SLaunchHTaskInfo* createHTaskLaunchInfo(SStreamMeta* pMeta, int64_t streamId, int32_t taskId) {
|
||||
SLaunchHTaskInfo* createHTaskLaunchInfo(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t hStreamId,
|
||||
int32_t hTaskId) {
|
||||
SLaunchHTaskInfo* pInfo = taosMemoryCalloc(1, sizeof(SLaunchHTaskInfo));
|
||||
if (pInfo == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pInfo->id.taskId = taskId;
|
||||
pInfo->id.streamId = streamId;
|
||||
pInfo->id.taskId = taskId;
|
||||
|
||||
pInfo->hTaskId.streamId = hStreamId;
|
||||
pInfo->hTaskId.taskId = hTaskId;
|
||||
|
||||
pInfo->pMeta = pMeta;
|
||||
return pInfo;
|
||||
}
|
||||
|
||||
// an fill history task needs to be started.
|
||||
int32_t streamLaunchFillHistoryTask(SStreamTask* pTask) {
|
||||
SStreamMeta* pMeta = pTask->pMeta;
|
||||
|
||||
int64_t streamId = pTask->hTaskInfo.id.streamId;
|
||||
int32_t hTaskId = pTask->hTaskInfo.id.taskId;
|
||||
static int32_t launchNotBuiltFillHistoryTask(SStreamTask* pTask) {
|
||||
SStreamMeta* pMeta = pTask->pMeta;
|
||||
STaskExecStatisInfo* pExecInfo = &pTask->execInfo;
|
||||
const char* idStr = pTask->id.idStr;
|
||||
int64_t hStreamId = pTask->hTaskInfo.id.streamId;
|
||||
int32_t hTaskId = pTask->hTaskInfo.id.taskId;
|
||||
ASSERT(hTaskId != 0);
|
||||
|
||||
SStreamTaskState* pStatus = streamTaskGetStatus(pTask);
|
||||
if (pStatus->state != TASK_STATUS__READY) {
|
||||
STaskExecStatisInfo* pInfo = &pTask->execInfo;
|
||||
stDebug("s-task:%s not launch related fill-history task:0x%" PRIx64 "-0x%x, status:%s", pTask->id.idStr,
|
||||
pTask->hTaskInfo.id.streamId, hTaskId, pStatus->name);
|
||||
stWarn("s-task:%s vgId:%d failed to launch history task:0x%x, since not built yet", idStr, pMeta->vgId, hTaskId);
|
||||
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, streamId, hTaskId, pInfo->init, pInfo->start, false);
|
||||
return -1;// todo set the correct error code
|
||||
} else {
|
||||
stDebug("s-task:%s start to launch related fill-history task:0x%" PRIx64 "-0x%x", pTask->id.idStr,
|
||||
pTask->hTaskInfo.id.streamId, hTaskId);
|
||||
SLaunchHTaskInfo* pInfo = createHTaskLaunchInfo(pMeta, pTask->id.streamId, pTask->id.taskId, hStreamId, hTaskId);
|
||||
if (pInfo == NULL) {
|
||||
stError("s-task:%s failed to launch related fill-history task, since Out Of Memory", idStr);
|
||||
|
||||
streamMetaAddTaskLaunchResult(pMeta, hStreamId, hTaskId, pExecInfo->init, pExecInfo->start, false);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
// Set the execute conditions, including the query time window and the version range
|
||||
SStreamTask** pHTask = taosHashGet(pMeta->pTasksMap, &pTask->hTaskInfo.id, sizeof(pTask->hTaskInfo.id));
|
||||
if (pHTask == NULL) {
|
||||
stWarn("s-task:%s vgId:%d failed to launch history task:0x%x, since not built yet", pTask->id.idStr, pMeta->vgId,
|
||||
hTaskId);
|
||||
// set the launch time info
|
||||
streamTaskInitForLaunchHTask(&pTask->hTaskInfo);
|
||||
|
||||
SLaunchHTaskInfo* pInfo = createHTaskLaunchInfo(pTask->pMeta, pTask->id.streamId, pTask->id.taskId);
|
||||
if (pInfo == NULL) {
|
||||
stError("s-task:%s failed to launch related fill-history task, since Out Of Memory", pTask->id.idStr);
|
||||
// check for the timer
|
||||
if (pTask->hTaskInfo.pTimer == NULL) {
|
||||
int32_t ref = atomic_add_fetch_32(&pTask->status.timerActive, 1);
|
||||
pTask->hTaskInfo.pTimer = taosTmrStart(tryLaunchHistoryTask, WAIT_FOR_MINIMAL_INTERVAL, pInfo, streamTimer);
|
||||
|
||||
if (pTask->hTaskInfo.pTimer == NULL) {
|
||||
ref = atomic_sub_fetch_32(&pTask->status.timerActive, 1);
|
||||
stError("s-task:%s failed to start timer, related fill-history task not launched, ref:%d", idStr, ref);
|
||||
|
||||
taosMemoryFree(pInfo);
|
||||
streamMetaAddTaskLaunchResult(pMeta, hStreamId, hTaskId, pExecInfo->init, pExecInfo->start, false);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
streamTaskInitForLaunchHTask(&pTask->hTaskInfo);
|
||||
if (pTask->hTaskInfo.pTimer == NULL) {
|
||||
int32_t ref = atomic_add_fetch_32(&pTask->status.timerActive, 1);
|
||||
pTask->hTaskInfo.pTimer = taosTmrStart(tryLaunchHistoryTask, WAIT_FOR_MINIMAL_INTERVAL, pInfo, streamTimer);
|
||||
if (pTask->hTaskInfo.pTimer == NULL) {
|
||||
atomic_sub_fetch_32(&pTask->status.timerActive, 1);
|
||||
stError("s-task:%s failed to start timer, related fill-history task not launched, ref:%d", pTask->id.idStr,
|
||||
pTask->status.timerActive);
|
||||
taosMemoryFree(pInfo);
|
||||
} else {
|
||||
ASSERT(ref >= 1);
|
||||
stDebug("s-task:%s set timer active flag, ref:%d", pTask->id.idStr, ref);
|
||||
}
|
||||
} else { // timer exists
|
||||
ASSERT(pTask->status.timerActive >= 1);
|
||||
stDebug("s-task:%s set timer active flag, task timer not null", pTask->id.idStr);
|
||||
taosTmrReset(tryLaunchHistoryTask, WAIT_FOR_MINIMAL_INTERVAL, pInfo, streamTimer, &pTask->hTaskInfo.pTimer);
|
||||
}
|
||||
ASSERT(ref >= 1);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if ((*pHTask)->status.downstreamReady == 1) {
|
||||
stDebug("s-task:%s fill-history task is ready, no need to check downstream", (*pHTask)->id.idStr);
|
||||
} else {
|
||||
checkFillhistoryTaskStatus(pTask, *pHTask);
|
||||
stDebug("s-task:%s set timer active flag, ref:%d", idStr, ref);
|
||||
} else { // timer exists
|
||||
ASSERT(pTask->status.timerActive >= 1);
|
||||
stDebug("s-task:%s set timer active flag, task timer not null", idStr);
|
||||
taosTmrReset(tryLaunchHistoryTask, WAIT_FOR_MINIMAL_INTERVAL, pInfo, streamTimer, &pTask->hTaskInfo.pTimer);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// an fill history task needs to be started.
|
||||
int32_t streamLaunchFillHistoryTask(SStreamTask* pTask) {
|
||||
SStreamMeta* pMeta = pTask->pMeta;
|
||||
STaskExecStatisInfo* pExecInfo = &pTask->execInfo;
|
||||
const char* idStr = pTask->id.idStr;
|
||||
int64_t hStreamId = pTask->hTaskInfo.id.streamId;
|
||||
int32_t hTaskId = pTask->hTaskInfo.id.taskId;
|
||||
ASSERT(hTaskId != 0);
|
||||
|
||||
// check stream task status in the first place.
|
||||
SStreamTaskState* pStatus = streamTaskGetStatus(pTask);
|
||||
if (pStatus->state != TASK_STATUS__READY) {
|
||||
stDebug("s-task:%s not launch related fill-history task:0x%" PRIx64 "-0x%x, status:%s", idStr, hStreamId, hTaskId,
|
||||
pStatus->name);
|
||||
|
||||
streamMetaAddTaskLaunchResult(pMeta, hStreamId, hTaskId, pExecInfo->init, pExecInfo->start, false);
|
||||
return -1; // todo set the correct error code
|
||||
}
|
||||
|
||||
stDebug("s-task:%s start to launch related fill-history task:0x%" PRIx64 "-0x%x", idStr, hStreamId, hTaskId);
|
||||
|
||||
// Set the execute conditions, including the query time window and the version range
|
||||
streamMetaRLock(pMeta);
|
||||
SStreamTask** pHTask = taosHashGet(pMeta->pTasksMap, &pTask->hTaskInfo.id, sizeof(pTask->hTaskInfo.id));
|
||||
streamMetaRUnLock(pMeta);
|
||||
|
||||
if (pHTask != NULL) { // it is already added into stream meta store.
|
||||
SStreamTask* pHisTask = streamMetaAcquireTask(pMeta, hStreamId, hTaskId);
|
||||
if (pHisTask == NULL) {
|
||||
stDebug("s-task:%s failed acquire and start fill-history task, it may have been dropped/stopped", idStr);
|
||||
streamMetaAddTaskLaunchResult(pMeta, hStreamId, hTaskId, pExecInfo->init, pExecInfo->start, false);
|
||||
} else {
|
||||
if (pHisTask->status.downstreamReady == 1) { // it's ready now, do nothing
|
||||
stDebug("s-task:%s fill-history task is ready, no need to check downstream", pHisTask->id.idStr);
|
||||
streamMetaAddTaskLaunchResult(pMeta, hStreamId, hTaskId, pExecInfo->init, pExecInfo->start, true);
|
||||
} else { // exist, but not ready, continue check downstream task status
|
||||
checkFillhistoryTaskStatus(pTask, pHisTask);
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pHisTask);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
return launchNotBuiltFillHistoryTask(pTask);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t streamTaskScanHistoryDataComplete(SStreamTask* pTask) {
|
||||
if (streamTaskGetStatus(pTask)->state == TASK_STATUS__DROPPING) {
|
||||
return 0;
|
||||
|
@ -1058,97 +1119,3 @@ void streamTaskSetRangeStreamCalc(SStreamTask* pTask) {
|
|||
}
|
||||
}
|
||||
|
||||
void streamTaskPause(SStreamTask* pTask, SStreamMeta* pMeta) {
|
||||
streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_PAUSE);
|
||||
|
||||
int32_t num = atomic_add_fetch_32(&pMeta->numOfPausedTasks, 1);
|
||||
stInfo("vgId:%d s-task:%s pause stream task. pause task num:%d", pMeta->vgId, pTask->id.idStr, num);
|
||||
|
||||
// in case of fill-history task, stop the tsdb file scan operation.
|
||||
if (pTask->info.fillHistory == 1) {
|
||||
void* pExecutor = pTask->exec.pExecutor;
|
||||
qKillTask(pExecutor, TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
stDebug("vgId:%d s-task:%s set pause flag and pause task", pMeta->vgId, pTask->id.idStr);
|
||||
}
|
||||
|
||||
void streamTaskResume(SStreamTask* pTask) {
|
||||
SStreamTaskState prevState = *streamTaskGetStatus(pTask);
|
||||
SStreamMeta* pMeta = pTask->pMeta;
|
||||
|
||||
if (prevState.state == TASK_STATUS__PAUSE || prevState.state == TASK_STATUS__HALT) {
|
||||
streamTaskRestoreStatus(pTask);
|
||||
|
||||
char* pNew = streamTaskGetStatus(pTask)->name;
|
||||
if (prevState.state == TASK_STATUS__PAUSE) {
|
||||
int32_t num = atomic_sub_fetch_32(&pMeta->numOfPausedTasks, 1);
|
||||
stInfo("s-task:%s status:%s resume from %s, paused task(s):%d", pTask->id.idStr, pNew, prevState.name, num);
|
||||
} else {
|
||||
stInfo("s-task:%s status:%s resume from %s", pTask->id.idStr, pNew, prevState.name);
|
||||
}
|
||||
} else {
|
||||
stDebug("s-task:%s status:%s not in pause/halt status, no need to resume", pTask->id.idStr, prevState.name);
|
||||
}
|
||||
}
|
||||
|
||||
static void displayStatusInfo(SStreamMeta* pMeta, SHashObj* pTaskSet, bool succ) {
|
||||
int32_t vgId = pMeta->vgId;
|
||||
void* pIter = NULL;
|
||||
size_t keyLen = 0;
|
||||
|
||||
stInfo("vgId:%d %d tasks check-downstream completed %s", vgId, taosHashGetSize(pTaskSet),
|
||||
succ ? "success" : "failed");
|
||||
|
||||
while ((pIter = taosHashIterate(pTaskSet, pIter)) != NULL) {
|
||||
STaskInitTs* pInfo = pIter;
|
||||
void* key = taosHashGetKey(pIter, &keyLen);
|
||||
|
||||
SStreamTask** pTask1 = taosHashGet(pMeta->pTasksMap, key, sizeof(STaskId));
|
||||
if (pTask1 == NULL) {
|
||||
stInfo("s-task:0x%x is dropped already, %s", (int32_t)((STaskId*)key)->taskId, succ ? "success" : "failed");
|
||||
} else {
|
||||
stInfo("s-task:%s level:%d vgId:%d, init:%" PRId64 ", initEnd:%" PRId64 ", %s", (*pTask1)->id.idStr,
|
||||
(*pTask1)->info.taskLevel, vgId, pInfo->start, pInfo->end, pInfo->success ? "success" : "failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t streamMetaUpdateTaskDownstreamStatus(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t startTs,
|
||||
int64_t endTs, bool ready) {
|
||||
STaskStartInfo* pStartInfo = &pMeta->startInfo;
|
||||
STaskId id = {.streamId = streamId, .taskId = taskId};
|
||||
|
||||
streamMetaWLock(pMeta);
|
||||
SHashObj* pDst = ready ? pStartInfo->pReadyTaskSet : pStartInfo->pFailedTaskSet;
|
||||
|
||||
STaskInitTs initTs = {.start = startTs, .end = endTs, .success = ready};
|
||||
taosHashPut(pDst, &id, sizeof(id), &initTs, sizeof(STaskInitTs));
|
||||
|
||||
int32_t numOfTotal = streamMetaGetNumOfTasks(pMeta);
|
||||
int32_t numOfRecv = taosHashGetSize(pStartInfo->pReadyTaskSet) + taosHashGetSize(pStartInfo->pFailedTaskSet);
|
||||
|
||||
if (numOfRecv == numOfTotal) {
|
||||
pStartInfo->readyTs = taosGetTimestampMs();
|
||||
pStartInfo->elapsedTime = (pStartInfo->startTs != 0) ? pStartInfo->readyTs - pStartInfo->startTs : 0;
|
||||
|
||||
stDebug("vgId:%d all %d task(s) check downstream completed, last completed task:0x%x (succ:%d) startTs:%" PRId64
|
||||
", readyTs:%" PRId64 " total elapsed time:%.2fs",
|
||||
pMeta->vgId, numOfTotal, taskId, ready, pStartInfo->startTs, pStartInfo->readyTs,
|
||||
pStartInfo->elapsedTime / 1000.0);
|
||||
|
||||
// print the initialization elapsed time and info
|
||||
displayStatusInfo(pMeta, pStartInfo->pReadyTaskSet, true);
|
||||
displayStatusInfo(pMeta, pStartInfo->pFailedTaskSet, false);
|
||||
streamMetaResetStartInfo(pStartInfo);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
pStartInfo->completeFn(pMeta);
|
||||
} else {
|
||||
streamMetaWUnLock(pMeta);
|
||||
stDebug("vgId:%d recv check downstream results, s-task:0x%x succ:%d, received:%d, total:%d", pMeta->vgId, taskId,
|
||||
ready, numOfRecv, numOfTotal);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -435,7 +435,6 @@ int32_t streamStateAddIfNotExist(SStreamState* pState, const SWinKey* key, void*
|
|||
|
||||
int32_t streamStateReleaseBuf(SStreamState* pState, void* pVal, bool used) {
|
||||
// todo refactor
|
||||
stDebug("streamStateReleaseBuf");
|
||||
if (!pVal) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,55 @@ static int32_t addToTaskset(SArray* pArray, SStreamTask* pTask) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t doUpdateTaskEpset(SStreamTask* pTask, int32_t nodeId, SEpSet* pEpSet) {
|
||||
char buf[512] = {0};
|
||||
|
||||
if (pTask->info.nodeId == nodeId) { // execution task should be moved away
|
||||
epsetAssign(&pTask->info.epSet, pEpSet);
|
||||
EPSET_TO_STR(pEpSet, buf)
|
||||
stDebug("s-task:0x%x (vgId:%d) self node epset is updated %s", pTask->id.taskId, nodeId, buf);
|
||||
}
|
||||
|
||||
// check for the dispath info and the upstream task info
|
||||
int32_t level = pTask->info.taskLevel;
|
||||
if (level == TASK_LEVEL__SOURCE) {
|
||||
streamTaskUpdateDownstreamInfo(pTask, nodeId, pEpSet);
|
||||
} else if (level == TASK_LEVEL__AGG) {
|
||||
streamTaskUpdateUpstreamInfo(pTask, nodeId, pEpSet);
|
||||
streamTaskUpdateDownstreamInfo(pTask, nodeId, pEpSet);
|
||||
} else { // TASK_LEVEL__SINK
|
||||
streamTaskUpdateUpstreamInfo(pTask, nodeId, pEpSet);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void freeItem(void* p) {
|
||||
SStreamContinueExecInfo* pInfo = p;
|
||||
rpcFreeCont(pInfo->msg.pCont);
|
||||
}
|
||||
|
||||
static void freeUpstreamItem(void* p) {
|
||||
SStreamChildEpInfo** pInfo = p;
|
||||
taosMemoryFree(*pInfo);
|
||||
}
|
||||
|
||||
static SStreamChildEpInfo* createStreamTaskEpInfo(const SStreamTask* pTask) {
|
||||
SStreamChildEpInfo* pEpInfo = taosMemoryMalloc(sizeof(SStreamChildEpInfo));
|
||||
if (pEpInfo == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pEpInfo->childId = pTask->info.selfChildId;
|
||||
pEpInfo->epSet = pTask->info.epSet;
|
||||
pEpInfo->nodeId = pTask->info.nodeId;
|
||||
pEpInfo->taskId = pTask->id.taskId;
|
||||
pEpInfo->stage = -1;
|
||||
|
||||
return pEpInfo;
|
||||
}
|
||||
|
||||
SStreamTask* tNewStreamTask(int64_t streamId, int8_t taskLevel, bool fillHistory, int64_t triggerParam,
|
||||
SArray* pTaskList, bool hasFillhistory) {
|
||||
SStreamTask* pTask = (SStreamTask*)taosMemoryCalloc(1, sizeof(SStreamTask));
|
||||
|
@ -164,7 +213,7 @@ int32_t tDecodeStreamTask(SDecoder* pDecoder, SStreamTask* pTask) {
|
|||
|
||||
if (tStartDecode(pDecoder) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pTask->ver) < 0) return -1;
|
||||
if (pTask->ver != SSTREAM_TASK_VER) return -1;
|
||||
if (pTask->ver <= SSTREAM_TASK_INCOMPATIBLE_VER) return -1;
|
||||
|
||||
if (tDecodeI64(pDecoder, &pTask->id.streamId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pTask->id.taskId) < 0) return -1;
|
||||
|
@ -251,7 +300,7 @@ int32_t tDecodeStreamTaskChkInfo(SDecoder* pDecoder, SCheckpointInfo* pChkpInfo)
|
|||
|
||||
if (tStartDecode(pDecoder) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pChkpInfo->msgVer) < 0) return -1;
|
||||
// if (ver != SSTREAM_TASK_VER) return -1;
|
||||
// if (ver <= SSTREAM_TASK_INCOMPATIBLE_VER) return -1;
|
||||
|
||||
if (tDecodeI64(pDecoder, &skip64) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &skip32) < 0) return -1;
|
||||
|
@ -279,7 +328,7 @@ int32_t tDecodeStreamTaskId(SDecoder* pDecoder, STaskId* pTaskId) {
|
|||
int64_t ver;
|
||||
if (tStartDecode(pDecoder) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &ver) < 0) return -1;
|
||||
if (ver != SSTREAM_TASK_VER) return -1;
|
||||
if (ver <= SSTREAM_TASK_INCOMPATIBLE_VER) return -1;
|
||||
|
||||
if (tDecodeI64(pDecoder, &pTaskId->streamId) < 0) return -1;
|
||||
|
||||
|
@ -291,16 +340,6 @@ int32_t tDecodeStreamTaskId(SDecoder* pDecoder, STaskId* pTaskId) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void freeItem(void* p) {
|
||||
SStreamContinueExecInfo* pInfo = p;
|
||||
rpcFreeCont(pInfo->msg.pCont);
|
||||
}
|
||||
|
||||
static void freeUpstreamItem(void* p) {
|
||||
SStreamChildEpInfo** pInfo = p;
|
||||
taosMemoryFree(*pInfo);
|
||||
}
|
||||
|
||||
void tFreeStreamTask(SStreamTask* pTask) {
|
||||
char* p = NULL;
|
||||
int32_t taskId = pTask->id.taskId;
|
||||
|
@ -475,14 +514,6 @@ int32_t streamTaskInit(SStreamTask* pTask, SStreamMeta* pMeta, SMsgCb* pMsgCb, i
|
|||
}
|
||||
|
||||
taosThreadMutexInit(&pTask->lock, &attr);
|
||||
// if (pTask->info.fillHistory == 1) {
|
||||
// //
|
||||
// } else {
|
||||
|
||||
// }
|
||||
// if (streamTaskSetDb(pMeta, pTask) != 0) {
|
||||
// return -1;
|
||||
// }
|
||||
streamTaskOpenAllUpstreamInput(pTask);
|
||||
|
||||
pTask->outputInfo.pDownstreamUpdateList = taosArrayInit(4, sizeof(SDownstreamTaskEpset));
|
||||
|
@ -509,22 +540,6 @@ int32_t streamTaskGetNumOfDownstream(const SStreamTask* pTask) {
|
|||
}
|
||||
}
|
||||
|
||||
static SStreamChildEpInfo* createStreamTaskEpInfo(const SStreamTask* pTask) {
|
||||
SStreamChildEpInfo* pEpInfo = taosMemoryMalloc(sizeof(SStreamChildEpInfo));
|
||||
if (pEpInfo == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pEpInfo->childId = pTask->info.selfChildId;
|
||||
pEpInfo->epSet = pTask->info.epSet;
|
||||
pEpInfo->nodeId = pTask->info.nodeId;
|
||||
pEpInfo->taskId = pTask->id.taskId;
|
||||
pEpInfo->stage = -1;
|
||||
|
||||
return pEpInfo;
|
||||
}
|
||||
|
||||
int32_t streamTaskSetUpstreamInfo(SStreamTask* pTask, const SStreamTask* pUpstreamTask) {
|
||||
SStreamChildEpInfo* pEpInfo = createStreamTaskEpInfo(pUpstreamTask);
|
||||
if (pEpInfo == NULL) {
|
||||
|
@ -622,29 +637,6 @@ int32_t streamTaskStop(SStreamTask* pTask) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t doUpdateTaskEpset(SStreamTask* pTask, int32_t nodeId, SEpSet* pEpSet) {
|
||||
char buf[512] = {0};
|
||||
|
||||
if (pTask->info.nodeId == nodeId) { // execution task should be moved away
|
||||
epsetAssign(&pTask->info.epSet, pEpSet);
|
||||
EPSET_TO_STR(pEpSet, buf)
|
||||
stDebug("s-task:0x%x (vgId:%d) self node epset is updated %s", pTask->id.taskId, nodeId, buf);
|
||||
}
|
||||
|
||||
// check for the dispath info and the upstream task info
|
||||
int32_t level = pTask->info.taskLevel;
|
||||
if (level == TASK_LEVEL__SOURCE) {
|
||||
streamTaskUpdateDownstreamInfo(pTask, nodeId, pEpSet);
|
||||
} else if (level == TASK_LEVEL__AGG) {
|
||||
streamTaskUpdateUpstreamInfo(pTask, nodeId, pEpSet);
|
||||
streamTaskUpdateDownstreamInfo(pTask, nodeId, pEpSet);
|
||||
} else { // TASK_LEVEL__SINK
|
||||
streamTaskUpdateUpstreamInfo(pTask, nodeId, pEpSet);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t streamTaskUpdateEpsetInfo(SStreamTask* pTask, SArray* pNodeList) {
|
||||
STaskExecStatisInfo* p = &pTask->execInfo;
|
||||
|
||||
|
@ -677,7 +669,29 @@ void streamTaskResetUpstreamStageInfo(SStreamTask* pTask) {
|
|||
stDebug("s-task:%s reset all upstream tasks stage info", pTask->id.idStr);
|
||||
}
|
||||
|
||||
bool streamTaskAllUpstreamClosed(SStreamTask* pTask) {
|
||||
void streamTaskOpenAllUpstreamInput(SStreamTask* pTask) {
|
||||
int32_t num = taosArrayGetSize(pTask->upstreamInfo.pList);
|
||||
if (num == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SStreamChildEpInfo* pInfo = taosArrayGetP(pTask->upstreamInfo.pList, i);
|
||||
pInfo->dataAllowed = true;
|
||||
}
|
||||
|
||||
pTask->upstreamInfo.numOfClosed = 0;
|
||||
stDebug("s-task:%s opening up inputQ for %d upstream tasks", pTask->id.idStr, num);
|
||||
}
|
||||
|
||||
void streamTaskCloseUpstreamInput(SStreamTask* pTask, int32_t taskId) {
|
||||
SStreamChildEpInfo* pInfo = streamTaskGetUpstreamTaskEpInfo(pTask, taskId);
|
||||
if (pInfo != NULL) {
|
||||
pInfo->dataAllowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool streamTaskIsAllUpstreamClosed(SStreamTask* pTask) {
|
||||
return pTask->upstreamInfo.numOfClosed == taosArrayGetSize(pTask->upstreamInfo.pList);
|
||||
}
|
||||
|
||||
|
@ -760,7 +774,7 @@ int32_t streamBuildAndSendDropTaskMsg(SMsgCb* pMsgCb, int32_t vgId, SStreamTaskI
|
|||
return code;
|
||||
}
|
||||
|
||||
STaskId streamTaskExtractKey(const SStreamTask* pTask) {
|
||||
STaskId streamTaskGetTaskId(const SStreamTask* pTask) {
|
||||
STaskId id = {.streamId = pTask->id.streamId, .taskId = pTask->id.taskId};
|
||||
return id;
|
||||
}
|
||||
|
@ -801,3 +815,40 @@ void streamTaskStatusCopy(STaskStatusEntry* pDst, const STaskStatusEntry* pSrc)
|
|||
pDst->chkpointTransId = pSrc->chkpointTransId;
|
||||
}
|
||||
|
||||
void streamTaskPause(SStreamMeta* pMeta, SStreamTask* pTask) {
|
||||
streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_PAUSE);
|
||||
|
||||
int32_t num = atomic_add_fetch_32(&pMeta->numOfPausedTasks, 1);
|
||||
stInfo("vgId:%d s-task:%s pause stream task. pause task num:%d", pMeta->vgId, pTask->id.idStr, num);
|
||||
|
||||
// in case of fill-history task, stop the tsdb file scan operation.
|
||||
if (pTask->info.fillHistory == 1) {
|
||||
void* pExecutor = pTask->exec.pExecutor;
|
||||
qKillTask(pExecutor, TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
stDebug("vgId:%d s-task:%s set pause flag and pause task", pMeta->vgId, pTask->id.idStr);
|
||||
}
|
||||
|
||||
void streamTaskResume(SStreamTask* pTask) {
|
||||
SStreamTaskState prevState = *streamTaskGetStatus(pTask);
|
||||
SStreamMeta* pMeta = pTask->pMeta;
|
||||
|
||||
if (prevState.state == TASK_STATUS__PAUSE || prevState.state == TASK_STATUS__HALT) {
|
||||
streamTaskRestoreStatus(pTask);
|
||||
|
||||
char* pNew = streamTaskGetStatus(pTask)->name;
|
||||
if (prevState.state == TASK_STATUS__PAUSE) {
|
||||
int32_t num = atomic_sub_fetch_32(&pMeta->numOfPausedTasks, 1);
|
||||
stInfo("s-task:%s status:%s resume from %s, paused task(s):%d", pTask->id.idStr, pNew, prevState.name, num);
|
||||
} else {
|
||||
stInfo("s-task:%s status:%s resume from %s", pTask->id.idStr, pNew, prevState.name);
|
||||
}
|
||||
} else {
|
||||
stDebug("s-task:%s status:%s not in pause/halt status, no need to resume", pTask->id.idStr, prevState.name);
|
||||
}
|
||||
}
|
||||
|
||||
bool streamTaskIsSinkTask(const SStreamTask* pTask) {
|
||||
return pTask->info.taskLevel == TASK_LEVEL__SINK;
|
||||
}
|
||||
|
|
|
@ -527,8 +527,7 @@ bool hasRowBuff(SStreamFileState* pFileState, void* pKey, int32_t keyLen) {
|
|||
}
|
||||
|
||||
SStreamSnapshot* getSnapshot(SStreamFileState* pFileState) {
|
||||
int64_t mark = (INT64_MIN + pFileState->deleteMark >= pFileState->maxTs) ? INT64_MIN
|
||||
: pFileState->maxTs - pFileState->deleteMark;
|
||||
int64_t mark = (pFileState->deleteMark == INT64_MAX) ? INT64_MIN : pFileState->maxTs - pFileState->deleteMark;
|
||||
clearExpiredRowBuff(pFileState, mark, false);
|
||||
return pFileState->usedBuffs;
|
||||
}
|
||||
|
|
|
@ -414,6 +414,7 @@ void cliHandleResp(SCliConn* conn) {
|
|||
// buf's mem alread translated to transMsg.pCont
|
||||
if (!CONN_NO_PERSIST_BY_APP(conn)) {
|
||||
transMsg.info.handle = (void*)conn->refId;
|
||||
transMsg.info.refId = (int64_t)(void*)conn->refId;
|
||||
tDebug("%s conn %p ref by app", CONN_GET_INST_LABEL(conn), conn);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#include "zlib.h"
|
||||
|
||||
#ifdef WINDOWS
|
||||
#include <io.h>
|
||||
#include <WinBase.h>
|
||||
#include <io.h>
|
||||
#include <ktmw32.h>
|
||||
#include <windows.h>
|
||||
#define F_OK 0
|
||||
|
@ -50,7 +50,7 @@ typedef struct TdFile {
|
|||
TdThreadRwlock rwlock;
|
||||
int refId;
|
||||
HANDLE hFile;
|
||||
FILE* fp;
|
||||
FILE *fp;
|
||||
int32_t tdFileOptions;
|
||||
} TdFile;
|
||||
#else
|
||||
|
@ -230,7 +230,7 @@ int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime, int32_t *a
|
|||
int32_t code = _stati64(path, &fileStat);
|
||||
#else
|
||||
struct stat fileStat;
|
||||
int32_t code = stat(path, &fileStat);
|
||||
int32_t code = stat(path, &fileStat);
|
||||
#endif
|
||||
if (code < 0) {
|
||||
return code;
|
||||
|
@ -274,7 +274,7 @@ int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno) {
|
|||
return -1;
|
||||
}
|
||||
struct stat fileStat;
|
||||
int32_t code = fstat(pFile->fd, &fileStat);
|
||||
int32_t code = fstat(pFile->fd, &fileStat);
|
||||
if (code < 0) {
|
||||
printf("taosFStatFile run fstat fail.");
|
||||
return code;
|
||||
|
@ -374,7 +374,7 @@ int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
|
|||
DWORD bytesRead;
|
||||
if (!ReadFile(pFile->hFile, buf, count, &bytesRead, NULL)) {
|
||||
bytesRead = -1;
|
||||
}
|
||||
}
|
||||
#if FILE_WITH_LOCK
|
||||
taosThreadRwlockUnlock(&(pFile->rwlock));
|
||||
#endif
|
||||
|
@ -389,7 +389,7 @@ int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count) {
|
|||
taosThreadRwlockWrlock(&(pFile->rwlock));
|
||||
#endif
|
||||
|
||||
DWORD bytesWritten;
|
||||
DWORD bytesWritten;
|
||||
if (!WriteFile(pFile->hFile, buf, count, &bytesWritten, NULL)) {
|
||||
bytesWritten = -1;
|
||||
}
|
||||
|
@ -666,7 +666,7 @@ int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
|
|||
}
|
||||
int64_t leftbytes = count;
|
||||
int64_t readbytes;
|
||||
char * tbuf = (char *)buf;
|
||||
char *tbuf = (char *)buf;
|
||||
|
||||
while (leftbytes > 0) {
|
||||
#ifdef WINDOWS
|
||||
|
@ -716,7 +716,7 @@ int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count) {
|
|||
|
||||
int64_t nleft = count;
|
||||
int64_t nwritten = 0;
|
||||
char * tbuf = (char *)buf;
|
||||
char *tbuf = (char *)buf;
|
||||
|
||||
while (nleft > 0) {
|
||||
nwritten = write(pFile->fd, (void *)tbuf, (uint32_t)nleft);
|
||||
|
@ -1028,7 +1028,7 @@ int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, in
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif // WINDOWS
|
||||
#endif // WINDOWS
|
||||
|
||||
TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
|
||||
FILE *fp = NULL;
|
||||
|
@ -1056,7 +1056,7 @@ TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
|
|||
if (hFile != NULL) CloseHandle(hFile);
|
||||
#else
|
||||
if (fd >= 0) close(fd);
|
||||
#endif
|
||||
#endif
|
||||
if (fp != NULL) fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1067,7 +1067,7 @@ TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
|
|||
pFile->fp = fp;
|
||||
pFile->refId = 0;
|
||||
|
||||
#ifdef WINDOWS
|
||||
#ifdef WINDOWS
|
||||
pFile->hFile = hFile;
|
||||
pFile->tdFileOptions = tdFileOptions;
|
||||
// do nothing, since the property of pmode is set with _O_TEMPORARY; the OS will recycle
|
||||
|
@ -1137,7 +1137,7 @@ int64_t taosPReadFile(TdFilePtr pFile, void *buf, int64_t count, int64_t offset)
|
|||
#endif
|
||||
return -1;
|
||||
}
|
||||
DWORD ret = 0;
|
||||
DWORD ret = 0;
|
||||
OVERLAPPED ol = {0};
|
||||
ol.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 0x20);
|
||||
ol.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);
|
||||
|
@ -1179,7 +1179,7 @@ int32_t taosFsyncFile(TdFilePtr pFile) {
|
|||
if (pFile->hFile != NULL) {
|
||||
if (pFile->tdFileOptions & TD_FILE_WRITE_THROUGH) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return !FlushFileBuffers(pFile->hFile);
|
||||
#else
|
||||
if (pFile->fd >= 0) {
|
||||
|
@ -1204,7 +1204,7 @@ bool taosValidFile(TdFilePtr pFile) {
|
|||
return pFile != NULL && pFile->hFile != NULL;
|
||||
#else
|
||||
return pFile != NULL && pFile->fd > 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t taosUmaskFile(int32_t maskVal) {
|
||||
|
@ -1249,7 +1249,7 @@ int64_t taosGetLineFile(TdFilePtr pFile, char **__restrict ptrBuf) {
|
|||
}
|
||||
|
||||
bufferSize += 512;
|
||||
void* newBuf = taosMemoryRealloc(*ptrBuf, bufferSize);
|
||||
void *newBuf = taosMemoryRealloc(*ptrBuf, bufferSize);
|
||||
if (newBuf == NULL) {
|
||||
taosMemoryFreeClear(*ptrBuf);
|
||||
return -1;
|
||||
|
@ -1363,7 +1363,7 @@ int32_t taosCompressFile(char *srcFileName, char *destFileName) {
|
|||
|
||||
cmp_end:
|
||||
if (pFile) {
|
||||
taosCloseFile(&pFile);
|
||||
taosCloseFile(&pFile);
|
||||
}
|
||||
if (pSrcFile) {
|
||||
taosCloseFile(&pSrcFile);
|
||||
|
@ -1386,3 +1386,15 @@ int32_t taosSetFileHandlesLimit() {
|
|||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t taosLinkFile(char *src, char *dst) {
|
||||
#ifndef WINDOWS
|
||||
if (link(src, dst) != 0) {
|
||||
if (errno == EXDEV || errno == ENOTSUP) {
|
||||
return -1;
|
||||
}
|
||||
return errno;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
"user": "root",
|
||||
"password": "taosdata",
|
||||
"connection_pool_size": 8,
|
||||
"num_of_records_per_req": 2000,
|
||||
"num_of_records_per_req": 3000,
|
||||
"prepared_rand": 3000,
|
||||
"thread_count": 2,
|
||||
"create_table_thread_count": 1,
|
||||
"confirm_parameter_prompt": "no",
|
||||
|
|
|
@ -28,7 +28,9 @@ from frame import *
|
|||
|
||||
|
||||
class TDTestCase(TBase):
|
||||
|
||||
updatecfgDict = {
|
||||
"countAlwaysReturnValue" : "0"
|
||||
}
|
||||
|
||||
def insertData(self):
|
||||
tdLog.info(f"insert data.")
|
||||
|
@ -42,6 +44,10 @@ class TDTestCase(TBase):
|
|||
self.insert_rows = 100000
|
||||
self.timestamp_step = 10000
|
||||
|
||||
# create count check table
|
||||
sql = f"create table {self.db}.ta(ts timestamp, age int) tags(area int)"
|
||||
tdSql.execute(sql)
|
||||
|
||||
def doAction(self):
|
||||
tdLog.info(f"do action.")
|
||||
self.flushDb()
|
||||
|
@ -64,7 +70,10 @@ class TDTestCase(TBase):
|
|||
selid = random.choice(vgids)
|
||||
self.balanceVGroupLeaderOn(selid)
|
||||
|
||||
|
||||
# check count always return value
|
||||
sql = f"select count(*) from {self.db}.ta"
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(0) # countAlwaysReturnValue is false
|
||||
|
||||
# run
|
||||
def run(self):
|
||||
|
|
|
@ -75,7 +75,6 @@ class TDTestCase(TBase):
|
|||
|
||||
# others
|
||||
etool.exeBinFile("taos", f'-N 200 -l 2048 -s "{sql}" ', wait=False)
|
||||
etool.exeBinFile("taos", f'-n server', wait=False)
|
||||
|
||||
|
||||
def doTaosd(self):
|
||||
|
@ -86,11 +85,11 @@ class TDTestCase(TBase):
|
|||
# -s
|
||||
sdb = "./sdb.json"
|
||||
eos.delFile(sdb)
|
||||
etool.runBinFile("taosd", f"-s -c {cfg}")
|
||||
self.checkFileExist(sdb)
|
||||
etool.exeBinFile("taosd", f"-s -c {cfg}")
|
||||
|
||||
|
||||
# -C
|
||||
etool.runBinFile("taosd", "-C")
|
||||
etool.exeBinFile("taosd", "-C")
|
||||
# -k
|
||||
rets = etool.runBinFile("taosd", "-C")
|
||||
self.checkListNotEmpty(rets)
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"filetype": "insert",
|
||||
"cfgdir": "/etc/taos",
|
||||
"host": "127.0.0.1",
|
||||
"port": 6030,
|
||||
"user": "root",
|
||||
"password": "taosdata",
|
||||
"connection_pool_size": 8,
|
||||
"num_of_records_per_req": 4000,
|
||||
"prepared_rand": 10000,
|
||||
"thread_count": 3,
|
||||
"create_table_thread_count": 1,
|
||||
"confirm_parameter_prompt": "no",
|
||||
"databases": [
|
||||
{
|
||||
"dbinfo": {
|
||||
"name": "db",
|
||||
"drop": "yes",
|
||||
"vgroups": 3,
|
||||
"replica": 3,
|
||||
"duration":"3d",
|
||||
"wal_retention_period": 1,
|
||||
"wal_retention_size": 1,
|
||||
"stt_trigger": 1
|
||||
},
|
||||
"super_tables": [
|
||||
{
|
||||
"name": "stb",
|
||||
"child_table_exists": "no",
|
||||
"childtable_count": 6,
|
||||
"insert_rows": 100000,
|
||||
"childtable_prefix": "d",
|
||||
"insert_mode": "taosc",
|
||||
"timestamp_step": 30000,
|
||||
"start_timestamp":"2023-10-01 10:00:00",
|
||||
"columns": [
|
||||
{ "type": "bool", "name": "bc"},
|
||||
{ "type": "float", "name": "fc" },
|
||||
{ "type": "double", "name": "dc"},
|
||||
{ "type": "tinyint", "name": "ti"},
|
||||
{ "type": "smallint", "name": "si" },
|
||||
{ "type": "int", "name": "ic" },
|
||||
{ "type": "bigint", "name": "bi" },
|
||||
{ "type": "utinyint", "name": "uti"},
|
||||
{ "type": "usmallint", "name": "usi"},
|
||||
{ "type": "uint", "name": "ui" },
|
||||
{ "type": "ubigint", "name": "ubi"},
|
||||
{ "type": "binary", "name": "bin", "len": 8},
|
||||
{ "type": "nchar", "name": "nch", "len": 16}
|
||||
],
|
||||
"tags": [
|
||||
{"type": "tinyint", "name": "groupid","max": 10,"min": 1},
|
||||
{"name": "location","type": "binary", "len": 16, "values":
|
||||
["San Francisco", "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View","Sunnyvale", "Santa Clara", "Cupertino"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import time
|
||||
import random
|
||||
|
||||
import taos
|
||||
import frame
|
||||
import frame.etool
|
||||
|
||||
|
||||
from frame.log import *
|
||||
from frame.cases import *
|
||||
from frame.sql import *
|
||||
from frame.caseBase import *
|
||||
from frame import *
|
||||
|
||||
|
||||
class TDTestCase(TBase):
|
||||
updatecfgDict = {
|
||||
"keepColumnName" : "1",
|
||||
"ttlChangeOnWrite" : "1",
|
||||
"querySmaOptimize": "1"
|
||||
}
|
||||
|
||||
def insertData(self):
|
||||
tdLog.info(f"insert data.")
|
||||
# taosBenchmark run
|
||||
jfile = etool.curFile(__file__, "query_basic.json")
|
||||
etool.benchMark(json=jfile)
|
||||
|
||||
tdSql.execute(f"use {self.db}")
|
||||
tdSql.execute("select database();")
|
||||
# set insert data information
|
||||
self.childtable_count = 6
|
||||
self.insert_rows = 100000
|
||||
self.timestamp_step = 30000
|
||||
|
||||
|
||||
def doQuery(self):
|
||||
tdLog.info(f"do query.")
|
||||
|
||||
# __group_key
|
||||
sql = f"select count(*),_group_key(uti),uti from {self.stb} partition by uti;"
|
||||
tdSql.execute(sql)
|
||||
tdSql.checkRows(251)
|
||||
|
||||
sql = f"select count(*),_group_key(usi) from {self.stb} group by usi;"
|
||||
tdSql.execute(sql)
|
||||
tdSql.checkRows(997)
|
||||
|
||||
# tail
|
||||
sql1 = "select ts,ui from d0 order by ts desc limit 5 offset 2;"
|
||||
sql2 = "select ts,tail(ui,5,2) from d0;"
|
||||
self.checkSameResult(sql1, sql2)
|
||||
|
||||
# uninqe
|
||||
sql1 = "select distinct uti from d0 order by uti;"
|
||||
sql2 = "select UNIQUE(uti) from d0 order by uti asc;"
|
||||
self.checkSameResult(sql1, sql2)
|
||||
|
||||
# top
|
||||
sql1 = "select top(bi,10) from stb;"
|
||||
sql2 = "select bi from stb where bi is not null order by bi desc limit 10;"
|
||||
self.checkSameResult(sql1, sql2)
|
||||
|
||||
# run
|
||||
def run(self):
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
|
||||
# insert data
|
||||
self.insertData()
|
||||
|
||||
# check insert data correct
|
||||
self.checkInsertCorrect()
|
||||
|
||||
# check
|
||||
self.checkConsistency("usi")
|
||||
|
||||
# do action
|
||||
self.doQuery()
|
||||
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -7,6 +7,7 @@
|
|||
"password": "taosdata",
|
||||
"connection_pool_size": 8,
|
||||
"num_of_records_per_req": 2000,
|
||||
"prepared_rand": 1000,
|
||||
"thread_count": 2,
|
||||
"create_table_thread_count": 1,
|
||||
"confirm_parameter_prompt": "no",
|
||||
|
|
|
@ -14,11 +14,12 @@ import time
|
|||
# Auto Gen class
|
||||
#
|
||||
class AutoGen:
|
||||
def __init__(self):
|
||||
def __init__(self, fillOne=False):
|
||||
self.ts = 1600000000000
|
||||
self.batch_size = 100
|
||||
seed = time.time() % 10000
|
||||
random.seed(seed)
|
||||
self.fillOne = fillOne
|
||||
|
||||
# set start ts
|
||||
def set_start_ts(self, ts):
|
||||
|
@ -87,6 +88,23 @@ class AutoGen:
|
|||
|
||||
return datas
|
||||
|
||||
# fill one data
|
||||
def fillone_data(self, i, marr):
|
||||
datas = ""
|
||||
for c in marr:
|
||||
if datas != "":
|
||||
datas += ","
|
||||
|
||||
if c == 0:
|
||||
datas += "%d" % (self.ts + i)
|
||||
elif c == 12 or c == 13: # binary
|
||||
datas += '"1"'
|
||||
else:
|
||||
datas += '1'
|
||||
|
||||
return datas
|
||||
|
||||
|
||||
# generate specail wide random string
|
||||
def random_string(self, count):
|
||||
letters = string.ascii_letters
|
||||
|
@ -96,7 +114,6 @@ class AutoGen:
|
|||
def create_db(self, dbname, vgroups = 2, replica = 1):
|
||||
self.dbname = dbname
|
||||
tdSql.execute(f'create database {dbname} vgroups {vgroups} replica {replica}')
|
||||
tdSql.execute(f'use {dbname}')
|
||||
|
||||
# create table or stable
|
||||
def create_stable(self, stbname, tag_cnt, column_cnt, binary_len, nchar_len):
|
||||
|
@ -106,7 +123,7 @@ class AutoGen:
|
|||
self.mtags, tags = self.gen_columns_sql("t", tag_cnt, binary_len, nchar_len)
|
||||
self.mcols, cols = self.gen_columns_sql("c", column_cnt - 1, binary_len, nchar_len)
|
||||
|
||||
sql = f"create table {stbname} (ts timestamp, {cols}) tags({tags})"
|
||||
sql = f"create table {self.dbname}.{stbname} (ts timestamp, {cols}) tags({tags})"
|
||||
tdSql.execute(sql)
|
||||
|
||||
# create child table
|
||||
|
@ -115,7 +132,7 @@ class AutoGen:
|
|||
self.child_name = prename
|
||||
for i in range(cnt):
|
||||
tags_data = self.gen_data(i, self.mtags)
|
||||
sql = f"create table {prename}{i} using {stbname} tags({tags_data})"
|
||||
sql = f"create table {self.dbname}.{prename}{i} using {self.dbname}.{stbname} tags({tags_data})"
|
||||
tdSql.execute(sql)
|
||||
|
||||
tdLog.info(f"create child tables {cnt} ok")
|
||||
|
@ -127,17 +144,20 @@ class AutoGen:
|
|||
|
||||
# loop do
|
||||
for i in range(cnt):
|
||||
value = self.gen_data(i, self.mcols)
|
||||
if self.fillOne :
|
||||
value = self.fillone_data(i, self.mcols)
|
||||
else:
|
||||
value = self.gen_data(i, self.mcols)
|
||||
ts += step
|
||||
values += f"({ts},{value}) "
|
||||
if batch_size == 1 or (i > 0 and i % batch_size == 0) :
|
||||
sql = f"insert into {child_name} values {values}"
|
||||
sql = f"insert into {self.dbname}.{child_name} values {values}"
|
||||
tdSql.execute(sql)
|
||||
values = ""
|
||||
|
||||
# end batch
|
||||
if values != "":
|
||||
sql = f"insert into {child_name} values {values}"
|
||||
sql = f"insert into {self.dbname}.{child_name} values {values}"
|
||||
tdSql.execute(sql)
|
||||
tdLog.info(f" insert data i={i}")
|
||||
values = ""
|
||||
|
@ -159,5 +179,3 @@ class AutoGen:
|
|||
self.insert_data_child(name, cnt, self.batch_size, 0)
|
||||
|
||||
tdLog.info(f" insert same timestamp ok, child table={self.child_cnt} insert rows={cnt}")
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import os
|
|||
import time
|
||||
import datetime
|
||||
import random
|
||||
import copy
|
||||
|
||||
from frame.log import *
|
||||
from frame.sql import *
|
||||
|
@ -135,8 +136,9 @@ class TBase:
|
|||
tdSql.checkAgg(sql, self.childtable_count)
|
||||
|
||||
# check step
|
||||
sql = f"select count(*) from (select diff(ts) as dif from {self.stb} partition by tbname) where dif != {self.timestamp_step}"
|
||||
tdSql.checkAgg(sql, 0)
|
||||
sql = f"select * from (select diff(ts) as dif from {self.stb} partition by tbname) where dif != {self.timestamp_step}"
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(0)
|
||||
|
||||
# save agg result
|
||||
def snapshotAgg(self):
|
||||
|
@ -156,6 +158,71 @@ class TBase:
|
|||
tdSql.checkAgg(self.sqlFirst, self.first)
|
||||
tdSql.checkAgg(self.sqlLast, self.last)
|
||||
|
||||
# self check
|
||||
def checkConsistency(self, col):
|
||||
# top with max
|
||||
sql = f"select max({col}) from {self.stb}"
|
||||
expect = tdSql.getFirstValue(sql)
|
||||
sql = f"select top({col}, 5) from {self.stb}"
|
||||
tdSql.checkFirstValue(sql, expect)
|
||||
|
||||
#bottom with min
|
||||
sql = f"select min({col}) from {self.stb}"
|
||||
expect = tdSql.getFirstValue(sql)
|
||||
sql = f"select bottom({col}, 5) from {self.stb}"
|
||||
tdSql.checkFirstValue(sql, expect)
|
||||
|
||||
# order by asc limit 1 with first
|
||||
sql = f"select last({col}) from {self.stb}"
|
||||
expect = tdSql.getFirstValue(sql)
|
||||
sql = f"select {col} from {self.stb} order by _c0 desc limit 1"
|
||||
tdSql.checkFirstValue(sql, expect)
|
||||
|
||||
# order by desc limit 1 with last
|
||||
sql = f"select first({col}) from {self.stb}"
|
||||
expect = tdSql.getFirstValue(sql)
|
||||
sql = f"select {col} from {self.stb} order by _c0 asc limit 1"
|
||||
tdSql.checkFirstValue(sql, expect)
|
||||
|
||||
|
||||
# check sql1 is same result with sql2
|
||||
def checkSameResult(self, sql1, sql2):
|
||||
tdLog.info(f"sql1={sql1}")
|
||||
tdLog.info(f"sql2={sql2}")
|
||||
tdLog.info("compare sql1 same with sql2 ...")
|
||||
|
||||
# sql
|
||||
rows1 = tdSql.query(sql1,queryTimes=2)
|
||||
res1 = copy.deepcopy(tdSql.queryResult)
|
||||
|
||||
tdSql.query(sql2,queryTimes=2)
|
||||
res2 = tdSql.queryResult
|
||||
|
||||
rowlen1 = len(res1)
|
||||
rowlen2 = len(res2)
|
||||
errCnt = 0
|
||||
|
||||
if rowlen1 != rowlen2:
|
||||
tdLog.exit(f"both row count not equal. rowlen1={rowlen1} rowlen2={rowlen2} ")
|
||||
return False
|
||||
|
||||
for i in range(rowlen1):
|
||||
row1 = res1[i]
|
||||
row2 = res2[i]
|
||||
collen1 = len(row1)
|
||||
collen2 = len(row2)
|
||||
if collen1 != collen2:
|
||||
tdLog.exit(f"both col count not equal. collen1={collen1} collen2={collen2}")
|
||||
return False
|
||||
for j in range(collen1):
|
||||
if row1[j] != row2[j]:
|
||||
tdLog.info(f"error both column value not equal. row={i} col={j} col1={row1[j]} col2={row2[j]} .")
|
||||
errCnt += 1
|
||||
|
||||
if errCnt > 0:
|
||||
tdLog.exit(f"sql2 column value different with sql1. different count ={errCnt} ")
|
||||
|
||||
tdLog.info("sql1 same result with sql2.")
|
||||
|
||||
#
|
||||
# get db information
|
||||
|
|
|
@ -549,6 +549,12 @@ class TDSql:
|
|||
def getFirstValue(self, sql) :
|
||||
self.query(sql)
|
||||
return self.getData(0, 0)
|
||||
|
||||
# expect first value
|
||||
def checkFirstValue(self, sql, expect):
|
||||
self.query(sql)
|
||||
self.checkData(0, 0, expect)
|
||||
|
||||
|
||||
def get_times(self, time_str, precision="ms"):
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
,,y,system-test,./pytest.sh python3 ./test.py -f 8-stream/pause_resume_test.py
|
||||
#,,n,system-test,python3 ./test.py -f 8-stream/vnode_restart.py -N 4
|
||||
#,,n,system-test,python3 ./test.py -f 8-stream/snode_restart.py -N 4
|
||||
#,,n,system-test,python3 ./test.py -f 8-stream/snode_restart_with_checkpoint.py -N 4
|
||||
,,n,system-test,python3 ./test.py -f 8-stream/snode_restart_with_checkpoint.py -N 4
|
||||
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/tbname_vgroup.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/count_interval.py
|
||||
|
@ -146,6 +146,10 @@
|
|||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py -Q 2
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py -Q 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py -Q 4
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/td-28068.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/td-28068.py -Q 2
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/td-28068.py -Q 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/td-28068.py -Q 4
|
||||
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreDnode.py -N 5 -M 3 -i False
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreVnode.py -N 5 -M 3 -i False
|
||||
|
@ -422,6 +426,11 @@ e
|
|||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/last_row.py -R
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/last.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/last.py -R
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/last_and_last_row.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/last_and_last_row.py -R
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/last_and_last_row.py -Q 2
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/last_and_last_row.py -Q 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/last_and_last_row.py -Q 4
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/leastsquares.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/leastsquares.py -R
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/length.py
|
||||
|
|
|
@ -14,11 +14,12 @@ import time
|
|||
# Auto Gen class
|
||||
#
|
||||
class AutoGen:
|
||||
def __init__(self):
|
||||
def __init__(self, fillOne=False):
|
||||
self.ts = 1600000000000
|
||||
self.batch_size = 100
|
||||
seed = time.time() % 10000
|
||||
random.seed(seed)
|
||||
self.fillOne = fillOne
|
||||
|
||||
# set start ts
|
||||
def set_start_ts(self, ts):
|
||||
|
@ -87,6 +88,23 @@ class AutoGen:
|
|||
|
||||
return datas
|
||||
|
||||
# fill one data
|
||||
def fillone_data(self, i, marr):
|
||||
datas = ""
|
||||
for c in marr:
|
||||
if datas != "":
|
||||
datas += ","
|
||||
|
||||
if c == 0:
|
||||
datas += "%d" % (self.ts + i)
|
||||
elif c == 12 or c == 13: # binary
|
||||
datas += '"1"'
|
||||
else:
|
||||
datas += '1'
|
||||
|
||||
return datas
|
||||
|
||||
|
||||
# generate specail wide random string
|
||||
def random_string(self, count):
|
||||
letters = string.ascii_letters
|
||||
|
@ -96,7 +114,7 @@ class AutoGen:
|
|||
def create_db(self, dbname, vgroups = 2, replica = 1):
|
||||
self.dbname = dbname
|
||||
tdSql.execute(f'create database {dbname} vgroups {vgroups} replica {replica}')
|
||||
tdSql.execute(f'use {dbname}')
|
||||
tdSql.execute(f"use {dbname}")
|
||||
|
||||
# create table or stable
|
||||
def create_stable(self, stbname, tag_cnt, column_cnt, binary_len, nchar_len):
|
||||
|
@ -106,7 +124,7 @@ class AutoGen:
|
|||
self.mtags, tags = self.gen_columns_sql("t", tag_cnt, binary_len, nchar_len)
|
||||
self.mcols, cols = self.gen_columns_sql("c", column_cnt - 1, binary_len, nchar_len)
|
||||
|
||||
sql = f"create table {stbname} (ts timestamp, {cols}) tags({tags})"
|
||||
sql = f"create table {self.dbname}.{stbname} (ts timestamp, {cols}) tags({tags})"
|
||||
tdSql.execute(sql)
|
||||
|
||||
# create child table
|
||||
|
@ -115,7 +133,7 @@ class AutoGen:
|
|||
self.child_name = prename
|
||||
for i in range(cnt):
|
||||
tags_data = self.gen_data(i, self.mtags)
|
||||
sql = f"create table {prename}{i} using {stbname} tags({tags_data})"
|
||||
sql = f"create table {self.dbname}.{prename}{i} using {self.dbname}.{stbname} tags({tags_data})"
|
||||
tdSql.execute(sql)
|
||||
|
||||
tdLog.info(f"create child tables {cnt} ok")
|
||||
|
@ -127,17 +145,20 @@ class AutoGen:
|
|||
|
||||
# loop do
|
||||
for i in range(cnt):
|
||||
value = self.gen_data(i, self.mcols)
|
||||
if self.fillOne :
|
||||
value = self.fillone_data(i, self.mcols)
|
||||
else:
|
||||
value = self.gen_data(i, self.mcols)
|
||||
ts += step
|
||||
values += f"({ts},{value}) "
|
||||
if batch_size == 1 or (i > 0 and i % batch_size == 0) :
|
||||
sql = f"insert into {child_name} values {values}"
|
||||
sql = f"insert into {self.dbname}.{child_name} values {values}"
|
||||
tdSql.execute(sql)
|
||||
values = ""
|
||||
|
||||
# end batch
|
||||
if values != "":
|
||||
sql = f"insert into {child_name} values {values}"
|
||||
sql = f"insert into {self.dbname}.{child_name} values {values}"
|
||||
tdSql.execute(sql)
|
||||
tdLog.info(f" insert data i={i}")
|
||||
values = ""
|
||||
|
|
|
@ -1845,6 +1845,23 @@ class TDCom:
|
|||
if i == 1:
|
||||
self.record_history_ts = ts_value
|
||||
|
||||
def get_subtable(self, tbname_pre):
|
||||
tdSql.query(f'show tables')
|
||||
tbname_list = list(map(lambda x:x[0], tdSql.queryResult))
|
||||
for tbname in tbname_list:
|
||||
if tbname_pre in tbname:
|
||||
return tbname
|
||||
|
||||
def get_subtable_wait(self, tbname_pre):
|
||||
tbname = self.get_subtable(tbname_pre)
|
||||
latency = 0
|
||||
while tbname is None:
|
||||
tbname = self.get_subtable(tbname_pre)
|
||||
if latency < self.stream_timeout:
|
||||
latency += 1
|
||||
time.sleep(1)
|
||||
return tbname
|
||||
|
||||
def is_json(msg):
|
||||
if isinstance(msg, str):
|
||||
try:
|
||||
|
|
|
@ -88,7 +88,7 @@ class TDSql:
|
|||
self.affectedRows = self.cursor.execute(sql)
|
||||
return self.affectedRows
|
||||
except Exception as e:
|
||||
tdLog.notice("Try to execute sql again, query times: %d "%i)
|
||||
tdLog.notice("Try to execute sql again, execute times: %d "%i)
|
||||
if i == queryTimes:
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
args = (caller.filename, caller.lineno, sql, repr(e))
|
||||
|
|
|
@ -3,22 +3,22 @@
|
|||
set +e
|
||||
#set -x
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
TD_OS="Darwin"
|
||||
TD_OS="Darwin"
|
||||
else
|
||||
OS=$(cat /etc/*-release | grep "^NAME=" | cut -d= -f2)
|
||||
len=$(echo ${#OS})
|
||||
len=$((len-2))
|
||||
TD_OS=$(echo -ne ${OS:1:${len}} | cut -d" " -f1)
|
||||
OS=$(cat /etc/*-release | grep "^NAME=" | cut -d= -f2)
|
||||
len=$(echo ${#OS})
|
||||
len=$((len - 2))
|
||||
TD_OS=$(echo -ne ${OS:1:${len}} | cut -d" " -f1)
|
||||
fi
|
||||
|
||||
if [[ "$TD_OS" == "Alpine" ]]; then
|
||||
echo -e "os is Alpine,skip check Asan"
|
||||
exit 0
|
||||
echo -e "os is Alpine,skip check Asan"
|
||||
exit 0
|
||||
fi
|
||||
unset LD_PRELOAD
|
||||
SCRIPT_DIR=`dirname $0`
|
||||
SCRIPT_DIR=$(dirname $0)
|
||||
cd $SCRIPT_DIR/../
|
||||
SCRIPT_DIR=`pwd`
|
||||
SCRIPT_DIR=$(pwd)
|
||||
|
||||
IN_TDINTERNAL="community"
|
||||
if [[ "$SCRIPT_DIR" == *"$IN_TDINTERNAL"* ]]; then
|
||||
|
@ -27,31 +27,28 @@ else
|
|||
cd ../../
|
||||
fi
|
||||
|
||||
TAOS_DIR=`pwd`
|
||||
TAOS_DIR=$(pwd)
|
||||
LOG_DIR=$TAOS_DIR/sim/asan
|
||||
|
||||
error_num=$(cat ${LOG_DIR}/*.asan | grep "ERROR" | wc -l)
|
||||
|
||||
|
||||
error_num=`cat ${LOG_DIR}/*.asan | grep "ERROR" | wc -l`
|
||||
|
||||
archOs=`arch`
|
||||
if [[ $archOs =~ "aarch64" ]]; then
|
||||
echo "arm64 check mem leak"
|
||||
memory_leak=`cat ${LOG_DIR}/*.asan | grep "Direct leak" | grep -v "Direct leak of 32 byte"| wc -l`
|
||||
memory_count=`cat ${LOG_DIR}/*.asan | grep "Direct leak of 32 byte"| wc -l`
|
||||
archOs=$(arch)
|
||||
if [[ $archOs =~ "aarch64" ]]; then
|
||||
echo "arm64 check mem leak"
|
||||
memory_leak=$(cat ${LOG_DIR}/*.asan | grep "Direct leak" | grep -v "Direct leak of 32 byte" | wc -l)
|
||||
memory_count=$(cat ${LOG_DIR}/*.asan | grep "Direct leak of 32 byte" | wc -l)
|
||||
|
||||
if [ $memory_count -eq $error_num ] && [ $memory_leak -eq 0 ]; then
|
||||
echo "reset error_num to 0, ignore: __cxa_thread_atexit_impl leak"
|
||||
error_num=0
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "os check mem leak"
|
||||
memory_leak=`cat ${LOG_DIR}/*.asan | grep "Direct leak" | wc -l`
|
||||
memory_leak=$(cat ${LOG_DIR}/*.asan | grep "Direct leak" | wc -l)
|
||||
fi
|
||||
|
||||
|
||||
indirect_leak=`cat ${LOG_DIR}/*.asan | grep "Indirect leak" | wc -l`
|
||||
python_error=`cat ${LOG_DIR}/*.info | grep -w "stack" | wc -l`
|
||||
indirect_leak=$(cat ${LOG_DIR}/*.asan | grep "Indirect leak" | wc -l)
|
||||
python_error=$(cat ${LOG_DIR}/*.info | grep -w "stack" | wc -l)
|
||||
|
||||
# ignore
|
||||
|
||||
|
@ -64,18 +61,18 @@ python_error=`cat ${LOG_DIR}/*.info | grep -w "stack" | wc -l`
|
|||
# /root/TDengine/source/libs/scalar/src/sclfunc.c:772:11: runtime error: 3.52344e+09 is outside the range of representable values of type 'int'
|
||||
# /root/TDengine/source/libs/scalar/src/sclfunc.c:753:11: runtime error: 4.75783e+11 is outside the range of representable values of type 'short int'
|
||||
|
||||
# TD-20569
|
||||
# TD-20569
|
||||
# /root/TDengine/source/libs/function/src/builtinsimpl.c:856:29: runtime error: signed integer overflow: 9223372036854775806 + 9223372036854775805 cannot be represented in type 'long int'
|
||||
# /root/TDengine/source/libs/scalar/src/sclvector.c:1075:66: runtime error: signed integer overflow: 9223372034707292160 + 1668838476672 cannot be represented in type 'long int'
|
||||
# /root/TDengine/source/common/src/tdataformat.c:1876:7: runtime error: signed integer overflow: 8252423483843671206 + 2406154664059062870 cannot be represented in type 'long int'
|
||||
# /home/chr/TDengine/source/libs/scalar/src/filter.c:3149:14: runtime error: applying non-zero offset 18446744073709551615 to null pointer
|
||||
|
||||
# /home/chr/TDengine/source/libs/scalar/src/filter.c:3149:14: runtime error: applying non-zero offset 18446744073709551615 to null pointer
|
||||
# /home/chr/TDengine/source/libs/scalar/src/filter.c:3149:14: runtime error: applying non-zero offset 18446744073709551615 to null pointer
|
||||
# /home/TDinternal/community/source/libs/scalar/src/sclvector.c:1109:66: runtime error: signed integer overflow: 9223372034707292160 + 1676867897049 cannot be represented in type 'long int'
|
||||
|
||||
|
||||
#0 0x7f2d64f5a808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
|
||||
#1 0x7f2d63fcf459 in strerror /build/glibc-SzIz7B/glibc-2.31/string/strerror.c:38
|
||||
runtime_error=`cat ${LOG_DIR}/*.asan | grep "runtime error" | grep -v "trees.c:873" | grep -v "sclfunc.c.*outside the range of representable values of type"| grep -v "signed integer overflow" |grep -v "strerror.c"| grep -v "asan_malloc_linux.cc" |grep -v "strerror.c"|wc -l`
|
||||
runtime_error=$(cat ${LOG_DIR}/*.asan | grep "runtime error" | grep -v "trees.c:873" | grep -v "sclfunc.c.*outside the range of representable values of type" | grep -v "signed integer overflow" | grep -v "strerror.c" | grep -v "asan_malloc_linux.cc" | grep -v "strerror.c" | wc -l)
|
||||
|
||||
echo -e "\033[44;32;1m"asan error_num: $error_num"\033[0m"
|
||||
echo -e "\033[44;32;1m"asan memory_leak: $memory_leak"\033[0m"
|
||||
|
@ -86,10 +83,10 @@ echo -e "\033[44;32;1m"asan python error: $python_error"\033[0m"
|
|||
let "errors=$error_num+$memory_leak+$indirect_leak+$runtime_error+$python_error"
|
||||
|
||||
if [ $errors -eq 0 ]; then
|
||||
echo -e "\033[44;32;1m"no asan errors"\033[0m"
|
||||
echo -e "\033[44;32;1m"no asan errors"\033[0m"
|
||||
exit 0
|
||||
else
|
||||
echo -e "\033[44;31;1m"asan total errors: $errors"\033[0m"
|
||||
echo -e "\033[44;31;1m"asan total errors: $errors"\033[0m"
|
||||
if [ $python_error -ne 0 ]; then
|
||||
cat ${LOG_DIR}/*.info
|
||||
fi
|
||||
|
|
|
@ -55,7 +55,7 @@ if $rows != 1 then
|
|||
return -1
|
||||
endi
|
||||
sql explain select count(*), last_row(f1), last(f1) from sta;
|
||||
if $data00 != @-> Aggragate (functions=3 width=24 input_order=desc )@ then
|
||||
if $data00 != @-> Merge (columns=3 width=24 input_order=unknown output_order=unknown mode=column)@ then
|
||||
return -1
|
||||
endi
|
||||
sql_error select count(*), last_row(f1), min(f1), f1 from sta;
|
||||
|
|
|
@ -48,16 +48,6 @@ if $rows != 2 then
|
|||
goto loop0
|
||||
endi
|
||||
|
||||
if $data00 != aaa-t1 then
|
||||
print =====data00=$data00
|
||||
goto loop0
|
||||
endi
|
||||
|
||||
if $data10 != aaa-t2 then
|
||||
print =====data10=$data10
|
||||
goto loop0
|
||||
endi
|
||||
|
||||
$loop_count = 0
|
||||
loop1:
|
||||
|
||||
|
@ -264,17 +254,6 @@ if $rows != 2 then
|
|||
goto loop6
|
||||
endi
|
||||
|
||||
if $data00 != tbn-t1 then
|
||||
print =====data00=$data00
|
||||
goto loop6
|
||||
endi
|
||||
|
||||
if $data10 != tbn-t2 then
|
||||
print =====data10=$data10
|
||||
goto loop6
|
||||
endi
|
||||
|
||||
|
||||
print ===== step5
|
||||
print ===== tag name + table name
|
||||
|
||||
|
@ -312,21 +291,6 @@ if $rows != 3 then
|
|||
goto loop7
|
||||
endi
|
||||
|
||||
if $data00 != tbn-t1 then
|
||||
print =====data00=$data00
|
||||
goto loop7
|
||||
endi
|
||||
|
||||
if $data10 != tbn-t2 then
|
||||
print =====data10=$data10
|
||||
goto loop7
|
||||
endi
|
||||
|
||||
if $data20 != tbn-t3 then
|
||||
print =====data20=$data20
|
||||
goto loop7
|
||||
endi
|
||||
|
||||
$loop_count = 0
|
||||
loop8:
|
||||
|
||||
|
|
|
@ -47,16 +47,6 @@ if $rows != 2 then
|
|||
goto loop0
|
||||
endi
|
||||
|
||||
if $data00 != aaa-1 then
|
||||
print =====data00=$data00
|
||||
goto loop0
|
||||
endi
|
||||
|
||||
if $data10 != aaa-2 then
|
||||
print =====data10=$data10
|
||||
goto loop0
|
||||
endi
|
||||
|
||||
$loop_count = 0
|
||||
loop1:
|
||||
|
||||
|
@ -264,16 +254,6 @@ if $rows != 2 then
|
|||
goto loop6
|
||||
endi
|
||||
|
||||
if $data00 != tbn-1 then
|
||||
print =====data00=$data00
|
||||
goto loop6
|
||||
endi
|
||||
|
||||
if $data10 != tbn-2 then
|
||||
print =====data10=$data10
|
||||
goto loop6
|
||||
endi
|
||||
|
||||
print ===== step5
|
||||
print ===== tag name + table name
|
||||
|
||||
|
@ -311,21 +291,6 @@ if $rows != 3 then
|
|||
goto loop7
|
||||
endi
|
||||
|
||||
if $data00 != tbn-t1 then
|
||||
print =====data00=$data00
|
||||
goto loop7
|
||||
endi
|
||||
|
||||
if $data10 != tbn-t2 then
|
||||
print =====data10=$data10
|
||||
goto loop7
|
||||
endi
|
||||
|
||||
if $data20 != tbn-t3 then
|
||||
print =====data20=$data20
|
||||
goto loop7
|
||||
endi
|
||||
|
||||
$loop_count = 0
|
||||
loop8:
|
||||
|
||||
|
|
|
@ -415,11 +415,6 @@ if $data00 != aaa then
|
|||
goto loop9
|
||||
endi
|
||||
|
||||
if $data10 != aaa-1 then
|
||||
print =====data00=$data00
|
||||
goto loop9
|
||||
endi
|
||||
|
||||
$loop_count = 0
|
||||
loop10:
|
||||
|
||||
|
|
|
@ -162,6 +162,16 @@ class TDTestCase:
|
|||
case6 = {"col": "c9"}
|
||||
self.checkcsum(**case6)
|
||||
|
||||
# unsigned check
|
||||
case61 = {"col": "c11"}
|
||||
self.checkcsum(**case61)
|
||||
case62 = {"col": "c12"}
|
||||
self.checkcsum(**case62)
|
||||
case63 = {"col": "c13"}
|
||||
self.checkcsum(**case63)
|
||||
case64 = {"col": "c14"}
|
||||
self.checkcsum(**case64)
|
||||
|
||||
# case7~8: nested query
|
||||
case7 = {"table_expr": "(select ts,c1 from db.stb1 order by ts, tbname )"}
|
||||
self.checkcsum(**case7)
|
||||
|
@ -317,14 +327,14 @@ class TDTestCase:
|
|||
f"insert into t{i} values ("
|
||||
f"{basetime + (j+1)*10 + i * msec_per_min}, {random.randint(-200, -1)}, {random.uniform(200, -1)}, {basetime + random.randint(-200, -1)}, "
|
||||
f"'binary_{j}', {random.uniform(-200, -1)}, {random.choice([0,1])}, {random.randint(-200,-1)}, "
|
||||
f"{random.randint(-200, -1)}, {random.randint(-127, -1)}, 'nchar_{j}' )"
|
||||
f"{random.randint(-200, -1)}, {random.randint(-127, -1)}, 'nchar_{j}', {j},{j},{j},{j} )"
|
||||
)
|
||||
|
||||
tdSql.execute(
|
||||
f"insert into t{i} values ("
|
||||
f"{basetime - (j+1) * 10 + i * msec_per_min}, {random.randint(1, 200)}, {random.uniform(1, 200)}, {basetime - random.randint(1, 200)}, "
|
||||
f"'binary_{j}_1', {random.uniform(1, 200)}, {random.choice([0, 1])}, {random.randint(1,200)}, "
|
||||
f"{random.randint(1,200)}, {random.randint(1,127)}, 'nchar_{j}_1' )"
|
||||
f"{random.randint(1,200)}, {random.randint(1,127)}, 'nchar_{j}_1', {j*2},{j*2},{j*2},{j*2} )"
|
||||
)
|
||||
tdSql.execute(
|
||||
f"insert into tt{i} values ( {basetime-(j+1) * 10 + i * msec_per_min}, {random.randint(1, 200)} )"
|
||||
|
@ -340,8 +350,8 @@ class TDTestCase:
|
|||
tdSql.execute(
|
||||
"create stable db.stb1 (\
|
||||
ts timestamp, c1 int, c2 float, c3 timestamp, c4 binary(16), c5 double, c6 bool, \
|
||||
c7 bigint, c8 smallint, c9 tinyint, c10 nchar(16)\
|
||||
) \
|
||||
c7 bigint, c8 smallint, c9 tinyint, c10 nchar(16),\
|
||||
c11 int unsigned, c12 smallint unsigned, c13 tinyint unsigned, c14 bigint unsigned) \
|
||||
tags(st1 int)"
|
||||
)
|
||||
tdSql.execute(
|
||||
|
@ -373,10 +383,10 @@ class TDTestCase:
|
|||
|
||||
tdLog.printNoPrefix("######## insert data in the range near the max(bigint/double):")
|
||||
self.csum_test_table(tbnum)
|
||||
tdSql.execute(f"insert into db.t1(ts, c1,c2,c5,c7) values "
|
||||
f"({nowtime - (per_table_rows + 1) * 10 + i * msec_per_min}, {2**31-1}, {3.4*10**38}, {1.7*10**308}, {2**63-1})")
|
||||
tdSql.execute(f"insert into db.t1(ts, c1,c2,c5,c7) values "
|
||||
f"({nowtime - (per_table_rows + 2) * 10 + i * msec_per_min}, {2**31-1}, {3.4*10**38}, {1.7*10**308}, {2**63-1})")
|
||||
tdSql.execute(f"insert into db.t1(ts, c1,c2,c5,c7,c11) values "
|
||||
f"({nowtime - (per_table_rows + 1) * 10 + i * msec_per_min}, {2**31-1}, {3.4*10**38}, {1.7*10**308}, {2**63-1}, 128)")
|
||||
tdSql.execute(f"insert into db.t1(ts, c1,c2,c5,c7,c11) values "
|
||||
f"({nowtime - (per_table_rows + 2) * 10 + i * msec_per_min}, {2**31-1}, {3.4*10**38}, {1.7*10**308}, {2**63-1}, 129)")
|
||||
self.csum_current_query()
|
||||
self.csum_error_query()
|
||||
|
||||
|
@ -460,7 +470,7 @@ class TDTestCase:
|
|||
tdSql.checkRows(40)
|
||||
|
||||
# bug need fix
|
||||
tdSql.query("select tbname , csum(c1) from db.stb1 partition by tbname")
|
||||
tdSql.query("select tbname , csum(c1), csum(c12) from db.stb1 partition by tbname")
|
||||
tdSql.checkRows(40)
|
||||
tdSql.query("select tbname , csum(st1) from db.stb1 partition by tbname")
|
||||
tdSql.checkRows(70)
|
||||
|
@ -468,7 +478,7 @@ class TDTestCase:
|
|||
tdSql.checkRows(7)
|
||||
|
||||
# partition by tags
|
||||
tdSql.query("select st1 , csum(c1) from db.stb1 partition by st1")
|
||||
tdSql.query("select st1 , csum(c1), csum(c13) from db.stb1 partition by st1")
|
||||
tdSql.checkRows(40)
|
||||
tdSql.query("select csum(c1) from db.stb1 partition by st1")
|
||||
tdSql.checkRows(40)
|
||||
|
|
|
@ -0,0 +1,660 @@
|
|||
import datetime
|
||||
import sys
|
||||
from util.log import *
|
||||
from util.cases import *
|
||||
from util.sql import *
|
||||
from util.dnodes import tdDnodes
|
||||
from math import inf
|
||||
|
||||
|
||||
class TDTestCase:
|
||||
def init(self, conn, logSql, replicaVer=1):
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor(), True)
|
||||
|
||||
def check_explain_res_has_row(self, plan_str_expect: str, rows, sql):
|
||||
plan_found = False
|
||||
for row in rows:
|
||||
if str(row).find(plan_str_expect) >= 0:
|
||||
tdLog.debug("plan: [%s] found in: [%s]" % (plan_str_expect, str(row)))
|
||||
plan_found = True
|
||||
break
|
||||
if not plan_found:
|
||||
tdLog.exit("plan: %s not found in res: [%s] in sql: %s" % (plan_str_expect, str(rows), sql))
|
||||
|
||||
def check_explain_res_no_row(self, plan_str_not_expect: str, res, sql):
|
||||
for row in res:
|
||||
if str(row).find(plan_str_not_expect) >= 0:
|
||||
tdLog.exit('plan: [%s] found in: [%s] for sql: %s' % (plan_str_not_expect, str(row), sql))
|
||||
|
||||
def explain_sql(self, sql: str):
|
||||
sql = "explain " + sql
|
||||
tdSql.query(sql, queryTimes=1)
|
||||
return tdSql.queryResult
|
||||
|
||||
def explain_and_check_res(self, sqls, hasLastRowScanRes):
|
||||
for sql, has_last in zip(sqls, hasLastRowScanRes):
|
||||
res = self.explain_sql(sql)
|
||||
if has_last == 1:
|
||||
self.check_explain_res_has_row("Last Row Scan", res, sql)
|
||||
else:
|
||||
self.check_explain_res_no_row("Last Row Scan", res, sql)
|
||||
|
||||
def none_model_test(self):
|
||||
tdSql.execute("drop database if exists last_test_none_model ;")
|
||||
tdSql.execute("create database last_test_none_model cachemodel 'none';")
|
||||
tdSql.execute("use last_test_none_model;")
|
||||
tdSql.execute("create stable last_test_none_model.st(ts timestamp, id int) tags(tid int);")
|
||||
tdSql.execute("create table last_test_none_model.test_t1 using last_test_none_model.st tags(1);")
|
||||
tdSql.execute("create table last_test_none_model.test_t2 using last_test_none_model.st tags(2);")
|
||||
tdSql.execute("create table last_test_none_model.test_t3 using last_test_none_model.st tags(3);")
|
||||
tdSql.execute("create table last_test_none_model.test_t4 using last_test_none_model.st tags(4);")
|
||||
|
||||
maxRange = 100
|
||||
# 2023-11-13 00:00:00.000
|
||||
startTs = 1699804800000
|
||||
for i in range(maxRange):
|
||||
insertSqlString = "insert into last_test_none_model.test_t1 values(%d, %d);" % (startTs + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
|
||||
last_ts = startTs + maxRange
|
||||
tdSql.execute("insert into last_test_none_model.test_t1 (ts) values(%d)" % (last_ts))
|
||||
sql = f'select last_row(ts), last(*) from last_test_none_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_no_row("Last Row Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), last_row(id), last(id) from last_test_none_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, None)
|
||||
tdSql.checkData(0, 3, maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_no_row("Last Row Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last(*), last_row(ts), count(*) from last_test_none_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, maxRange - 1)
|
||||
tdSql.checkData(0, 2, last_ts)
|
||||
tdSql.checkData(0, 3, maxRange + 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_no_row("Last Row Scan", explain_res, sql)
|
||||
|
||||
tdSql.error(f'select last(*), last_row(ts), ts from last_test_none_model.test_t1;')
|
||||
|
||||
sql = f'select last_row(ts), last(ts), count(*) , last_row(id), last(id), last(*) from last_test_none_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, maxRange + 1)
|
||||
tdSql.checkData(0, 3, None)
|
||||
tdSql.checkData(0, 4, maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts)
|
||||
tdSql.checkData(0, 6, maxRange - 1)
|
||||
|
||||
|
||||
startTs2 = startTs + 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 2 * maxRange
|
||||
insertSqlString = "insert into last_test_none_model.test_t2 values(%d, %d);" % (startTs2 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
last_ts2 = startTs2 + maxRange
|
||||
|
||||
startTs3 = startTs + 2 * 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 3 * maxRange
|
||||
insertSqlString = "insert into last_test_none_model.test_t3 values(%d, %d);" % (startTs3 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
last_ts3 = startTs3 + 4 * maxRange - 1
|
||||
|
||||
startTs4 = startTs + 3 * 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 4 * maxRange
|
||||
insertSqlString = "insert into last_test_none_model.test_t4 values(%d, %d);" % (startTs4 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
|
||||
last_ts4 = startTs4 + 5 * maxRange - 1
|
||||
sql = f'select last_row(ts), last(*) from last_test_none_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 5 * maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_no_row("Last Row Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), last_row(id), last(id) from last_test_none_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_no_row("Last Row Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last(*), last_row(ts), count(*) from last_test_none_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 2, last_ts4)
|
||||
tdSql.checkData(0, 3, 4 * maxRange + 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_no_row("Last Row Scan", explain_res, sql)
|
||||
|
||||
tdSql.error(f'select last(*), last_row(ts), ts from last_test_none_model.st;')
|
||||
|
||||
sql = f'select last_row(ts), last(ts), count(*) , last_row(id), last(id), last(*) from last_test_none_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 4 * maxRange + 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 4, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts4)
|
||||
tdSql.checkData(0, 6, 5 * maxRange - 1)
|
||||
|
||||
sql = f'select last_row(1), last(2), count(*) , last_row(id), last(id), last(*) from last_test_none_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.checkData(0, 1, 2)
|
||||
tdSql.checkData(0, 2, 4 * maxRange + 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 4, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts4)
|
||||
tdSql.checkData(0, 6, 5 * maxRange - 1)
|
||||
|
||||
tdSql.execute("drop table if exists last_test_none_model.test_t4 ;")
|
||||
tdSql.execute("drop table if exists last_test_none_model.test_t3 ;")
|
||||
tdSql.execute("drop table if exists last_test_none_model.test_t2 ;")
|
||||
tdSql.execute("drop table if exists last_test_none_model.test_t1 ;")
|
||||
tdSql.execute("drop stable if exists last_test_none_model.st;")
|
||||
tdSql.execute("drop database if exists last_test_none_model;")
|
||||
|
||||
def last_value_model_test(self):
|
||||
tdSql.execute("create database last_test_last_value_model cachemodel 'last_value' ;")
|
||||
tdSql.execute("use last_test_last_value_model;")
|
||||
tdSql.execute("create stable last_test_last_value_model.st(ts timestamp, id int) tags(tid int);")
|
||||
tdSql.execute("create table last_test_last_value_model.test_t1 using last_test_last_value_model.st tags(1);")
|
||||
tdSql.execute("create table last_test_last_value_model.test_t2 using last_test_last_value_model.st tags(2);")
|
||||
tdSql.execute("create table last_test_last_value_model.test_t3 using last_test_last_value_model.st tags(3);")
|
||||
tdSql.execute("create table last_test_last_value_model.test_t4 using last_test_last_value_model.st tags(4);")
|
||||
|
||||
maxRange = 100
|
||||
# 2023-11-13 00:00:00.000
|
||||
startTs = 1699804800000
|
||||
for i in range(maxRange):
|
||||
insertSqlString = "insert into last_test_last_value_model.test_t1 values(%d, %d);" % (startTs + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
|
||||
last_ts = startTs + maxRange
|
||||
tdSql.execute("insert into last_test_last_value_model.test_t1 (ts) values(%d)" % (last_ts))
|
||||
sql = f'select last_row(ts), last(*) from last_test_last_value_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), last_row(id), last(id) from last_test_last_value_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, None)
|
||||
tdSql.checkData(0, 3, maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last(*), last_row(ts), count(*) from last_test_last_value_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, maxRange - 1)
|
||||
tdSql.checkData(0, 2, last_ts)
|
||||
tdSql.checkData(0, 3, maxRange + 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), count(*) , last_row(id), last(id), last(*) from last_test_last_value_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, maxRange + 1)
|
||||
tdSql.checkData(0, 3, None)
|
||||
tdSql.checkData(0, 4, maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts)
|
||||
tdSql.checkData(0, 6, maxRange - 1)
|
||||
|
||||
startTs2 = startTs + 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 2 * maxRange
|
||||
insertSqlString = "insert into last_test_last_value_model.test_t2 values(%d, %d);" % (startTs2 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
last_ts2 = startTs2 + maxRange
|
||||
|
||||
startTs3 = startTs + 2 * 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 3 * maxRange
|
||||
insertSqlString = "insert into last_test_last_value_model.test_t3 values(%d, %d);" % (startTs3 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
last_ts3 = startTs3 + 4 * maxRange - 1
|
||||
|
||||
startTs4 = startTs + 3 * 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 4 * maxRange
|
||||
insertSqlString = "insert into last_test_last_value_model.test_t4 values(%d, %d);" % (startTs4 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
|
||||
last_ts4 = startTs4 + 5 * maxRange - 1
|
||||
sql = f'select last_row(ts), last(*) from last_test_last_value_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 5 * maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), last_row(id), last(id) from last_test_last_value_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last(*), last_row(ts), count(*) from last_test_last_value_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 2, last_ts4)
|
||||
tdSql.checkData(0, 3, 4 * maxRange + 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
tdSql.error(f'select last(*), last_row(ts), ts from last_test_last_value_model.st;')
|
||||
|
||||
sql = f'select last_row(ts), last(ts), count(*) , last_row(id), last(id), last(*) from last_test_last_value_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 4 * maxRange + 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 4, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts4)
|
||||
tdSql.checkData(0, 6, 5 * maxRange - 1)
|
||||
|
||||
sql = f'select last_row(1), last(2), count(*) , last_row(id), last(id), last(*) from last_test_last_value_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.checkData(0, 1, 2)
|
||||
tdSql.checkData(0, 2, 4 * maxRange + 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 4, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts4)
|
||||
tdSql.checkData(0, 6, 5 * maxRange - 1)
|
||||
|
||||
tdSql.execute("drop table if exists last_test_last_value_model.test_t4 ;")
|
||||
tdSql.execute("drop table if exists last_test_last_value_model.test_t3 ;")
|
||||
tdSql.execute("drop table if exists last_test_last_value_model.test_t2 ;")
|
||||
tdSql.execute("drop table if exists last_test_last_value_model.test_t1 ;")
|
||||
tdSql.execute("drop stable if exists last_test_last_value_model.st;")
|
||||
tdSql.execute("drop database if exists last_test_last_value_model;")
|
||||
|
||||
def last_row_model_test(self):
|
||||
tdSql.execute("create database last_test_last_row_model cachemodel 'last_row';")
|
||||
tdSql.execute("use last_test_last_row_model;")
|
||||
tdSql.execute("create stable last_test_last_row_model.st(ts timestamp, id int) tags(tid int);")
|
||||
tdSql.execute("create table last_test_last_row_model.test_t1 using last_test_last_row_model.st tags(1);")
|
||||
tdSql.execute("create table last_test_last_row_model.test_t2 using last_test_last_row_model.st tags(2);")
|
||||
tdSql.execute("create table last_test_last_row_model.test_t3 using last_test_last_row_model.st tags(3);")
|
||||
tdSql.execute("create table last_test_last_row_model.test_t4 using last_test_last_row_model.st tags(4);")
|
||||
|
||||
maxRange = 100
|
||||
# 2023-11-13 00:00:00.000
|
||||
startTs = 1699804800000
|
||||
for i in range(maxRange):
|
||||
insertSqlString = "insert into last_test_last_row_model.test_t1 values(%d, %d);" % (startTs + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
|
||||
last_ts = startTs + maxRange
|
||||
tdSql.execute("insert into last_test_last_row_model.test_t1 (ts) values(%d)" % (last_ts))
|
||||
sql = f'select last_row(ts), last(*) from last_test_last_row_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), last_row(id), last(id) from last_test_last_row_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, None)
|
||||
tdSql.checkData(0, 3, maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last(*), last_row(ts), count(*) from last_test_last_row_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, maxRange - 1)
|
||||
tdSql.checkData(0, 2, last_ts)
|
||||
tdSql.checkData(0, 3, maxRange + 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), count(*) , last_row(id), last(id), last(*) from last_test_last_row_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, maxRange + 1)
|
||||
tdSql.checkData(0, 3, None)
|
||||
tdSql.checkData(0, 4, maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts)
|
||||
tdSql.checkData(0, 6, maxRange - 1)
|
||||
|
||||
startTs2 = startTs + 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 2 * maxRange
|
||||
insertSqlString = "insert into last_test_last_row_model.test_t2 values(%d, %d);" % (startTs2 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
last_ts2 = startTs2 + maxRange
|
||||
|
||||
startTs3 = startTs + 2 * 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 3 * maxRange
|
||||
insertSqlString = "insert into last_test_last_row_model.test_t3 values(%d, %d);" % (startTs3 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
last_ts3 = startTs3 + 4 * maxRange - 1
|
||||
|
||||
startTs4 = startTs + 3 * 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 4 * maxRange
|
||||
insertSqlString = "insert into last_test_last_row_model.test_t4 values(%d, %d);" % (startTs4 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
|
||||
last_ts4 = startTs4 + 5 * maxRange - 1
|
||||
sql = f'select last_row(ts), last(*) from last_test_last_row_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 5 * maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), last_row(id), last(id) from last_test_last_row_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last(*), last_row(ts), count(*) from last_test_last_row_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 2, last_ts4)
|
||||
tdSql.checkData(0, 3, 4 * maxRange + 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_has_row("Table Scan", explain_res, sql)
|
||||
|
||||
tdSql.error(f'select last(*), last_row(ts), ts from last_test_last_row_model.st;')
|
||||
|
||||
sql = f'select last_row(ts), last(ts), count(*) , last_row(id), last(id), last(*) from last_test_last_row_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 4 * maxRange + 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 4, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts4)
|
||||
tdSql.checkData(0, 6, 5 * maxRange - 1)
|
||||
|
||||
sql = f'select last_row(1), last(2), count(*) , last_row(id), last(id), last(*) from last_test_last_row_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.checkData(0, 1, 2)
|
||||
tdSql.checkData(0, 2, 4 * maxRange + 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 4, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts4)
|
||||
tdSql.checkData(0, 6, 5 * maxRange - 1)
|
||||
|
||||
tdSql.execute("drop table if exists last_test_last_row_model.test_t4 ;")
|
||||
tdSql.execute("drop table if exists last_test_last_row_model.test_t3 ;")
|
||||
tdSql.execute("drop table if exists last_test_last_row_model.test_t2 ;")
|
||||
tdSql.execute("drop table if exists last_test_last_row_model.test_t1 ;")
|
||||
tdSql.execute("drop stable if exists last_test_last_row_model.st;")
|
||||
tdSql.execute("drop database if exists last_test_last_row_model;")
|
||||
|
||||
def both_model_test(self):
|
||||
tdSql.execute("create database last_test_both_model cachemodel 'both';")
|
||||
tdSql.execute("use last_test_both_model;")
|
||||
tdSql.execute("create stable last_test_both_model.st(ts timestamp, id int) tags(tid int);")
|
||||
tdSql.execute("create table last_test_both_model.test_t1 using last_test_both_model.st tags(1);")
|
||||
tdSql.execute("create table last_test_both_model.test_t2 using last_test_both_model.st tags(2);")
|
||||
tdSql.execute("create table last_test_both_model.test_t3 using last_test_both_model.st tags(3);")
|
||||
tdSql.execute("create table last_test_both_model.test_t4 using last_test_both_model.st tags(4);")
|
||||
|
||||
maxRange = 100
|
||||
# 2023-11-13 00:00:00.000
|
||||
startTs = 1699804800000
|
||||
for i in range(maxRange):
|
||||
insertSqlString = "insert into last_test_both_model.test_t1 values(%d, %d);" % (startTs + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
|
||||
last_ts = startTs + maxRange
|
||||
tdSql.execute("insert into last_test_both_model.test_t1 (ts) values(%d)" % (last_ts))
|
||||
sql = f'select last_row(ts), last(*) from last_test_both_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_no_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), last_row(id), last(id) from last_test_both_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, None)
|
||||
tdSql.checkData(0, 3, maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_no_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last(*), last_row(ts), count(*) from last_test_both_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, maxRange - 1)
|
||||
tdSql.checkData(0, 2, last_ts)
|
||||
tdSql.checkData(0, 3, maxRange + 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), count(*) , last_row(id), last(id), last(*) from last_test_both_model.test_t1;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts)
|
||||
tdSql.checkData(0, 1, last_ts)
|
||||
tdSql.checkData(0, 2, maxRange + 1)
|
||||
tdSql.checkData(0, 3, None)
|
||||
tdSql.checkData(0, 4, maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts)
|
||||
tdSql.checkData(0, 6, maxRange - 1)
|
||||
|
||||
tdSql.error(f'select last(*), last_row(ts), ts from last_test_both_model.test_t1;')
|
||||
|
||||
startTs2 = startTs + 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 2 * maxRange
|
||||
insertSqlString = "insert into last_test_both_model.test_t2 values(%d, %d);" % (startTs2 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
last_ts2 = startTs2 + maxRange
|
||||
|
||||
startTs3 = startTs + 2 * 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 3 * maxRange
|
||||
insertSqlString = "insert into last_test_both_model.test_t3 values(%d, %d);" % (startTs3 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
last_ts3 = startTs3 + 4 * maxRange - 1
|
||||
|
||||
startTs4 = startTs + 3 * 86400000
|
||||
for i in range(maxRange):
|
||||
i = i + 4 * maxRange
|
||||
insertSqlString = "insert into last_test_both_model.test_t4 values(%d, %d);" % (startTs4 + i, i)
|
||||
tdSql.execute(insertSqlString)
|
||||
|
||||
last_ts4 = startTs4 + 5 * maxRange - 1
|
||||
|
||||
sql = f'select last_row(ts), last(*) from last_test_both_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 5 * maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_no_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last_row(ts), last(ts), last_row(id), last(id) from last_test_both_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
self.check_explain_res_no_row("Table Scan", explain_res, sql)
|
||||
|
||||
sql = f'select last(*), last_row(ts), count(*) from last_test_both_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, 5 * maxRange - 1)
|
||||
#tdSql.checkData(0, 2, last_ts4)
|
||||
tdSql.checkData(0, 3, 4 * maxRange + 1)
|
||||
|
||||
explain_res = self.explain_sql(sql)
|
||||
self.check_explain_res_has_row("Last Row Scan", explain_res, sql)
|
||||
|
||||
tdSql.error(f'select last(*), last_row(ts), ts from last_test_both_model.st;')
|
||||
|
||||
sql = f'select last_row(ts), last(ts), count(*) , last_row(id), last(id), last(*) from last_test_both_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, last_ts4)
|
||||
tdSql.checkData(0, 1, last_ts4)
|
||||
tdSql.checkData(0, 2, 4 * maxRange + 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 4, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts4)
|
||||
tdSql.checkData(0, 6, 5 * maxRange - 1)
|
||||
|
||||
sql = f'select last_row(1), last(2), count(*) , last_row(id), last(id), last(*) from last_test_both_model.st;'
|
||||
tdSql.query(sql)
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.checkData(0, 1, 2)
|
||||
tdSql.checkData(0, 2, 4 * maxRange + 1)
|
||||
tdSql.checkData(0, 3, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 4, 5 * maxRange - 1)
|
||||
tdSql.checkData(0, 5, last_ts4)
|
||||
tdSql.checkData(0, 6, 5 * maxRange - 1)
|
||||
|
||||
tdSql.execute("drop table if exists last_test_both_model.test_t4 ;")
|
||||
tdSql.execute("drop table if exists last_test_both_model.test_t3 ;")
|
||||
tdSql.execute("drop table if exists last_test_both_model.test_t2 ;")
|
||||
tdSql.execute("drop table if exists last_test_both_model.test_t1 ;")
|
||||
tdSql.execute("drop stable if exists last_test_both_model.st;")
|
||||
tdSql.execute("drop database if exists last_test_both_model;")
|
||||
|
||||
def run(self):
|
||||
self.none_model_test()
|
||||
|
||||
self.last_value_model_test()
|
||||
|
||||
self.last_row_model_test()
|
||||
|
||||
self.both_model_test()
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -250,7 +250,7 @@ class TDTestCase:
|
|||
"last_row(c1), last(c1)",
|
||||
"last_row(c1), c1,c3, ts"
|
||||
]
|
||||
has_last_row_scan_res = [0,0,1]
|
||||
has_last_row_scan_res = [1,1,1]
|
||||
sqls = self.format_sqls(sql_template, select_items)
|
||||
self.explain_and_check_res(sqls, has_last_row_scan_res)
|
||||
#res_expect = [None, None, [999, 999, 499, "2018-11-25 19:30:00.000"]]
|
||||
|
@ -387,7 +387,7 @@ class TDTestCase:
|
|||
tdSql.query('select last(c1) from meters partition by t1')
|
||||
print(str(tdSql.queryResult))
|
||||
tdSql.checkCols(1)
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkRows(5)
|
||||
p = subprocess.run(["taos", '-s', "alter table test.meters drop column c1; alter table test.meters add column c2 int"])
|
||||
p.check_returncode()
|
||||
tdSql.query_success_failed('select last(c1) from meters partition by t1', queryTimes=10, expectErrInfo="Invalid column name: c1")
|
||||
|
|
|
@ -1310,81 +1310,81 @@ class TDTestCase:
|
|||
ts = ts + 20
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_null_childtable group by tbname order by tbname;")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 1, 52);
|
||||
tdSql.checkData(0, 1, 52)
|
||||
|
||||
|
||||
#stables
|
||||
tdSql.query(f"insert into nested.stable_1 (ts,tbname,q_int) values(now,'stable_1_1',1) \
|
||||
nested.stable_1 (ts,tbname,q_bigint) values(now+1a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_smallint) values(now+2a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_tinyint) values(now+3a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_float) values(now+4a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_double) values(now+5a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_bool) values(now+6a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_binary) values(now+7a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_nchar) values(now+8a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_ts) values(now+9a,'stable_1_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_int) values(now,'stable_null_data_1',1) \
|
||||
nested.stable_null_data (ts,tbname,q_bigint) values(now+1a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_smallint) values(now+2a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_tinyint) values(now+3a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_float) values(now+4a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_double) values(now+5a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_bool) values(now+6a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_binary) values(now+7a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_nchar) values(now+8a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_ts) values(now+9a,'stable_null_data_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_int) values(now,'stable_null_childtable_1',1) \
|
||||
nested.stable_null_childtable (ts,tbname,q_bigint) values(now+1a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_smallint) values(now+2a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_tinyint) values(now+3a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_float) values(now+4a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_double) values(now+5a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_bool) values(now+6a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_binary) values(now+7a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_nchar) values(now+8a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_ts) values(now+9a,'stable_null_childtable_1',1);")
|
||||
tdSql.query(f"insert into nested.stable_1 (ts,tbname,q_int) values({ts},'stable_1_1',1) \
|
||||
nested.stable_1 (ts,tbname,q_bigint) values({ts}+1a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_smallint) values({ts}+2a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_tinyint) values({ts}+3a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_float) values({ts}+4a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_double) values({ts}+5a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_bool) values({ts}+6a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_binary) values({ts}+7a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_nchar) values({ts}+8a,'stable_1_1',1)\
|
||||
nested.stable_1 (ts,tbname,q_ts) values({ts}+9a,'stable_1_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_int) values({ts},'stable_null_data_1',1) \
|
||||
nested.stable_null_data (ts,tbname,q_bigint) values({ts}+1a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_smallint) values({ts}+2a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_tinyint) values({ts}+3a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_float) values({ts}+4a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_double) values({ts}+5a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_bool) values({ts}+6a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_binary) values({ts}+7a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_nchar) values({ts}+8a,'stable_null_data_1',1)\
|
||||
nested.stable_null_data (ts,tbname,q_ts) values({ts}+9a,'stable_null_data_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_int) values({ts},'stable_null_childtable_1',1) \
|
||||
nested.stable_null_childtable (ts,tbname,q_bigint) values({ts}+1a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_smallint) values({ts}+2a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_tinyint) values({ts}+3a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_float) values({ts}+4a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_double) values({ts}+5a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_bool) values({ts}+6a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_binary) values({ts}+7a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_nchar) values({ts}+8a,'stable_null_childtable_1',1)\
|
||||
nested.stable_null_childtable (ts,tbname,q_ts) values({ts}+9a,'stable_null_childtable_1',1);")
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_1 group by tbname order by tbname;")
|
||||
tdSql.checkRows(6)
|
||||
tdSql.checkData(0, 1, 162);
|
||||
tdSql.checkData(1, 1, 200);
|
||||
tdSql.checkData(0, 1, 162)
|
||||
tdSql.checkData(1, 1, 200)
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_null_data group by tbname order by tbname;")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 1, 62);
|
||||
tdSql.checkData(0, 1, 62)
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_null_childtable group by tbname order by tbname;")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 1, 62);
|
||||
tdSql.checkData(0, 1, 62)
|
||||
|
||||
#test special character
|
||||
|
||||
tdSql.query(f"insert into nested.stable_1 (ts,tbname,q_int) values(now+10a,'!@!@$$^$',1) \
|
||||
nested.stable_null_data (ts,tbname,q_int) values(now+10a,'%^$^&^&',1) \
|
||||
nested.stable_null_childtable (ts,tbname,q_int) values(now+10a,'$^%$%^&',1);")
|
||||
tdSql.query(f"insert into nested.stable_1 (ts,tbname,q_int) values({ts}+10a,'!@!@$$^$',1) \
|
||||
nested.stable_null_data (ts,tbname,q_int) values({ts}+10a,'%^$^&^&',1) \
|
||||
nested.stable_null_childtable (ts,tbname,q_int) values({ts}+10a,'$^%$%^&',1);")
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_1 group by tbname order by tbname;")
|
||||
tdSql.checkRows(7)
|
||||
tdSql.checkData(0, 1, 1);
|
||||
tdSql.checkData(1, 1, 162);
|
||||
tdSql.checkData(2, 1, 200);
|
||||
tdSql.checkData(0, 1, 1)
|
||||
tdSql.checkData(1, 1, 162)
|
||||
tdSql.checkData(2, 1, 200)
|
||||
tdSql.query(f"select count(*) from nested.stable_1 where tbname ='!@!@$$^$' ;")
|
||||
tdSql.checkData(0, 0, 1);
|
||||
tdSql.checkData(0, 0, 1)
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_null_data group by tbname order by tbname;")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 1, 1);
|
||||
tdSql.checkData(1, 1, 62);
|
||||
tdSql.checkData(0, 1, 1)
|
||||
tdSql.checkData(1, 1, 62)
|
||||
tdSql.query(f"select count(*) from nested.stable_null_data where tbname ='%^$^&^&' ;")
|
||||
tdSql.checkData(0, 0, 1);
|
||||
tdSql.checkData(0, 0, 1)
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_null_childtable group by tbname order by tbname;")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 1, 1);
|
||||
tdSql.checkData(1, 1, 62);
|
||||
tdSql.checkData(0, 1, 1)
|
||||
tdSql.checkData(1, 1, 62)
|
||||
tdSql.query(f"select count(*) from nested.stable_null_childtable where tbname ='$^%$%^&' ;")
|
||||
tdSql.checkData(0, 0, 1);
|
||||
tdSql.checkData(0, 0, 1)
|
||||
|
||||
#test csv
|
||||
sql1 = "select tbname,ts,q_int,q_binary from nested.stable_1 >>'%s/stable_1.csv';" %self.testcasePath
|
||||
|
@ -1404,31 +1404,31 @@ class TDTestCase:
|
|||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_1 group by tbname order by tbname;")
|
||||
tdSql.checkRows(7)
|
||||
tdSql.checkData(0, 1, 1);
|
||||
tdSql.checkData(1, 1, 162);
|
||||
tdSql.checkData(2, 1, 200);
|
||||
tdSql.checkData(0, 1, 1)
|
||||
tdSql.checkData(1, 1, 162)
|
||||
tdSql.checkData(2, 1, 200)
|
||||
tdSql.query(f"select count(*) from nested.stable_1 where tbname ='!@!@$$^$' ;")
|
||||
tdSql.checkData(0, 0, 1);
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.query(f"select count(q_bool) from nested.stable_1;")
|
||||
tdSql.checkData(0, 0, 0);
|
||||
tdSql.checkData(0, 0, 0)
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_null_data group by tbname order by tbname;")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 1, 1);
|
||||
tdSql.checkData(1, 1, 62);
|
||||
tdSql.checkData(0, 1, 1)
|
||||
tdSql.checkData(1, 1, 62)
|
||||
tdSql.query(f"select count(*) from nested.stable_null_data where tbname ='%^$^&^&' ;")
|
||||
tdSql.checkData(0, 0, 1);
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.query(f"select count(q_bool) from nested.stable_null_data;")
|
||||
tdSql.checkData(0, 0, 0);
|
||||
tdSql.checkData(0, 0, 0)
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_null_childtable group by tbname order by tbname;")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 1, 1);
|
||||
tdSql.checkData(1, 1, 62);
|
||||
tdSql.checkData(0, 1, 1)
|
||||
tdSql.checkData(1, 1, 62)
|
||||
tdSql.query(f"select count(*) from nested.stable_null_childtable where tbname ='$^%$%^&' ;")
|
||||
tdSql.checkData(0, 0, 1);
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.query(f"select count(q_bool) from nested.stable_null_childtable;")
|
||||
tdSql.checkData(0, 0, 0);
|
||||
tdSql.checkData(0, 0, 0)
|
||||
|
||||
|
||||
tdSql.query(f"delete from nested.stable_1;")
|
||||
|
@ -1440,37 +1440,46 @@ class TDTestCase:
|
|||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_1 group by tbname order by tbname;")
|
||||
tdSql.checkRows(7)
|
||||
tdSql.checkData(0, 1, 1);
|
||||
tdSql.checkData(1, 1, 162);
|
||||
tdSql.checkData(2, 1, 200);
|
||||
tdSql.checkData(0, 1, 1)
|
||||
tdSql.checkData(1, 1, 162)
|
||||
tdSql.checkData(2, 1, 200)
|
||||
tdSql.query(f"select count(*) from nested.stable_1 where tbname ='!@!@$$^$' ;")
|
||||
tdSql.checkData(0, 0, 1);
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.query(f"select count(q_bool) from nested.stable_1;")
|
||||
tdSql.checkData(0, 0, 0);
|
||||
tdSql.checkData(0, 0, 0)
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_null_data group by tbname order by tbname;")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 1, 1);
|
||||
tdSql.checkData(1, 1, 62);
|
||||
tdSql.checkData(0, 1, 1)
|
||||
tdSql.checkData(1, 1, 62)
|
||||
tdSql.query(f"select count(*) from nested.stable_null_data where tbname ='%^$^&^&' ;")
|
||||
tdSql.checkData(0, 0, 1);
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.query(f"select count(q_bool) from nested.stable_null_data;")
|
||||
tdSql.checkData(0, 0, 0);
|
||||
tdSql.checkData(0, 0, 0)
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_null_childtable group by tbname order by tbname;")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 1, 1);
|
||||
tdSql.checkData(1, 1, 62);
|
||||
tdSql.checkData(0, 1, 1)
|
||||
tdSql.checkData(1, 1, 62)
|
||||
tdSql.query(f"select count(*) from nested.stable_null_childtable where tbname ='$^%$%^&' ;")
|
||||
tdSql.checkData(0, 0, 1);
|
||||
tdSql.checkData(0, 0, 1)
|
||||
tdSql.query(f"select count(q_bool) from nested.stable_null_childtable;")
|
||||
tdSql.checkData(0, 0, 0);
|
||||
tdSql.checkData(0, 0, 0)
|
||||
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_1 where ts is not null group by tbname order by tbname;")
|
||||
tdSql.checkRows(7)
|
||||
tdSql.query(f"select tbname,count(*) from nested.stable_1 where ts is null group by tbname order by tbname;")
|
||||
tdSql.checkRows(7)
|
||||
tdSql.query(f"select tbname,last(*) from nested.stable_1 where ts is not null group by tbname order by tbname;")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query(f"select tbname,last(*) from nested.stable_1 where ts is null group by tbname order by tbname;")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
#test stable
|
||||
|
||||
tdSql.error(f"insert into nested.stable_1 (ts,tbname,q_int) values(now,'stable_1',1) \
|
||||
nested.stable_null_data (ts,tbname,q_int) values(now,'stable_null_data',1) \
|
||||
nested.stable_null_childtable (ts,tbname,q_int) values(now,'stable_null_childtable',1);")
|
||||
tdSql.error(f"insert into nested.stable_1 (ts,tbname,q_int) values({ts},'stable_1',1) \
|
||||
nested.stable_null_data (ts,tbname,q_int) values({ts},'stable_null_data',1) \
|
||||
nested.stable_null_childtable (ts,tbname,q_int) values({ts},'stable_null_childtable',1);")
|
||||
|
||||
|
||||
def stop(self):
|
||||
|
|
|
@ -276,6 +276,33 @@ class TDTestCase:
|
|||
sql2 = "select count(*) as a, count(c2) as b, max(c2) as c, min(c2) as d, sum(c2) as e from st;"
|
||||
self.queryResultSame(sql1, sql2)
|
||||
|
||||
def queryOrderByAgg(self):
|
||||
|
||||
tdSql.query("SELECT COUNT(*) FROM t1 order by COUNT(*)")
|
||||
|
||||
tdSql.query("SELECT COUNT(*) FROM t1 order by last(c2)")
|
||||
|
||||
tdSql.query("SELECT c1 FROM t1 order by last(ts)")
|
||||
|
||||
tdSql.query("SELECT ts FROM t1 order by last(ts)")
|
||||
|
||||
tdSql.query("SELECT last(ts), ts, c1 FROM t1 order by 2")
|
||||
|
||||
tdSql.query("SELECT ts, last(ts) FROM t1 order by last(ts)")
|
||||
|
||||
tdSql.query(f"SELECT * FROM t1 order by last(ts)")
|
||||
|
||||
tdSql.query(f"SELECT last(ts) as t2, ts FROM t1 order by 1")
|
||||
tdSql.checkRows(1)
|
||||
|
||||
tdSql.query(f"SELECT last(ts), ts FROM t1 order by last(ts)")
|
||||
tdSql.checkRows(1)
|
||||
|
||||
tdSql.error(f"SELECT first(ts), ts FROM t1 order by last(ts)")
|
||||
|
||||
tdSql.error(f"SELECT last(ts) as t2, ts FROM t1 order by last(t2)")
|
||||
|
||||
|
||||
# run
|
||||
def run(self):
|
||||
# prepare env
|
||||
|
@ -287,6 +314,9 @@ class TDTestCase:
|
|||
# advance
|
||||
self.queryAdvance()
|
||||
|
||||
# agg
|
||||
self.queryOrderByAgg()
|
||||
|
||||
|
||||
# stop
|
||||
def stop(self):
|
||||
|
|
|
@ -2,6 +2,7 @@ from util.log import *
|
|||
from util.sql import *
|
||||
from util.cases import *
|
||||
from util.dnodes import *
|
||||
from util.autogen import *
|
||||
|
||||
|
||||
INT_COL = "c1"
|
||||
|
@ -23,11 +24,11 @@ TS_TYPE_COL = [TS_COL]
|
|||
DBNAME = "db"
|
||||
|
||||
class TDTestCase:
|
||||
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
tdSql.init(conn.cursor())
|
||||
self.autoGen = AutoGen(True)
|
||||
|
||||
def __sum_condition(self):
|
||||
sum_condition = []
|
||||
|
@ -207,9 +208,55 @@ class TDTestCase:
|
|||
'''
|
||||
)
|
||||
|
||||
def testAllTypes(self):
|
||||
# create stable and insert
|
||||
tdLog.info("test all types")
|
||||
dbname = "sumdb"
|
||||
stbname = "stb"
|
||||
colnum = 16
|
||||
self.autoGen.set_batch_size(1000)
|
||||
self.autoGen.create_db(dbname)
|
||||
self.autoGen.create_stable(stbname, 16, colnum, 8, 16)
|
||||
self.autoGen.create_child(stbname, "d", 4)
|
||||
self.autoGen.insert_data(10000)
|
||||
|
||||
# check correct
|
||||
i = 0
|
||||
for c in self.autoGen.mcols:
|
||||
|
||||
if c in [0, 11, 12, 13]:
|
||||
i += 1
|
||||
continue
|
||||
|
||||
# query
|
||||
col = f"c{i}"
|
||||
sql = f"select count({col}), sum({col}), avg({col}), max({col}), min({col}), stddev({col}), leastsquares({col},1,9) from {dbname}.{stbname}"
|
||||
tdSql.query(sql)
|
||||
# sum
|
||||
tdSql.checkData(0, 0, 4*10000, True)
|
||||
# sum
|
||||
tdSql.checkData(0, 1, 4*10000, True)
|
||||
# avg
|
||||
tdSql.checkData(0, 2, 1, True)
|
||||
# max
|
||||
tdSql.checkData(0, 3, 1, True)
|
||||
# min
|
||||
tdSql.checkData(0, 4, 1, True)
|
||||
# stddev
|
||||
tdSql.checkData(0, 5, 0, True)
|
||||
|
||||
sql = f"select twa({col}) from {dbname}.d0"
|
||||
tdSql.query(sql)
|
||||
tdSql.checkData(0, 0, 1, True)
|
||||
|
||||
i += 1
|
||||
|
||||
|
||||
def run(self):
|
||||
tdSql.prepare()
|
||||
|
||||
self.testAllTypes()
|
||||
|
||||
tdLog.printNoPrefix("==========step1:create table")
|
||||
self.__create_tb()
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
from util.cases import *
|
||||
from util.sql import *
|
||||
|
||||
class TDTestCase:
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor(), True)
|
||||
|
||||
tdSql.execute("drop database if exists td_28068;")
|
||||
tdSql.execute("create database td_28068;")
|
||||
tdSql.execute("create database if not exists td_28068;")
|
||||
tdSql.execute("create stable td_28068.st (ts timestamp, test_case nchar(10), time_cost float, num float) tags (branch nchar(10), scenario nchar(10));")
|
||||
tdSql.execute("insert into td_28068.ct1 using td_28068.st (branch, scenario) tags ('3.0', 'scenario1') values (now(), 'query1', 1,2);")
|
||||
tdSql.execute("insert into td_28068.ct1 using td_28068.st (branch, scenario) tags ('3.0', 'scenario1') values (now(), 'query1', 2,3);")
|
||||
tdSql.execute("insert into td_28068.ct2 using td_28068.st (branch, scenario) tags ('3.0', 'scenario2') values (now(), 'query1', 10,1);")
|
||||
tdSql.execute("insert into td_28068.ct2 using td_28068.st (branch, scenario) tags ('3.0', 'scenario2') values (now(), 'query1', 11,5);")
|
||||
tdSql.execute("insert into td_28068.ct3 using td_28068.st (branch, scenario) tags ('3.1', 'scenario1') values (now(), 'query1', 20,4);")
|
||||
tdSql.execute("insert into td_28068.ct3 using td_28068.st (branch, scenario) tags ('3.1', 'scenario1') values (now(), 'query1', 30,1);")
|
||||
tdSql.execute("insert into td_28068.ct4 using td_28068.st (branch, scenario) tags ('3.1', 'scenario2') values (now(), 'query1', 8,8);")
|
||||
tdSql.execute("insert into td_28068.ct4 using td_28068.st (branch, scenario) tags ('3.1', 'scenario2') values (now(), 'query1', 9,10);")
|
||||
|
||||
def run(self):
|
||||
tdSql.error('select last(ts) as ts, last(branch) as branch, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch);')
|
||||
tdSql.error('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch), last(scenario); ')
|
||||
|
||||
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch); ')
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario, last(test_case) from td_28068.st group by branch, scenario order by last(branch), last(test_case);')
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by branch, scenario order by last(branch), last(scenario);')
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by branch, scenario order by branch1, scenario1;')
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by tbname; ')
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case from td_28068.st group by branch, scenario order by test_case;')
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query('select last(ts) as ts, last(branch) as branch1, last(scenario) as scenario1, last(test_case) as test_case1 from td_28068.st group by branch, scenario order by last(test_case);')
|
||||
tdSql.checkRows(4)
|
||||
|
||||
tdSql.query('select time_cost, num, time_cost + num as final_cost from td_28068.st partition by branch; ')
|
||||
tdSql.checkRows(8)
|
||||
|
||||
tdSql.query('select count(*) from td_28068.st partition by branch order by branch; ')
|
||||
tdSql.checkRows(2)
|
||||
|
||||
tdSql.query('select time_cost, num, time_cost + num as final_cost from td_28068.st order by time_cost;')
|
||||
tdSql.checkRows(8)
|
||||
|
||||
tdSql.query('select time_cost, num, time_cost + num as final_cost from td_28068.st order by final_cost;')
|
||||
tdSql.checkRows(8)
|
||||
|
||||
tdSql.execute("drop database if exists td_28068;")
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -0,0 +1,218 @@
|
|||
|
||||
import taos
|
||||
import sys
|
||||
import time
|
||||
import socket
|
||||
import os
|
||||
import threading
|
||||
import math
|
||||
|
||||
from util.log import *
|
||||
from util.sql import *
|
||||
from util.cases import *
|
||||
from util.dnodes import *
|
||||
from util.common import *
|
||||
from util.cluster import *
|
||||
sys.path.append("./7-tmq")
|
||||
from tmqCommon import *
|
||||
|
||||
from util.cluster import *
|
||||
sys.path.append("./6-cluster")
|
||||
from clusterCommonCreate import *
|
||||
from clusterCommonCheck import clusterComCheck
|
||||
|
||||
class TDTestCase:
|
||||
def __init__(self):
|
||||
self.vgroups = 1
|
||||
self.ctbNum = 10
|
||||
self.rowsPerTbl = 1000
|
||||
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
tdSql.init(conn.cursor(), True)
|
||||
|
||||
def getDataPath(self):
|
||||
selfPath = tdCom.getBuildPath()
|
||||
|
||||
return selfPath + '/../sim/dnode%d/data/vnode/vnode%d/wal/*';
|
||||
|
||||
def prepareTestEnv(self):
|
||||
tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ")
|
||||
paraDict = {'dbName': 'dbt',
|
||||
'dropFlag': 1,
|
||||
'event': '',
|
||||
'vgroups': 1,
|
||||
'stbName': 'stb',
|
||||
'colPrefix': 'c',
|
||||
'tagPrefix': 't',
|
||||
'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}],
|
||||
'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}],
|
||||
'ctbPrefix': 'ctb',
|
||||
'ctbStartIdx': 0,
|
||||
'ctbNum': 10,
|
||||
'rowsPerTbl': 1000,
|
||||
'batchNum': 10,
|
||||
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||
'pollDelay': 60,
|
||||
'showMsg': 1,
|
||||
'showRow': 1,
|
||||
'snapshot': 0}
|
||||
|
||||
paraDict['vgroups'] = self.vgroups
|
||||
paraDict['ctbNum'] = self.ctbNum
|
||||
paraDict['rowsPerTbl'] = self.rowsPerTbl
|
||||
|
||||
tdCom.drop_all_db()
|
||||
tmqCom.initConsumerTable()
|
||||
tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], wal_retention_period=36000,vgroups=paraDict["vgroups"],replica=self.replicaVar)
|
||||
tdLog.info("create stb")
|
||||
tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"])
|
||||
return
|
||||
|
||||
def restartAndRemoveWal(self, deleteWal):
|
||||
tdDnodes = cluster.dnodes
|
||||
tdSql.query("select * from information_schema.ins_vnodes")
|
||||
for result in tdSql.queryResult:
|
||||
if result[2] == 'dbt':
|
||||
tdLog.debug("dnode is %d"%(result[0]))
|
||||
dnodeId = result[0]
|
||||
vnodeId = result[1]
|
||||
|
||||
tdDnodes[dnodeId - 1].stoptaosd()
|
||||
time.sleep(1)
|
||||
dataPath = self.getDataPath()
|
||||
dataPath = dataPath%(dnodeId,vnodeId)
|
||||
tdLog.debug("dataPath:%s"%dataPath)
|
||||
if deleteWal:
|
||||
if os.system('rm -rf ' + dataPath) != 0:
|
||||
tdLog.exit("rm error")
|
||||
|
||||
tdDnodes[dnodeId - 1].starttaosd()
|
||||
time.sleep(1)
|
||||
break
|
||||
tdLog.debug("restart dnode ok")
|
||||
|
||||
def splitVgroups(self):
|
||||
tdSql.query("select * from information_schema.ins_vnodes")
|
||||
vnodeId = 0
|
||||
for result in tdSql.queryResult:
|
||||
if result[2] == 'dbt':
|
||||
vnodeId = result[1]
|
||||
tdLog.debug("vnode is %d"%(vnodeId))
|
||||
break
|
||||
splitSql = "split vgroup %d" %(vnodeId)
|
||||
tdLog.debug("splitSql:%s"%(splitSql))
|
||||
tdSql.query(splitSql)
|
||||
tdLog.debug("splitSql ok")
|
||||
|
||||
def tmqCase1(self, deleteWal=False):
|
||||
tdLog.printNoPrefix("======== test case 1: ")
|
||||
paraDict = {'dbName': 'dbt',
|
||||
'dropFlag': 1,
|
||||
'event': '',
|
||||
'vgroups': 1,
|
||||
'stbName': 'stb',
|
||||
'colPrefix': 'c',
|
||||
'tagPrefix': 't',
|
||||
'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}],
|
||||
'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}],
|
||||
'ctbPrefix': 'ctb1',
|
||||
'ctbStartIdx': 0,
|
||||
'ctbNum': 10,
|
||||
'rowsPerTbl': 1000,
|
||||
'batchNum': 10,
|
||||
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||
'pollDelay': 120,
|
||||
'showMsg': 1,
|
||||
'showRow': 1,
|
||||
'snapshot': 0}
|
||||
|
||||
paraDict['vgroups'] = self.vgroups
|
||||
paraDict['ctbNum'] = self.ctbNum
|
||||
paraDict['rowsPerTbl'] = self.rowsPerTbl
|
||||
|
||||
topicNameList = ['topic1']
|
||||
# expectRowsList = []
|
||||
tmqCom.initConsumerTable()
|
||||
|
||||
tdLog.info("create topics from stb ")
|
||||
queryString = "stable %s.%s"%(paraDict['dbName'], paraDict['stbName'])
|
||||
# sqlString = "create topic %s as stable %s" %(topicNameList[0], paraDict['stbName'])
|
||||
sqlString = "create topic %s as %s" %(topicNameList[0], queryString)
|
||||
tdLog.info("create topic sql: %s"%sqlString)
|
||||
tdSql.execute(sqlString)
|
||||
# tdSql.query(queryString)
|
||||
# expectRowsList.append(tdSql.getRows())
|
||||
|
||||
# init consume info, and start tmq_sim, then check consume result
|
||||
tdLog.info("insert consume info to consume processor")
|
||||
consumerId = 0
|
||||
expectrowcnt = paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 2
|
||||
topicList = topicNameList[0]
|
||||
ifcheckdata = 1
|
||||
ifManualCommit = 1
|
||||
keyList = 'group.id:cgrp1, enable.auto.commit:true, auto.commit.interval.ms:200, auto.offset.reset:earliest'
|
||||
tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit)
|
||||
|
||||
tdLog.info("start consume processor")
|
||||
tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot'])
|
||||
tdLog.info("wait the consume result")
|
||||
|
||||
tdLog.info("create ctb1")
|
||||
tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'],
|
||||
ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx'])
|
||||
|
||||
tdLog.info("create ctb2")
|
||||
paraDict2 = paraDict.copy()
|
||||
paraDict2['ctbPrefix'] = "ctb2"
|
||||
tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict2['ctbPrefix'],
|
||||
ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx'])
|
||||
|
||||
tdLog.info("insert ctb1 data")
|
||||
pInsertThread = tmqCom.asyncInsertDataByInterlace(paraDict)
|
||||
|
||||
tmqCom.getStartConsumeNotifyFromTmqsim()
|
||||
tmqCom.getStartCommitNotifyFromTmqsim()
|
||||
|
||||
#restart dnode & remove wal
|
||||
self.restartAndRemoveWal(deleteWal)
|
||||
|
||||
# split vgroup
|
||||
self.splitVgroups()
|
||||
|
||||
|
||||
tdLog.info("insert ctb2 data")
|
||||
pInsertThread1 = tmqCom.asyncInsertDataByInterlace(paraDict2)
|
||||
pInsertThread.join()
|
||||
pInsertThread1.join()
|
||||
|
||||
expectRows = 1
|
||||
resultList = tmqCom.selectConsumeResult(expectRows)
|
||||
|
||||
if expectrowcnt / 2 > resultList[0]:
|
||||
tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectrowcnt / 2, resultList[0]))
|
||||
tdLog.exit("%d tmq consume rows error!"%consumerId)
|
||||
|
||||
# tmqCom.checkFileContent(consumerId, queryString)
|
||||
|
||||
time.sleep(2)
|
||||
for i in range(len(topicNameList)):
|
||||
tdSql.query("drop topic %s"%topicNameList[i])
|
||||
|
||||
if deleteWal == True:
|
||||
clusterComCheck.check_vgroups_status(vgroup_numbers=2,db_replica=self.replicaVar,db_name="dbt",count_number=240)
|
||||
tdLog.printNoPrefix("======== test case 1 end ...... ")
|
||||
|
||||
def run(self):
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(False)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
event = threading.Event()
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -0,0 +1,222 @@
|
|||
|
||||
import taos
|
||||
import sys
|
||||
import time
|
||||
import socket
|
||||
import os
|
||||
import threading
|
||||
import math
|
||||
|
||||
from util.log import *
|
||||
from util.sql import *
|
||||
from util.cases import *
|
||||
from util.dnodes import *
|
||||
from util.common import *
|
||||
from util.cluster import *
|
||||
sys.path.append("./7-tmq")
|
||||
from tmqCommon import *
|
||||
|
||||
from util.cluster import *
|
||||
sys.path.append("./6-cluster")
|
||||
from clusterCommonCreate import *
|
||||
from clusterCommonCheck import clusterComCheck
|
||||
|
||||
|
||||
|
||||
class TDTestCase:
|
||||
def __init__(self):
|
||||
self.vgroups = 1
|
||||
self.ctbNum = 10
|
||||
self.rowsPerTbl = 1000
|
||||
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
tdSql.init(conn.cursor(), True)
|
||||
|
||||
def getDataPath(self):
|
||||
selfPath = tdCom.getBuildPath()
|
||||
|
||||
return selfPath + '/../sim/dnode%d/data/vnode/vnode%d/wal/*';
|
||||
|
||||
def prepareTestEnv(self):
|
||||
tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ")
|
||||
paraDict = {'dbName': 'dbt',
|
||||
'dropFlag': 1,
|
||||
'event': '',
|
||||
'vgroups': 1,
|
||||
'stbName': 'stb',
|
||||
'colPrefix': 'c',
|
||||
'tagPrefix': 't',
|
||||
'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}],
|
||||
'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}],
|
||||
'ctbPrefix': 'ctb',
|
||||
'ctbStartIdx': 0,
|
||||
'ctbNum': 10,
|
||||
'rowsPerTbl': 1000,
|
||||
'batchNum': 10,
|
||||
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||
'pollDelay': 60,
|
||||
'showMsg': 1,
|
||||
'showRow': 1,
|
||||
'snapshot': 0}
|
||||
|
||||
paraDict['vgroups'] = self.vgroups
|
||||
paraDict['ctbNum'] = self.ctbNum
|
||||
paraDict['rowsPerTbl'] = self.rowsPerTbl
|
||||
|
||||
tdCom.drop_all_db()
|
||||
tmqCom.initConsumerTable()
|
||||
tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], wal_retention_period=36000,vgroups=paraDict["vgroups"],replica=self.replicaVar)
|
||||
tdLog.info("create stb")
|
||||
tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"])
|
||||
return
|
||||
|
||||
def restartAndRemoveWal(self, deleteWal):
|
||||
tdDnodes = cluster.dnodes
|
||||
tdSql.query("select * from information_schema.ins_vnodes")
|
||||
for result in tdSql.queryResult:
|
||||
if result[2] == 'dbt':
|
||||
tdLog.debug("dnode is %d"%(result[0]))
|
||||
dnodeId = result[0]
|
||||
vnodeId = result[1]
|
||||
|
||||
tdDnodes[dnodeId - 1].stoptaosd()
|
||||
time.sleep(1)
|
||||
dataPath = self.getDataPath()
|
||||
dataPath = dataPath%(dnodeId,vnodeId)
|
||||
tdLog.debug("dataPath:%s"%dataPath)
|
||||
if deleteWal:
|
||||
if os.system('rm -rf ' + dataPath) != 0:
|
||||
tdLog.exit("rm error")
|
||||
|
||||
tdDnodes[dnodeId - 1].starttaosd()
|
||||
time.sleep(1)
|
||||
break
|
||||
tdLog.debug("restart dnode ok")
|
||||
|
||||
def splitVgroups(self):
|
||||
tdSql.query("select * from information_schema.ins_vnodes")
|
||||
vnodeId = 0
|
||||
for result in tdSql.queryResult:
|
||||
if result[2] == 'dbt':
|
||||
vnodeId = result[1]
|
||||
tdLog.debug("vnode is %d"%(vnodeId))
|
||||
break
|
||||
splitSql = "split vgroup %d" %(vnodeId)
|
||||
tdLog.debug("splitSql:%s"%(splitSql))
|
||||
tdSql.query(splitSql)
|
||||
tdLog.debug("splitSql ok")
|
||||
|
||||
def tmqCase1(self, deleteWal=False):
|
||||
tdLog.printNoPrefix("======== test case 1: ")
|
||||
paraDict = {'dbName': 'dbt',
|
||||
'dropFlag': 1,
|
||||
'event': '',
|
||||
'vgroups': 1,
|
||||
'stbName': 'stb',
|
||||
'colPrefix': 'c',
|
||||
'tagPrefix': 't',
|
||||
'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}],
|
||||
'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}],
|
||||
'ctbPrefix': 'ctb1',
|
||||
'ctbStartIdx': 0,
|
||||
'ctbNum': 10,
|
||||
'rowsPerTbl': 1000,
|
||||
'batchNum': 10,
|
||||
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||
'pollDelay': 180,
|
||||
'showMsg': 1,
|
||||
'showRow': 1,
|
||||
'snapshot': 0}
|
||||
|
||||
paraDict['vgroups'] = self.vgroups
|
||||
paraDict['ctbNum'] = self.ctbNum
|
||||
paraDict['rowsPerTbl'] = self.rowsPerTbl
|
||||
|
||||
topicNameList = ['topic1']
|
||||
# expectRowsList = []
|
||||
tmqCom.initConsumerTable()
|
||||
|
||||
tdLog.info("create topics from stb with filter")
|
||||
queryString = "select * from %s.%s"%(paraDict['dbName'], paraDict['stbName'])
|
||||
# sqlString = "create topic %s as stable %s" %(topicNameList[0], paraDict['stbName'])
|
||||
sqlString = "create topic %s as %s" %(topicNameList[0], queryString)
|
||||
tdLog.info("create topic sql: %s"%sqlString)
|
||||
tdSql.execute(sqlString)
|
||||
# tdSql.query(queryString)
|
||||
# expectRowsList.append(tdSql.getRows())
|
||||
|
||||
# init consume info, and start tmq_sim, then check consume result
|
||||
tdLog.info("insert consume info to consume processor")
|
||||
consumerId = 0
|
||||
expectrowcnt = paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 2
|
||||
topicList = topicNameList[0]
|
||||
ifcheckdata = 1
|
||||
ifManualCommit = 1
|
||||
keyList = 'group.id:cgrp1, enable.auto.commit:true, auto.commit.interval.ms:200, auto.offset.reset:earliest'
|
||||
tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit)
|
||||
|
||||
tdLog.info("start consume processor")
|
||||
tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot'])
|
||||
tdLog.info("wait the consume result")
|
||||
|
||||
tdLog.info("create ctb1")
|
||||
tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'],
|
||||
ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx'])
|
||||
|
||||
tdLog.info("create ctb2")
|
||||
paraDict2 = paraDict.copy()
|
||||
paraDict2['ctbPrefix'] = "ctb2"
|
||||
tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict2['ctbPrefix'],
|
||||
ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx'])
|
||||
|
||||
tdLog.info("insert ctb1 data")
|
||||
pInsertThread = tmqCom.asyncInsertDataByInterlace(paraDict)
|
||||
|
||||
tmqCom.getStartConsumeNotifyFromTmqsim()
|
||||
tmqCom.getStartCommitNotifyFromTmqsim()
|
||||
|
||||
#restart dnode & remove wal
|
||||
self.restartAndRemoveWal(deleteWal)
|
||||
|
||||
# split vgroup
|
||||
self.splitVgroups()
|
||||
|
||||
|
||||
tdLog.info("insert ctb2 data")
|
||||
pInsertThread1 = tmqCom.asyncInsertDataByInterlace(paraDict2)
|
||||
pInsertThread.join()
|
||||
pInsertThread1.join()
|
||||
|
||||
expectRows = 1
|
||||
|
||||
|
||||
resultList = tmqCom.selectConsumeResult(expectRows)
|
||||
|
||||
if expectrowcnt / 2 > resultList[0]:
|
||||
tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectrowcnt / 2, resultList[0]))
|
||||
tdLog.exit("%d tmq consume rows error!"%consumerId)
|
||||
|
||||
# tmqCom.checkFileContent(consumerId, queryString)
|
||||
|
||||
time.sleep(2)
|
||||
for i in range(len(topicNameList)):
|
||||
tdSql.query("drop topic %s"%topicNameList[i])
|
||||
|
||||
if deleteWal == True:
|
||||
clusterComCheck.check_vgroups_status(vgroup_numbers=2,db_replica=self.replicaVar,db_name="dbt",count_number=240)
|
||||
tdLog.printNoPrefix("======== test case 1 end ...... ")
|
||||
|
||||
def run(self):
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(False)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
event = threading.Event()
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -190,6 +190,8 @@ class TDTestCase:
|
|||
pInsertThread1.join()
|
||||
|
||||
expectRows = 1
|
||||
|
||||
|
||||
resultList = tmqCom.selectConsumeResult(expectRows)
|
||||
|
||||
if expectrowcnt / 2 > resultList[0]:
|
||||
|
@ -209,8 +211,6 @@ class TDTestCase:
|
|||
def run(self):
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(True)
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(False)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
|
|
@ -207,8 +207,6 @@ class TDTestCase:
|
|||
def run(self):
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(True)
|
||||
self.prepareTestEnv()
|
||||
self.tmqCase1(False)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
|
|
@ -106,14 +106,18 @@ class TDTestCase:
|
|||
ptn_counter = 0
|
||||
for c1_value in tdSql.queryResult:
|
||||
if partition == "c1":
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{abs(c1_value[1])}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{abs(c1_value[1])}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition is None:
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}no_partition{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}no_partition{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "abs(c1)":
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
ptn_counter += 1
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True)
|
||||
|
||||
|
@ -121,14 +125,18 @@ class TDTestCase:
|
|||
ptn_counter = 0
|
||||
for c1_value in tdSql.queryResult:
|
||||
if partition == "c1":
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{abs(c1_value[1])}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{abs(c1_value[1])}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition is None:
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}no_partition{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}no_partition{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "abs(c1)":
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{self.tb_name}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{self.tb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
ptn_counter += 1
|
||||
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True)
|
||||
|
@ -208,8 +216,8 @@ class TDTestCase:
|
|||
self.at_once_interval(interval=random.randint(10, 15), partition=None, delete=True)
|
||||
self.at_once_interval(interval=random.randint(10, 15), partition=self.tdCom.stream_case_when_tbname, case_when=f'case when {self.tdCom.stream_case_when_tbname} = tbname then {self.tdCom.partition_tbname_alias} else tbname end')
|
||||
self.at_once_interval(interval=random.randint(10, 15), partition="tbname", fill_history_value=1, fill_value="NULL")
|
||||
# for fill_value in ["NULL", "PREV", "NEXT", "LINEAR", "VALUE,1,2,3,4,5,6,7,8,9,10,11,1,2,3,4,5,6,7,8,9,10,11"]:
|
||||
for fill_value in ["PREV", "NEXT", "LINEAR", "VALUE,1,2,3,4,5,6,7,8,9,10,11,1,2,3,4,5,6,7,8,9,10,11"]:
|
||||
for fill_value in ["NULL", "PREV", "NEXT", "LINEAR", "VALUE,1,2,3,4,5,6,7,8,9,10,11,1,2,3,4,5,6,7,8,9,10,11"]:
|
||||
# for fill_value in ["PREV", "NEXT", "LINEAR", "VALUE,1,2,3,4,5,6,7,8,9,10,11,1,2,3,4,5,6,7,8,9,10,11"]:
|
||||
self.at_once_interval(interval=random.randint(10, 15), partition="tbname", fill_value=fill_value)
|
||||
self.at_once_interval(interval=random.randint(10, 15), partition="tbname", fill_value=fill_value, delete=True)
|
||||
|
||||
|
|
|
@ -153,12 +153,15 @@ class TDTestCase:
|
|||
ptn_counter = 0
|
||||
for c1_value in tdSql.queryResult:
|
||||
if partition == "c1":
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{abs(c1_value[1])}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{abs(c1_value[1])}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "abs(c1)":
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
ptn_counter += 1
|
||||
else:
|
||||
tdSql.query(f'select cast(cast(cast({c1_value[1]} as int unsigned) as bigint) as varchar(100))')
|
||||
|
@ -166,7 +169,8 @@ class TDTestCase:
|
|||
if subtable == "constant":
|
||||
return
|
||||
else:
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{subtable_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{subtable_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True)
|
||||
|
||||
def run(self):
|
||||
|
|
|
@ -59,10 +59,14 @@ class TDTestCase:
|
|||
ctb_subtable_value = f'concat(concat("{self.ctb_name}_{self.tdCom.subtable_prefix}", cast(cast({partition_elm_alias} as bigint) as varchar(20))), "{self.tdCom.subtable_suffix}")' if self.tdCom.subtable else None
|
||||
tb_subtable_value = f'concat(concat("{self.tb_name}_{self.tdCom.subtable_prefix}", cast(cast({partition_elm_alias} as bigint) as varchar(20))), "{self.tdCom.subtable_suffix}")' if self.tdCom.subtable else None
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
# create stb/ctb/tb stream
|
||||
self.tdCom.create_stream(stream_name=f'{self.ctb_name}{self.tdCom.stream_suffix}', des_table=self.ctb_stream_des_table, source_sql=f'select _wstart AS wstart, _wend AS wend, {self.tdCom.stb_source_select_str} from {self.ctb_name} partition by {partition} {partition_elm_alias} session(ts, {self.tdCom.dataDict["session"]}s)', trigger_mode="at_once", ignore_expired=ignore_expired, ignore_update=ignore_update, subtable_value=ctb_subtable_value, fill_history_value=fill_history_value)
|
||||
self.tdCom.create_stream(stream_name=f'{self.tb_name}{self.tdCom.stream_suffix}', des_table=self.tb_stream_des_table, source_sql=f'select _wstart AS wstart, _wend AS wend, {self.tdCom.tb_source_select_str} from {self.tb_name} partition by {partition} {partition_elm_alias} session(ts, {self.tdCom.dataDict["session"]}s)', trigger_mode="at_once", ignore_expired=ignore_expired, ignore_update=ignore_update, subtable_value=tb_subtable_value, fill_history_value=fill_history_value)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
for i in range(self.tdCom.range_count):
|
||||
ctb_name = self.tdCom.get_long_name()
|
||||
self.tdCom.screate_ctable(stbname=self.stb_name, ctbname=ctb_name)
|
||||
|
@ -167,35 +171,43 @@ class TDTestCase:
|
|||
for c1_value in tdSql.queryResult:
|
||||
if c1_value[1] is not None:
|
||||
if partition == "c1":
|
||||
tdSql.query(f'select count(*) from `{self.ctb_name}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.ctb_name}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "abs(c1)":
|
||||
if subtable:
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{self.ctb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.ctb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
else:
|
||||
tdSql.query(f'select count(*) from `{self.ctb_name}_{self.tdCom.subtable_prefix}{partition_elm_alias}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.ctb_name}_{self.tdCom.subtable_prefix}{partition_elm_alias}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{self.ctb_name}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.ctb_name}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
ptn_counter += 1
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True)
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True) if subtable is not None else tdSql.checkEqual(tdSql.queryResult[0][0] >= 0, True)
|
||||
|
||||
tdSql.query(f'select * from {self.tb_name}')
|
||||
ptn_counter = 0
|
||||
for c1_value in tdSql.queryResult:
|
||||
if c1_value[1] is not None:
|
||||
if partition == "c1":
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "abs(c1)":
|
||||
if subtable:
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
else:
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{partition_elm_alias}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{partition_elm_alias}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{self.tb_name}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{self.tb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
ptn_counter += 1
|
||||
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True)
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True) if subtable is not None else tdSql.checkEqual(tdSql.queryResult[0][0] >= 0, True)
|
||||
|
||||
|
||||
|
||||
|
@ -220,4 +232,4 @@ class TDTestCase:
|
|||
event = threading.Event()
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
|
|
|
@ -94,15 +94,19 @@ class TDTestCase:
|
|||
for c1_value in tdSql.queryResult:
|
||||
if partition == "c1":
|
||||
if subtable:
|
||||
tdSql.query(f'select count(*) from `{self.ctb_name}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.ctb_name}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
else:
|
||||
tdSql.query(f'select count(*) from `{self.ctb_name}_{self.tdCom.subtable_prefix}{partition_elm_alias}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.ctb_name}_{self.tdCom.subtable_prefix}{partition_elm_alias}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
return
|
||||
elif partition == "abs(c1)":
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{self.ctb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.ctb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{self.ctb_name}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.ctb_name}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
ptn_counter += 1
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True)
|
||||
|
||||
|
@ -111,17 +115,20 @@ class TDTestCase:
|
|||
for c1_value in tdSql.queryResult:
|
||||
if partition == "c1":
|
||||
if subtable:
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
else:
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{partition_elm_alias}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{partition_elm_alias}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
return
|
||||
elif partition == "abs(c1)":
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{self.tb_name}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{self.tb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
ptn_counter += 1
|
||||
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True)
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ class TDTestCase:
|
|||
# create stb/ctb/tb stream
|
||||
self.tdCom.create_stream(stream_name=f'{self.stb_name}{self.tdCom.stream_suffix}', des_table=self.tdCom.ext_stb_stream_des_table, subtable_value=stb_subtable_value, source_sql=f'select _wstart AS wstart, {partitial_tb_source_str} from {self.stb_name} interval({self.tdCom.dataDict["interval"]}s)', trigger_mode="max_delay", watermark=watermark_value, max_delay=max_delay_value, fill_value=fill_value, fill_history_value=fill_history_value, stb_field_name_value=stb_field_name_value, tag_value=tag_value, use_exist_stb=use_exist_stb)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
init_num = 0
|
||||
for i in range(self.tdCom.range_count):
|
||||
if i == 0:
|
||||
|
|
|
@ -117,14 +117,18 @@ class TDTestCase:
|
|||
ptn_counter = 0
|
||||
for c1_value in tdSql.queryResult:
|
||||
if partition == "c1":
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{abs(c1_value[1])}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{abs(c1_value[1])}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition is None:
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}no_partition{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}no_partition{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "abs(c1)":
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
ptn_counter += 1
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True)
|
||||
|
||||
|
@ -132,14 +136,18 @@ class TDTestCase:
|
|||
ptn_counter = 0
|
||||
for c1_value in tdSql.queryResult:
|
||||
if partition == "c1":
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{abs(c1_value[1])}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{abs(c1_value[1])}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition is None:
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}no_partition{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}no_partition{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "abs(c1)":
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{self.tb_name}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{self.tb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
ptn_counter += 1
|
||||
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True)
|
||||
|
|
|
@ -146,12 +146,15 @@ class TDTestCase:
|
|||
ptn_counter = 0
|
||||
for c1_value in tdSql.queryResult:
|
||||
if partition == "c1":
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}`;', count_expected_res=self.tdCom.range_count)
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`', count_expected_res=self.tdCom.range_count)
|
||||
elif partition == "abs(c1)":
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;', count_expected_res=self.tdCom.range_count)
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`', count_expected_res=self.tdCom.range_count)
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{tname}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}`;', count_expected_res=self.tdCom.range_count)
|
||||
tbname = self.tdCom.get_subtable_wait(f'{tname}_{self.tdCom.subtable_prefix}{self.ctb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`', count_expected_res=self.tdCom.range_count)
|
||||
ptn_counter += 1
|
||||
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] , self.tdCom.range_count)
|
||||
|
@ -161,12 +164,15 @@ class TDTestCase:
|
|||
ptn_counter = 0
|
||||
for c1_value in tdSql.queryResult:
|
||||
if partition == "c1":
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{c1_value[1]}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "abs(c1)":
|
||||
abs_c1_value = abs(c1_value[1])
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{abs_c1_value}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
elif partition == "tbname" and ptn_counter == 0:
|
||||
tdSql.query(f'select count(*) from `{self.tb_name}_{self.tdCom.subtable_prefix}{self.tb_name}{self.tdCom.subtable_suffix}`;')
|
||||
tbname = self.tdCom.get_subtable_wait(f'{self.tb_name}_{self.tdCom.subtable_prefix}{self.tb_name}{self.tdCom.subtable_suffix}')
|
||||
tdSql.query(f'select count(*) from `{tbname}`')
|
||||
ptn_counter += 1
|
||||
|
||||
tdSql.checkEqual(tdSql.queryResult[0][0] > 0, True)
|
||||
|
|
Loading…
Reference in New Issue