Merge branch '3.0' of https://github.com/taosdata/TDengine into feature/3.0_mhli
This commit is contained in:
commit
d364bde932
|
@ -88,9 +88,9 @@ int32_t create_stream() {
|
|||
/*const char* sql = "select min(k), max(k), sum(k) as sum_of_k from st1";*/
|
||||
/*const char* sql = "select sum(k) from tu1 interval(10m)";*/
|
||||
/*pRes = tmq_create_stream(pConn, "stream1", "out1", sql);*/
|
||||
pRes = taos_query(pConn,
|
||||
"create stream stream1 trigger at_once into abc2.outstb as select _wstartts, sum(k) from st1 "
|
||||
"partition by tbname interval(10m) ");
|
||||
pRes = taos_query(
|
||||
pConn,
|
||||
"create stream stream1 trigger at_once into abc1.outstb as select _wstartts, sum(k) from st1 interval(10m) ");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create stream stream1, reason:%s\n", taos_errstr(pRes));
|
||||
return -1;
|
||||
|
@ -107,11 +107,4 @@ int main(int argc, char* argv[]) {
|
|||
code = init_env();
|
||||
}
|
||||
create_stream();
|
||||
#if 0
|
||||
tmq_t* tmq = build_consumer();
|
||||
tmq_list_t* topic_list = build_topic_list();
|
||||
/*perf_loop(tmq, topic_list);*/
|
||||
/*basic_consume_loop(tmq, topic_list);*/
|
||||
sync_consume_loop(tmq, topic_list);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1776,12 +1776,10 @@ typedef struct {
|
|||
} SDDropTopicReq;
|
||||
|
||||
typedef struct {
|
||||
float xFilesFactor;
|
||||
int32_t delay;
|
||||
int32_t qmsg1Len;
|
||||
int32_t qmsg2Len;
|
||||
char* qmsg1; // pAst1:qmsg1:SRetention1 => trigger aggr task1
|
||||
char* qmsg2; // pAst2:qmsg2:SRetention2 => trigger aggr task2
|
||||
int64_t maxdelay[2];
|
||||
int64_t watermark[2];
|
||||
int32_t qmsgLen[2];
|
||||
char* qmsg[2]; // pAst:qmsg:SRetention => trigger aggr task1/2
|
||||
} SRSmaParam;
|
||||
|
||||
int32_t tEncodeSRSmaParam(SEncoder* pCoder, const SRSmaParam* pRSmaParam);
|
||||
|
|
|
@ -34,7 +34,6 @@ typedef enum {
|
|||
WRITE_QUEUE,
|
||||
APPLY_QUEUE,
|
||||
SYNC_QUEUE,
|
||||
MERGE_QUEUE,
|
||||
QUEUE_MAX,
|
||||
} EQueueType;
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ int32_t mndGetLoad(SMnode *pMnode, SMnodeLoad *pLoad);
|
|||
int32_t mndProcessRpcMsg(SRpcMsg *pMsg);
|
||||
int32_t mndProcessSyncMsg(SRpcMsg *pMsg);
|
||||
int32_t mndPreProcessMsg(SRpcMsg *pMsg);
|
||||
void mndAbortPreprocessMsg(SRpcMsg *pMsg);
|
||||
|
||||
/**
|
||||
* @brief Generate machine code
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#ifndef _TD_SNODE_H_
|
||||
#define _TD_SNODE_H_
|
||||
|
||||
#include "tmsgcb.h"
|
||||
#include "tmsg.h"
|
||||
#include "tmsgcb.h"
|
||||
#include "trpc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -68,8 +68,8 @@ int32_t sndGetLoad(SSnode *pSnode, SSnodeLoad *pLoad);
|
|||
* @param pMsg The request message
|
||||
* @param pRsp The response message
|
||||
*/
|
||||
void sndProcessUMsg(SSnode *pSnode, SRpcMsg *pMsg);
|
||||
void sndProcessSMsg(SSnode *pSnode, SRpcMsg *pMsg);
|
||||
int32_t sndProcessUMsg(SSnode *pSnode, SRpcMsg *pMsg);
|
||||
int32_t sndProcessSMsg(SSnode *pSnode, SRpcMsg *pMsg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -106,6 +106,9 @@ typedef struct SInterpFuncLogicNode {
|
|||
SNodeList* pFuncs;
|
||||
STimeWindow timeRange;
|
||||
int64_t interval;
|
||||
EFillMode fillMode;
|
||||
SNode* pFillValues; // SNodeListNode
|
||||
SNode* pTimeSeries; // SColumnNode
|
||||
} SInterpFuncLogicNode;
|
||||
|
||||
typedef enum EModifyTableType { MODIFY_TABLE_TYPE_INSERT = 1, MODIFY_TABLE_TYPE_DELETE } EModifyTableType;
|
||||
|
@ -309,6 +312,9 @@ typedef struct SInterpFuncPhysiNode {
|
|||
SNodeList* pFuncs;
|
||||
STimeWindow timeRange;
|
||||
int64_t interval;
|
||||
EFillMode fillMode;
|
||||
SNode* pFillValues; // SNodeListNode
|
||||
SNode* pTimeSeries; // SColumnNode
|
||||
} SInterpFuncPhysiNode;
|
||||
|
||||
typedef struct SJoinPhysiNode {
|
||||
|
|
|
@ -36,7 +36,6 @@ typedef struct SPlanContext {
|
|||
int64_t watermark;
|
||||
char* pMsg;
|
||||
int32_t msgLen;
|
||||
// double filesFactor;
|
||||
} SPlanContext;
|
||||
|
||||
// Create the physical plan for the query, according to the AST.
|
||||
|
|
|
@ -64,6 +64,8 @@ typedef struct {
|
|||
|
||||
int32_t qWorkerInit(int8_t nodeType, int32_t nodeId, SQWorkerCfg *cfg, void **qWorkerMgmt, const SMsgCb *pMsgCb);
|
||||
|
||||
int32_t qWorkerAbortPreprocessQueryMsg(void *qWorkerMgmt, SRpcMsg *pMsg);
|
||||
|
||||
int32_t qWorkerPreprocessQueryMsg(void *qWorkerMgmt, SRpcMsg *pMsg);
|
||||
|
||||
int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, int64_t ts);
|
||||
|
|
|
@ -152,7 +152,7 @@ void* streamDataBlockDecode(const void* buf, SStreamDataBlock* pInput);
|
|||
typedef struct {
|
||||
char* qmsg;
|
||||
// followings are not applicable to encoder and decoder
|
||||
void* inputHandle;
|
||||
// void* inputHandle;
|
||||
void* executor;
|
||||
} STaskExec;
|
||||
|
||||
|
@ -240,12 +240,13 @@ struct SStreamTask {
|
|||
int8_t inputType;
|
||||
int8_t status;
|
||||
|
||||
int8_t sourceType;
|
||||
int8_t execType;
|
||||
int8_t sinkType;
|
||||
int8_t dispatchType;
|
||||
int16_t dispatchMsgType;
|
||||
|
||||
int8_t dataScan;
|
||||
|
||||
// node info
|
||||
int32_t childId;
|
||||
int32_t nodeId;
|
||||
|
|
|
@ -567,6 +567,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_PAR_STREAM_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x265A)
|
||||
#define TSDB_CODE_PAR_GROUP_BY_NOT_ALLOWED_FUNC TAOS_DEF_ERROR_CODE(0, 0x265B)
|
||||
#define TSDB_CODE_PAR_INVALID_TABLE_OPTION TAOS_DEF_ERROR_CODE(0, 0x265C)
|
||||
#define TSDB_CODE_PAR_INVALID_INTERP_CLAUSE TAOS_DEF_ERROR_CODE(0, 0x265D)
|
||||
|
||||
//planner
|
||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||
|
|
|
@ -185,7 +185,7 @@ char tsCompressor[32] = "ZSTD_COMPRESSOR"; // ZSTD_COMPRESSOR or GZIP_COMPR
|
|||
bool tsStartUdfd = true;
|
||||
|
||||
// internal
|
||||
int32_t tsTransPullupInterval = 6;
|
||||
int32_t tsTransPullupInterval = 2;
|
||||
int32_t tsMqRebalanceInterval = 2;
|
||||
|
||||
void taosAddDataDir(int32_t index, char *v1, int32_t level, int32_t primary) {
|
||||
|
|
|
@ -4273,39 +4273,34 @@ void tFreeSCMCreateStreamReq(SCMCreateStreamReq *pReq) {
|
|||
}
|
||||
|
||||
int32_t tEncodeSRSmaParam(SEncoder *pCoder, const SRSmaParam *pRSmaParam) {
|
||||
if (tEncodeFloat(pCoder, pRSmaParam->xFilesFactor) < 0) return -1;
|
||||
if (tEncodeI32v(pCoder, pRSmaParam->delay) < 0) return -1;
|
||||
if (tEncodeI32v(pCoder, pRSmaParam->qmsg1Len) < 0) return -1;
|
||||
if (tEncodeI32v(pCoder, pRSmaParam->qmsg2Len) < 0) return -1;
|
||||
if (pRSmaParam->qmsg1Len > 0) {
|
||||
if (tEncodeBinary(pCoder, pRSmaParam->qmsg1, (uint64_t)pRSmaParam->qmsg1Len) < 0) // qmsg1Len contains len of '\0'
|
||||
return -1;
|
||||
}
|
||||
if (pRSmaParam->qmsg2Len > 0) {
|
||||
if (tEncodeBinary(pCoder, pRSmaParam->qmsg2, (uint64_t)pRSmaParam->qmsg2Len) < 0) // qmsg2Len contains len of '\0'
|
||||
return -1;
|
||||
for (int32_t i = 0; i < 2; ++i) {
|
||||
if (tEncodeI64v(pCoder, pRSmaParam->maxdelay[i]) < 0) return -1;
|
||||
if (tEncodeI64v(pCoder, pRSmaParam->watermark[i]) < 0) return -1;
|
||||
if (tEncodeI32v(pCoder, pRSmaParam->qmsgLen[i]) < 0) return -1;
|
||||
if (pRSmaParam->qmsgLen[i] > 0) {
|
||||
if (tEncodeBinary(pCoder, pRSmaParam->qmsg[i], (uint64_t)pRSmaParam->qmsgLen[i]) <
|
||||
0) // qmsgLen contains len of '\0'
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeSRSmaParam(SDecoder *pCoder, SRSmaParam *pRSmaParam) {
|
||||
if (tDecodeFloat(pCoder, &pRSmaParam->xFilesFactor) < 0) return -1;
|
||||
if (tDecodeI32v(pCoder, &pRSmaParam->delay) < 0) return -1;
|
||||
if (tDecodeI32v(pCoder, &pRSmaParam->qmsg1Len) < 0) return -1;
|
||||
if (tDecodeI32v(pCoder, &pRSmaParam->qmsg2Len) < 0) return -1;
|
||||
if (pRSmaParam->qmsg1Len > 0) {
|
||||
uint64_t len;
|
||||
if (tDecodeBinaryAlloc(pCoder, (void **)&pRSmaParam->qmsg1, &len) < 0) return -1; // qmsg1Len contains len of '\0'
|
||||
} else {
|
||||
pRSmaParam->qmsg1 = NULL;
|
||||
}
|
||||
if (pRSmaParam->qmsg2Len > 0) {
|
||||
uint64_t len;
|
||||
if (tDecodeBinaryAlloc(pCoder, (void **)&pRSmaParam->qmsg2, &len) < 0) return -1; // qmsg2Len contains len of '\0'
|
||||
} else {
|
||||
pRSmaParam->qmsg2 = NULL;
|
||||
for (int32_t i = 0; i < 2; ++i) {
|
||||
if (tDecodeI64v(pCoder, &pRSmaParam->maxdelay[i]) < 0) return -1;
|
||||
if (tDecodeI64v(pCoder, &pRSmaParam->watermark[i]) < 0) return -1;
|
||||
if (tDecodeI32v(pCoder, &pRSmaParam->qmsgLen[i]) < 0) return -1;
|
||||
if (pRSmaParam->qmsgLen[i] > 0) {
|
||||
uint64_t len;
|
||||
if (tDecodeBinaryAlloc(pCoder, (void **)&pRSmaParam->qmsg[i], &len) < 0)
|
||||
return -1; // qmsgLen contains len of '\0'
|
||||
} else {
|
||||
pRSmaParam->qmsg[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,9 +95,12 @@ SArray *smGetMsgHandles() {
|
|||
if (dmSetMgmtHandle(pArray, TDMT_MON_SM_INFO, smPutNodeMsgToMonitorQueue, 0) == NULL) goto _OVER;
|
||||
|
||||
if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DEPLOY, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TASK_DROP, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RUN, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DISPATCH, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DISPATCH_RSP, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RECOVER, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RECOVER_RSP, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER;
|
||||
|
||||
code = 0;
|
||||
_OVER:
|
||||
|
|
|
@ -55,7 +55,9 @@ static void smProcessUniqueQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t num
|
|||
taosGetQitem(qall, (void **)&pMsg);
|
||||
|
||||
dTrace("msg:%p, get from snode-unique queue", pMsg);
|
||||
sndProcessUMsg(pMgmt->pSnode, pMsg);
|
||||
if (sndProcessUMsg(pMgmt->pSnode, pMsg) < 0) {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
dTrace("msg:%p, is freed", pMsg);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
|
@ -67,7 +69,9 @@ static void smProcessSharedQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
|
|||
SSnodeMgmt *pMgmt = pInfo->ahandle;
|
||||
|
||||
dTrace("msg:%p, get from snode-shared queue", pMsg);
|
||||
sndProcessSMsg(pMgmt->pSnode, pMsg);
|
||||
if (sndProcessSMsg(pMgmt->pSnode, pMsg) < 0) {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
dTrace("msg:%p, is freed", pMsg);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
|
|
|
@ -170,10 +170,6 @@ static int32_t vmPutMsgToQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg, EQueueType qtyp
|
|||
dTrace("vgId:%d, msg:%p put into vnode-sync queue", pVnode->vgId, pMsg);
|
||||
taosWriteQitem(pVnode->pSyncQ, pMsg);
|
||||
break;
|
||||
case MERGE_QUEUE:
|
||||
dTrace("vgId:%d, msg:%p put into vnode-merge queue", pVnode->vgId, pMsg);
|
||||
taosWriteQitem(pVnode->pMergeQ, pMsg);
|
||||
break;
|
||||
case APPLY_QUEUE:
|
||||
dTrace("vgId:%d, msg:%p put into vnode-apply queue", pVnode->vgId, pMsg);
|
||||
taosWriteQitem(pVnode->pApplyQ, pMsg);
|
||||
|
@ -196,8 +192,6 @@ int32_t vmPutMsgToQueryQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return vmPutMsg
|
|||
|
||||
int32_t vmPutMsgToFetchQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return vmPutMsgToQueue(pMgmt, pMsg, FETCH_QUEUE); }
|
||||
|
||||
int32_t vmPutMsgToMergeQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return vmPutMsgToQueue(pMgmt, pMsg, MERGE_QUEUE); }
|
||||
|
||||
int32_t vmPutMsgToMgmtQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
||||
dTrace("msg:%p, put into vnode-mgmt queue", pMsg);
|
||||
taosWriteQitem(pMgmt->mgmtWorker.queue, pMsg);
|
||||
|
@ -243,9 +237,6 @@ int32_t vmGetQueueSize(SVnodeMgmt *pMgmt, int32_t vgId, EQueueType qtype) {
|
|||
case FETCH_QUEUE:
|
||||
size = taosQueueItemSize(pVnode->pFetchQ);
|
||||
break;
|
||||
case MERGE_QUEUE:
|
||||
size = taosQueueItemSize(pVnode->pMergeQ);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -341,8 +341,8 @@ typedef struct {
|
|||
int32_t colVer;
|
||||
int32_t smaVer;
|
||||
int32_t nextColId;
|
||||
float xFilesFactor;
|
||||
int32_t delay;
|
||||
int64_t watermark[2];
|
||||
int64_t maxdelay[2];
|
||||
int32_t ttl;
|
||||
int32_t numOfColumns;
|
||||
int32_t numOfTags;
|
||||
|
|
|
@ -30,7 +30,7 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
|
|||
int32_t mndScheduleStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream);
|
||||
|
||||
int32_t mndConvertRsmaTask(char** pDst, int32_t* pDstLen, const char* ast, int64_t uid, int8_t triggerType,
|
||||
int64_t watermark, double filesFactor);
|
||||
int64_t watermark);
|
||||
|
||||
int32_t mndScheduleStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream);
|
||||
|
||||
|
|
|
@ -554,6 +554,8 @@ static int32_t mndCheckMnodeState(SRpcMsg *pMsg) {
|
|||
pMsg->msgType != TDMT_MND_TRANS_TIMER) {
|
||||
mError("msg:%p, failed to check mnode state since %s, type:%s", pMsg, terrstr(), TMSG_INFO(pMsg->msgType));
|
||||
|
||||
mndAbortPreprocessMsg(pMsg);
|
||||
|
||||
SEpSet epSet = {0};
|
||||
mndGetMnodeEpSet(pMsg->info.node, &epSet);
|
||||
|
||||
|
|
|
@ -25,6 +25,13 @@ int32_t mndPreProcessMsg(SRpcMsg *pMsg) {
|
|||
return qWorkerPreprocessQueryMsg(pMnode->pQuery, pMsg);
|
||||
}
|
||||
|
||||
void mndAbortPreprocessMsg(SRpcMsg *pMsg) {
|
||||
if (TDMT_VND_QUERY != pMsg->msgType) return;
|
||||
|
||||
SMnode *pMnode = pMsg->info.node;
|
||||
qWorkerAbortPreprocessQueryMsg(pMnode->pQuery, pMsg);
|
||||
}
|
||||
|
||||
int32_t mndProcessQueryMsg(SRpcMsg *pMsg) {
|
||||
int32_t code = -1;
|
||||
SMnode *pMnode = pMsg->info.node;
|
||||
|
|
|
@ -43,7 +43,7 @@ static int32_t mndAddTaskToTaskSet(SArray* pArray, SStreamTask* pTask) {
|
|||
}
|
||||
|
||||
int32_t mndConvertRsmaTask(char** pDst, int32_t* pDstLen, const char* ast, int64_t uid, int8_t triggerType,
|
||||
int64_t watermark, double filesFactor) {
|
||||
int64_t watermark) {
|
||||
SNode* pAst = NULL;
|
||||
SQueryPlan* pPlan = NULL;
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
@ -63,9 +63,8 @@ int32_t mndConvertRsmaTask(char** pDst, int32_t* pDstLen, const char* ast, int64
|
|||
.topicQuery = false,
|
||||
.streamQuery = true,
|
||||
.rSmaQuery = true,
|
||||
.triggerType = STREAM_TRIGGER_AT_ONCE,
|
||||
.triggerType = triggerType,
|
||||
.watermark = watermark,
|
||||
/*.filesFactor = filesFactor,*/
|
||||
};
|
||||
|
||||
if (qCreateQueryPlan(&cxt, &pPlan, NULL) < 0) {
|
||||
|
@ -270,7 +269,6 @@ int32_t mndAddShuffleSinkTasksToStream(SMnode* pMnode, STrans* pTrans, SStreamOb
|
|||
pTask->epSet = mndGetVgroupEpset(pMnode, pVgroup);
|
||||
|
||||
// source
|
||||
pTask->sourceType = TASK_SOURCE__MERGE;
|
||||
pTask->inputType = TASK_INPUT_TYPE__DATA_BLOCK;
|
||||
|
||||
// exec
|
||||
|
@ -316,7 +314,6 @@ int32_t mndAddFixedSinkTaskToStream(SMnode* pMnode, STrans* pTrans, SStreamObj*
|
|||
#endif
|
||||
pTask->epSet = mndGetVgroupEpset(pMnode, &pStream->fixedSinkVg);
|
||||
// source
|
||||
pTask->sourceType = TASK_SOURCE__MERGE;
|
||||
pTask->inputType = TASK_INPUT_TYPE__DATA_BLOCK;
|
||||
|
||||
// exec
|
||||
|
@ -427,6 +424,8 @@ int32_t mndScheduleStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream) {
|
|||
SStreamTask* pTask = tNewSStreamTask(pStream->uid);
|
||||
mndAddTaskToTaskSet(taskSourceLevel, pTask);
|
||||
|
||||
pTask->dataScan = 1;
|
||||
|
||||
// input
|
||||
pTask->inputType = TASK_INPUT_TYPE__SUMBIT_BLOCK;
|
||||
|
||||
|
@ -470,6 +469,8 @@ int32_t mndScheduleStream(SMnode* pMnode, STrans* pTrans, SStreamObj* pStream) {
|
|||
SStreamTask* pTask = tNewSStreamTask(pStream->uid);
|
||||
mndAddTaskToTaskSet(taskOneLevel, pTask);
|
||||
|
||||
pTask->dataScan = 1;
|
||||
|
||||
// input
|
||||
pTask->inputType = TASK_INPUT_TYPE__SUMBIT_BLOCK;
|
||||
|
||||
|
|
|
@ -89,8 +89,10 @@ SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
|
|||
SDB_SET_INT32(pRaw, dataPos, pStb->tagVer, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pStb->colVer, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pStb->nextColId, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, (int32_t)(pStb->xFilesFactor * 10000), _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pStb->delay, _OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->maxdelay[0], _OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->maxdelay[1], _OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->watermark[0], _OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pStb->watermark[1], _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pStb->ttl, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pStb->numOfColumns, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pStb->numOfTags, _OVER)
|
||||
|
@ -168,10 +170,10 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
|
|||
SDB_GET_INT32(pRaw, dataPos, &pStb->tagVer, _OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &pStb->colVer, _OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &pStb->nextColId, _OVER)
|
||||
int32_t xFilesFactor = 0;
|
||||
SDB_GET_INT32(pRaw, dataPos, &xFilesFactor, _OVER)
|
||||
pStb->xFilesFactor = xFilesFactor / 10000.0f;
|
||||
SDB_GET_INT32(pRaw, dataPos, &pStb->delay, _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pStb->maxdelay[0], _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pStb->maxdelay[1], _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pStb->watermark[0], _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pStb->watermark[1], _OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &pStb->ttl, _OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &pStb->numOfColumns, _OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &pStb->numOfTags, _OVER)
|
||||
|
@ -399,18 +401,18 @@ static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pSt
|
|||
req.schemaTag.pSchema = pStb->pTags;
|
||||
|
||||
if (req.rollup) {
|
||||
req.pRSmaParam.xFilesFactor = pStb->xFilesFactor;
|
||||
req.pRSmaParam.delay = pStb->delay;
|
||||
req.pRSmaParam.maxdelay[0] = pStb->maxdelay[0];
|
||||
req.pRSmaParam.maxdelay[1] = pStb->maxdelay[1];
|
||||
if (pStb->ast1Len > 0) {
|
||||
if (mndConvertRsmaTask(&req.pRSmaParam.qmsg1, &req.pRSmaParam.qmsg1Len, pStb->pAst1, pStb->uid,
|
||||
STREAM_TRIGGER_AT_ONCE, 0, req.pRSmaParam.xFilesFactor) != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
if (mndConvertRsmaTask(&req.pRSmaParam.qmsg[0], &req.pRSmaParam.qmsgLen[0], pStb->pAst1, pStb->uid,
|
||||
STREAM_TRIGGER_WINDOW_CLOSE, req.pRSmaParam.watermark[0]) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
if (pStb->ast2Len > 0) {
|
||||
if (mndConvertRsmaTask(&req.pRSmaParam.qmsg2, &req.pRSmaParam.qmsg2Len, pStb->pAst2, pStb->uid,
|
||||
STREAM_TRIGGER_AT_ONCE, 0, req.pRSmaParam.xFilesFactor) != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
if (mndConvertRsmaTask(&req.pRSmaParam.qmsg[1], &req.pRSmaParam.qmsgLen[1], pStb->pAst2, pStb->uid,
|
||||
STREAM_TRIGGER_WINDOW_CLOSE, req.pRSmaParam.watermark[1]) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -418,17 +420,15 @@ static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pSt
|
|||
int32_t ret = 0;
|
||||
tEncodeSize(tEncodeSVCreateStbReq, &req, contLen, ret);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
contLen += sizeof(SMsgHead);
|
||||
|
||||
SMsgHead *pHead = taosMemoryMalloc(contLen);
|
||||
if (pHead == NULL) {
|
||||
taosMemoryFreeClear(req.pRSmaParam.qmsg1);
|
||||
taosMemoryFreeClear(req.pRSmaParam.qmsg2);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
pHead->contLen = htonl(contLen);
|
||||
|
@ -438,17 +438,19 @@ static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pSt
|
|||
tEncoderInit(&encoder, pBuf, contLen - sizeof(SMsgHead));
|
||||
if (tEncodeSVCreateStbReq(&encoder, &req) < 0) {
|
||||
taosMemoryFreeClear(pHead);
|
||||
taosMemoryFreeClear(req.pRSmaParam.qmsg1);
|
||||
taosMemoryFreeClear(req.pRSmaParam.qmsg2);
|
||||
tEncoderClear(&encoder);
|
||||
return NULL;
|
||||
goto _err;
|
||||
}
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
*pContLen = contLen;
|
||||
taosMemoryFreeClear(req.pRSmaParam.qmsg1);
|
||||
taosMemoryFreeClear(req.pRSmaParam.qmsg2);
|
||||
taosMemoryFreeClear(req.pRSmaParam.qmsg[0]);
|
||||
taosMemoryFreeClear(req.pRSmaParam.qmsg[1]);
|
||||
return pHead;
|
||||
_err:
|
||||
taosMemoryFreeClear(req.pRSmaParam.qmsg[0]);
|
||||
taosMemoryFreeClear(req.pRSmaParam.qmsg[1]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *mndBuildVDropStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) {
|
||||
|
@ -670,8 +672,10 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat
|
|||
pDst->tagVer = 1;
|
||||
pDst->colVer = 1;
|
||||
pDst->nextColId = 1;
|
||||
// pDst->xFilesFactor = pCreate->xFilesFactor;
|
||||
// pDst->delay = pCreate->delay;
|
||||
pDst->maxdelay[0] = pCreate->delay1;
|
||||
pDst->maxdelay[1] = pCreate->delay2;
|
||||
pDst->watermark[0] = pCreate->watermark1;
|
||||
pDst->watermark[1] = pCreate->watermark2;
|
||||
pDst->ttl = pCreate->ttl;
|
||||
pDst->numOfColumns = pCreate->numOfColumns;
|
||||
pDst->numOfTags = pCreate->numOfTags;
|
||||
|
@ -897,7 +901,7 @@ static int32_t mndUpdateStbCommentAndTTL(const SStbObj *pOld, SStbObj *pNew, cha
|
|||
return -1;
|
||||
}
|
||||
memcpy(pNew->comment, pComment, commentLen + 1);
|
||||
} else if(commentLen == 0){
|
||||
} else if (commentLen == 0) {
|
||||
pNew->commentLen = 0;
|
||||
}
|
||||
|
||||
|
@ -1849,7 +1853,7 @@ static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBloc
|
|||
char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(comment, pStb->comment);
|
||||
colDataAppend(pColInfo, numOfRows, comment, false);
|
||||
} else if(pStb->commentLen == 0) {
|
||||
} else if (pStb->commentLen == 0) {
|
||||
char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(comment, "");
|
||||
colDataAppend(pColInfo, numOfRows, comment, false);
|
||||
|
|
|
@ -68,8 +68,9 @@ void mndSyncCommitMsg(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbM
|
|||
mndTransExecute(pMnode, pTrans);
|
||||
mndReleaseTrans(pMnode, pTrans);
|
||||
}
|
||||
|
||||
#if 0
|
||||
sdbWriteFile(pMnode->pSdb, SDB_WRITE_DELTA);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -804,7 +804,7 @@ static void mndTransSendRpcRsp(SMnode *pMnode, STrans *pTrans) {
|
|||
sendRsp = true;
|
||||
}
|
||||
} else {
|
||||
if (pTrans->stage == TRN_STAGE_REDO_ACTION && pTrans->failedTimes > 2) {
|
||||
if (pTrans->stage == TRN_STAGE_REDO_ACTION && pTrans->failedTimes > 3) {
|
||||
if (code == 0) code = TSDB_CODE_MND_TRANS_UNKNOW_ERROR;
|
||||
sendRsp = true;
|
||||
}
|
||||
|
@ -1127,6 +1127,7 @@ static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans)
|
|||
}
|
||||
|
||||
if (code == 0) {
|
||||
pTrans->failedTimes = 0;
|
||||
pTrans->lastAction = action;
|
||||
pTrans->lastMsgType = 0;
|
||||
pTrans->lastErrorNo = 0;
|
||||
|
@ -1430,8 +1431,7 @@ void mndTransPullup(SMnode *pMnode) {
|
|||
mndReleaseTrans(pMnode, pTrans);
|
||||
}
|
||||
|
||||
// todo, set to SDB_WRITE_DELTA
|
||||
sdbWriteFile(pMnode->pSdb, 0);
|
||||
sdbWriteFile(pMnode->pSdb, SDB_WRITE_DELTA);
|
||||
taosArrayDestroy(pArray);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ extern "C" {
|
|||
#define mTrace(...) { if (mDebugFlag & DEBUG_TRACE) { taosPrintLog("MND ", DEBUG_TRACE, mDebugFlag, __VA_ARGS__); }}
|
||||
// clang-format on
|
||||
|
||||
#define SDB_WRITE_DELTA 100
|
||||
#define SDB_WRITE_DELTA 20
|
||||
|
||||
#define SDB_GET_VAL(pData, dataPos, val, pos, func, type) \
|
||||
{ \
|
||||
|
|
|
@ -161,9 +161,11 @@ static int32_t sdbCreateDir(SSdb *pSdb) {
|
|||
}
|
||||
|
||||
void sdbSetApplyInfo(SSdb *pSdb, int64_t index, int64_t term, int64_t config) {
|
||||
mTrace("mnode apply info changed, from index:%" PRId64 " term:%" PRId64 " config:%" PRId64 ", to index:%" PRId64
|
||||
#if 1
|
||||
mTrace("mnode apply info changed from index:%" PRId64 " term:%" PRId64 " config:%" PRId64 " to index:%" PRId64
|
||||
" term:%" PRId64 " config:%" PRId64,
|
||||
pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig, index, term, config);
|
||||
#endif
|
||||
pSdb->applyIndex = index;
|
||||
pSdb->applyTerm = term;
|
||||
pSdb->applyConfig = config;
|
||||
|
@ -173,7 +175,9 @@ void sdbGetCommitInfo(SSdb *pSdb, int64_t *index, int64_t *term, int64_t *config
|
|||
*index = pSdb->commitIndex;
|
||||
*term = pSdb->commitTerm;
|
||||
*config = pSdb->commitConfig;
|
||||
#if 0
|
||||
mTrace("mnode current info, apply index:%" PRId64 " term:%" PRId64 " config:%" PRId64 ", commit index:%" PRId64
|
||||
" term:%" PRId64 " config:%" PRId64,
|
||||
pSdb->applyIndex, pSdb->applyTerm, pSdb->applyConfig, *index, *term, *config);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ SStreamTask* sndMetaGetTask(SStreamMeta* pMeta, int32_t taskId);
|
|||
int32_t sndMetaRemoveTask(SStreamMeta* pMeta, int32_t taskId);
|
||||
|
||||
int32_t sndDropTaskOfStream(SStreamMeta* pMeta, int64_t streamId);
|
||||
|
||||
int32_t sndStopTaskOfStream(SStreamMeta* pMeta, int64_t streamId);
|
||||
int32_t sndResumeTaskOfStream(SStreamMeta* pMeta, int64_t streamId);
|
||||
|
||||
|
|
|
@ -76,45 +76,158 @@ int32_t sndMetaRemoveTask(SStreamMeta *pMeta, int32_t taskId) {
|
|||
return taosHashRemove(pMeta->pHash, &taskId, sizeof(int32_t));
|
||||
}
|
||||
|
||||
static int32_t sndProcessTaskExecReq(SSnode *pSnode, SRpcMsg *pMsg) {
|
||||
/*SStreamExecMsgHead *pHead = pMsg->pCont;*/
|
||||
/*int32_t taskId = pHead->streamTaskId;*/
|
||||
/*SStreamTask *pTask = sndMetaGetTask(pSnode->pMeta, taskId);*/
|
||||
/*if (pTask == NULL) {*/
|
||||
/*return -1;*/
|
||||
/*}*/
|
||||
static int32_t sndProcessTaskDeployReq(SSnode *pNode, SRpcMsg *pMsg) {
|
||||
SStreamMeta *pMeta = pNode->pMeta;
|
||||
char *msg = pMsg->pCont;
|
||||
int32_t msgLen = pMsg->contLen;
|
||||
|
||||
SStreamTask *pTask = taosMemoryCalloc(1, sizeof(SStreamTask));
|
||||
if (pTask == NULL) {
|
||||
return -1;
|
||||
}
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, (uint8_t *)msg, msgLen);
|
||||
if (tDecodeSStreamTask(&decoder, pTask) < 0) {
|
||||
ASSERT(0);
|
||||
}
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
pTask->status = TASK_STATUS__IDLE;
|
||||
|
||||
pTask->inputQueue = streamQueueOpen();
|
||||
pTask->outputQueue = streamQueueOpen();
|
||||
pTask->inputStatus = TASK_INPUT_STATUS__NORMAL;
|
||||
pTask->outputStatus = TASK_INPUT_STATUS__NORMAL;
|
||||
|
||||
if (pTask->inputQueue == NULL || pTask->outputQueue == NULL) goto FAIL;
|
||||
|
||||
pTask->pMsgCb = &pNode->msgCb;
|
||||
|
||||
ASSERT(pTask->execType != TASK_EXEC__NONE);
|
||||
|
||||
SReadHandle handle = {
|
||||
.pMsgCb = &pNode->msgCb,
|
||||
};
|
||||
|
||||
/*pTask->exec.inputHandle = NULL;*/
|
||||
pTask->exec.executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle);
|
||||
ASSERT(pTask->exec.executor);
|
||||
|
||||
streamSetupTrigger(pTask);
|
||||
|
||||
qInfo("deploy stream: stream id %ld task id %d child id %d on snode", pTask->streamId, pTask->taskId, pTask->childId);
|
||||
|
||||
return 0;
|
||||
|
||||
FAIL:
|
||||
if (pTask->inputQueue) streamQueueClose(pTask->inputQueue);
|
||||
if (pTask->outputQueue) streamQueueClose(pTask->outputQueue);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t sndProcessTaskRunReq(SSnode *pNode, SRpcMsg *pMsg) {
|
||||
SStreamMeta *pMeta = pNode->pMeta;
|
||||
SStreamTaskRunReq *pReq = pMsg->pCont;
|
||||
int32_t taskId = pReq->taskId;
|
||||
SStreamTask *pTask = *(SStreamTask **)taosHashGet(pMeta->pHash, &taskId, sizeof(int32_t));
|
||||
streamTaskProcessRunReq(pTask, &pNode->msgCb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sndProcessUMsg(SSnode *pSnode, SRpcMsg *pMsg) {
|
||||
static int32_t sndProcessTaskDispatchReq(SSnode *pNode, SRpcMsg *pMsg) {
|
||||
SStreamMeta *pMeta = pNode->pMeta;
|
||||
|
||||
char *msgStr = pMsg->pCont;
|
||||
char *msgBody = POINTER_SHIFT(msgStr, sizeof(SMsgHead));
|
||||
int32_t msgLen = pMsg->contLen - sizeof(SMsgHead);
|
||||
|
||||
SStreamDispatchReq req;
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, msgBody, msgLen);
|
||||
tDecodeStreamDispatchReq(&decoder, &req);
|
||||
int32_t taskId = req.taskId;
|
||||
SStreamTask *pTask = *(SStreamTask **)taosHashGet(pMeta->pHash, &taskId, sizeof(int32_t));
|
||||
SRpcMsg rsp = {
|
||||
.info = pMsg->info,
|
||||
.code = 0,
|
||||
};
|
||||
streamProcessDispatchReq(pTask, &pNode->msgCb, &req, &rsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t sndProcessTaskRecoverReq(SSnode *pNode, SRpcMsg *pMsg) {
|
||||
SStreamMeta *pMeta = pNode->pMeta;
|
||||
|
||||
SStreamTaskRecoverReq *pReq = pMsg->pCont;
|
||||
int32_t taskId = pReq->taskId;
|
||||
SStreamTask *pTask = *(SStreamTask **)taosHashGet(pMeta->pHash, &taskId, sizeof(int32_t));
|
||||
streamProcessRecoverReq(pTask, &pNode->msgCb, pReq, pMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t sndProcessTaskDispatchRsp(SSnode *pNode, SRpcMsg *pMsg) {
|
||||
SStreamMeta *pMeta = pNode->pMeta;
|
||||
|
||||
SStreamDispatchRsp *pRsp = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||
int32_t taskId = pRsp->taskId;
|
||||
SStreamTask *pTask = *(SStreamTask **)taosHashGet(pMeta->pHash, &taskId, sizeof(int32_t));
|
||||
streamProcessDispatchRsp(pTask, &pNode->msgCb, pRsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t sndProcessTaskRecoverRsp(SSnode *pNode, SRpcMsg *pMsg) {
|
||||
SStreamMeta *pMeta = pNode->pMeta;
|
||||
|
||||
SStreamTaskRecoverRsp *pRsp = pMsg->pCont;
|
||||
int32_t taskId = pRsp->taskId;
|
||||
SStreamTask *pTask = *(SStreamTask **)taosHashGet(pMeta->pHash, &taskId, sizeof(int32_t));
|
||||
streamProcessRecoverRsp(pTask, pRsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t sndProcessTaskDropReq(SSnode *pNode, SRpcMsg *pMsg) {
|
||||
SStreamMeta *pMeta = pNode->pMeta;
|
||||
|
||||
char *msg = pMsg->pCont;
|
||||
int32_t msgLen = pMsg->contLen;
|
||||
SVDropStreamTaskReq *pReq = (SVDropStreamTaskReq *)msg;
|
||||
int32_t code = taosHashRemove(pMeta->pHash, &pReq->taskId, sizeof(int32_t));
|
||||
ASSERT(code == 0);
|
||||
if (code == 0) {
|
||||
// sendrsp
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t sndProcessUMsg(SSnode *pSnode, SRpcMsg *pMsg) {
|
||||
// stream deploy
|
||||
// stream stop/resume
|
||||
// operator exec
|
||||
if (pMsg->msgType == TDMT_STREAM_TASK_DEPLOY) {
|
||||
void *msg = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||
SStreamTask *pTask = taosMemoryMalloc(sizeof(SStreamTask));
|
||||
if (pTask == NULL) {
|
||||
switch (pMsg->msgType) {
|
||||
case TDMT_STREAM_TASK_DEPLOY:
|
||||
return sndProcessTaskDeployReq(pSnode, pMsg);
|
||||
case TDMT_VND_STREAM_TASK_DROP:
|
||||
return sndProcessTaskDropReq(pSnode, pMsg);
|
||||
default:
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, msg, pMsg->contLen - sizeof(SMsgHead));
|
||||
tDecodeSStreamTask(&decoder, pTask);
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
sndMetaDeployTask(pSnode->pMeta, pTask);
|
||||
/*} else if (pMsg->msgType == TDMT_SND_TASK_EXEC) {*/
|
||||
/*sndProcessTaskExecReq(pSnode, pMsg);*/
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sndProcessSMsg(SSnode *pSnode, SRpcMsg *pMsg) {
|
||||
// operator exec
|
||||
/*if (pMsg->msgType == TDMT_SND_TASK_EXEC) {*/
|
||||
/*sndProcessTaskExecReq(pSnode, pMsg);*/
|
||||
/*} else {*/
|
||||
ASSERT(0);
|
||||
/*}*/
|
||||
int32_t sndProcessSMsg(SSnode *pSnode, SRpcMsg *pMsg) {
|
||||
switch (pMsg->msgType) {
|
||||
case TDMT_STREAM_TASK_RUN:
|
||||
return sndProcessTaskRunReq(pSnode, pMsg);
|
||||
case TDMT_STREAM_TASK_DISPATCH:
|
||||
return sndProcessTaskDispatchReq(pSnode, pMsg);
|
||||
case TDMT_STREAM_TASK_RECOVER:
|
||||
return sndProcessTaskRecoverReq(pSnode, pMsg);
|
||||
case TDMT_STREAM_TASK_DISPATCH_RSP:
|
||||
return sndProcessTaskDispatchRsp(pSnode, pMsg);
|
||||
case TDMT_STREAM_TASK_RECOVER_RSP:
|
||||
return sndProcessTaskRecoverRsp(pSnode, pMsg);
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ typedef void *tsdbReaderT;
|
|||
#define BLOCK_LOAD_TABLE_SEQ_ORDER 2
|
||||
#define BLOCK_LOAD_TABLE_RR_ORDER 3
|
||||
|
||||
tsdbReaderT *tsdbReaderOpen(SVnode *pVnode, SQueryTableDataCond *pCond, STableListInfo *tableInfoGroup, uint64_t qId,
|
||||
tsdbReaderT tsdbReaderOpen(SVnode *pVnode, SQueryTableDataCond *pCond, STableListInfo *tableInfoGroup, uint64_t qId,
|
||||
uint64_t taskId);
|
||||
tsdbReaderT tsdbQueryCacheLast(SVnode *pVnode, SQueryTableDataCond *pCond, STableListInfo *groupList, uint64_t qId,
|
||||
void *pMemRef);
|
||||
|
|
|
@ -32,11 +32,12 @@ extern "C" {
|
|||
#define smaTrace(...) do { if (smaDebugFlag & DEBUG_TRACE) { taosPrintLog("SMA ", DEBUG_TRACE, tsdbDebugFlag, __VA_ARGS__); }} while(0)
|
||||
// clang-format on
|
||||
|
||||
typedef struct SSmaEnv SSmaEnv;
|
||||
typedef struct SSmaStat SSmaStat;
|
||||
typedef struct SSmaStatItem SSmaStatItem;
|
||||
typedef struct SSmaKey SSmaKey;
|
||||
typedef struct SRSmaInfo SRSmaInfo;
|
||||
typedef struct SSmaEnv SSmaEnv;
|
||||
typedef struct SSmaStat SSmaStat;
|
||||
typedef struct SSmaStatItem SSmaStatItem;
|
||||
typedef struct SSmaKey SSmaKey;
|
||||
typedef struct SRSmaInfo SRSmaInfo;
|
||||
typedef struct SRSmaInfoItem SRSmaInfoItem;
|
||||
|
||||
struct SSmaEnv {
|
||||
TdThreadRwlock lock;
|
||||
|
|
|
@ -121,7 +121,7 @@ int tsdbInsertData(STsdb* pTsdb, int64_t version, SSubmitReq* pMsg, SSu
|
|||
int32_t tsdbInsertTableData(STsdb* pTsdb, int64_t version, SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock,
|
||||
SSubmitBlkRsp* pRsp);
|
||||
int32_t tsdbDeleteTableData(STsdb* pTsdb, int64_t version, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKEY eKey);
|
||||
tsdbReaderT* tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, STableListInfo* tableList, uint64_t qId,
|
||||
tsdbReaderT tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, STableListInfo* tableList, uint64_t qId,
|
||||
uint64_t taskId);
|
||||
tsdbReaderT tsdbQueryCacheLastT(STsdb* tsdb, SQueryTableDataCond* pCond, STableListInfo* tableList, uint64_t qId,
|
||||
void* pMemRef);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#include "sma.h"
|
||||
|
||||
// functions for external invocation
|
||||
|
||||
// TODO: Who is responsible for resource allocate and release?
|
||||
int32_t tdProcessTSmaInsert(SSma* pSma, int64_t indexUid, const char* msg) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
@ -45,6 +47,9 @@ int32_t smaGetTSmaDays(SVnodeCfg* pCfg, void* pCont, uint32_t contLen, int32_t*
|
|||
return code;
|
||||
}
|
||||
|
||||
|
||||
// functions for internal invocation
|
||||
|
||||
#if 0
|
||||
|
||||
/**
|
||||
|
|
|
@ -208,7 +208,6 @@ int32_t tdUnLockSma(SSma *pSma) {
|
|||
int32_t tdCheckAndInitSmaEnv(SSma *pSma, int8_t smaType) {
|
||||
SSmaEnv *pEnv = NULL;
|
||||
|
||||
// return if already init
|
||||
switch (smaType) {
|
||||
case TSDB_SMA_TYPE_TIME_RANGE:
|
||||
if ((pEnv = (SSmaEnv *)atomic_load_ptr(&SMA_TSMA_ENV(pSma)))) {
|
||||
|
@ -244,3 +243,34 @@ int32_t tdCheckAndInitSmaEnv(SSma *pSma, int8_t smaType) {
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
};
|
||||
|
||||
int32_t smaTimerInit(void **timer, int8_t *initFlag, const char *label) {
|
||||
int8_t old;
|
||||
while (1) {
|
||||
old = atomic_val_compare_exchange_8(initFlag, 0, 2);
|
||||
if (old != 2) break;
|
||||
}
|
||||
|
||||
if (old == 0) {
|
||||
*timer = taosTmrInit(10000, 100, 10000, label);
|
||||
if (!(*timer)) {
|
||||
atomic_store_8(initFlag, 0);
|
||||
return -1;
|
||||
}
|
||||
atomic_store_8(initFlag, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void smaTimerCleanUp(void *timer, int8_t *initFlag) {
|
||||
int8_t old;
|
||||
while (1) {
|
||||
old = atomic_val_compare_exchange_8(initFlag, 1, 2);
|
||||
if (old != 2) break;
|
||||
}
|
||||
|
||||
if (old == 1) {
|
||||
taosTmrCleanUp(timer);
|
||||
atomic_store_8(initFlag, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,61 @@
|
|||
*/
|
||||
|
||||
#include "sma.h"
|
||||
#include "tstream.h"
|
||||
|
||||
static FORCE_INLINE int32_t tdUidStorePut(STbUidStore *pStore, tb_uid_t suid, tb_uid_t *uid);
|
||||
static FORCE_INLINE int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids);
|
||||
static FORCE_INLINE int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t inputType, qTaskInfo_t *taskInfo,
|
||||
STSchema *pTSchema, tb_uid_t suid, int8_t level);
|
||||
static FORCE_INLINE int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t inputType, SRSmaInfoItem *rsmaItem,
|
||||
tb_uid_t suid, int8_t level);
|
||||
|
||||
#define SET_RSMA_INFO_ITEM_PARAMS(__idx, __level) \
|
||||
if (param->qmsg[__idx]) { \
|
||||
pRSmaInfo->items[__idx].pRsmaInfo = pRSmaInfo; \
|
||||
pRSmaInfo->items[__idx].taskInfo = qCreateStreamExecTaskInfo(param->qmsg[0], &handle); \
|
||||
if (!pRSmaInfo->items[__idx].taskInfo) { \
|
||||
goto _err; \
|
||||
} \
|
||||
pRSmaInfo->items[__idx].triggerStatus = TASK_TRIGGER_STATUS__IN_ACTIVE; \
|
||||
if (param->maxdelay[__idx] < 1) { \
|
||||
int64_t msInterval = \
|
||||
convertTimeFromPrecisionToUnit(pRetention[__level].freq, pTsdbCfg->precision, TIME_UNIT_MILLISECOND); \
|
||||
pRSmaInfo->items[__idx].maxDelay = msInterval; \
|
||||
} else { \
|
||||
pRSmaInfo->items[__idx].maxDelay = param->maxdelay[__idx]; \
|
||||
} \
|
||||
if (pRSmaInfo->items[__idx].maxDelay > TSDB_MAX_ROLLUP_MAX_DELAY) { \
|
||||
pRSmaInfo->items[__idx].maxDelay = TSDB_MAX_ROLLUP_MAX_DELAY; \
|
||||
} \
|
||||
pRSmaInfo->items[__idx].level = TSDB_RETENTION_L##__level; \
|
||||
pRSmaInfo->items[__idx].tmrHandle = taosTmrInit(10000, 100, 10000, "RSMA"); \
|
||||
if (!pRSmaInfo->items[__idx].tmrHandle) { \
|
||||
goto _err; \
|
||||
} \
|
||||
}
|
||||
|
||||
struct SRSmaInfoItem {
|
||||
SRSmaInfo *pRsmaInfo;
|
||||
void *taskInfo; // qTaskInfo_t
|
||||
void *tmrHandle;
|
||||
tmr_h tmrId;
|
||||
int8_t level;
|
||||
int8_t tmrInitFlag;
|
||||
int8_t triggerStatus; // TASK_TRIGGER_STATUS__IN_ACTIVE/TASK_TRIGGER_STATUS__ACTIVE
|
||||
int32_t maxDelay;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int64_t suid;
|
||||
SRSmaInfoItem *pItem;
|
||||
SSma *pSma;
|
||||
STSchema *pTSchema;
|
||||
} SRSmaTriggerParam;
|
||||
|
||||
struct SRSmaInfo {
|
||||
void *taskInfo[TSDB_RETENTION_L2]; // qTaskInfo_t
|
||||
STSchema *pTSchema;
|
||||
SSma *pSma;
|
||||
int64_t suid;
|
||||
SRSmaInfoItem items[TSDB_RETENTION_L2];
|
||||
};
|
||||
|
||||
static FORCE_INLINE void tdFreeTaskHandle(qTaskInfo_t *taskHandle) {
|
||||
|
@ -33,11 +80,20 @@ static FORCE_INLINE void tdFreeTaskHandle(qTaskInfo_t *taskHandle) {
|
|||
}
|
||||
|
||||
void *tdFreeRSmaInfo(SRSmaInfo *pInfo) {
|
||||
for (int32_t i = 0; i < TSDB_RETENTION_MAX; ++i) {
|
||||
if (pInfo->taskInfo[i]) {
|
||||
tdFreeTaskHandle(pInfo->taskInfo[i]);
|
||||
if (pInfo) {
|
||||
for (int32_t i = 0; i < TSDB_RETENTION_MAX; ++i) {
|
||||
SRSmaInfoItem *pItem = &pInfo->items[i];
|
||||
if (pItem->taskInfo) {
|
||||
tdFreeTaskHandle(pItem->taskInfo);
|
||||
}
|
||||
if (pItem->tmrHandle) {
|
||||
taosTmrCleanUp(pItem->tmrHandle);
|
||||
}
|
||||
}
|
||||
taosMemoryFree(pInfo->pTSchema);
|
||||
taosMemoryFree(pInfo);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -69,20 +125,20 @@ static FORCE_INLINE int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SA
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if (pRSmaInfo->taskInfo[0] && (qUpdateQualifiedTableId(pRSmaInfo->taskInfo[0], tbUids, true) != 0)) {
|
||||
if (pRSmaInfo->items[0].taskInfo && (qUpdateQualifiedTableId(pRSmaInfo->items[0].taskInfo, tbUids, true) < 0)) {
|
||||
smaError("vgId:%d, update tbUidList failed for uid:%" PRIi64 " since %s", SMA_VID(pSma), *suid, terrstr(terrno));
|
||||
return TSDB_CODE_FAILED;
|
||||
} else {
|
||||
smaDebug("vgId:%d, update tbUidList succeed for qTaskInfo:%p with suid:%" PRIi64 ", uid:%" PRIi64, SMA_VID(pSma),
|
||||
pRSmaInfo->taskInfo[0], *suid, *(int64_t *)taosArrayGet(tbUids, 0));
|
||||
pRSmaInfo->items[0].taskInfo, *suid, *(int64_t *)taosArrayGet(tbUids, 0));
|
||||
}
|
||||
|
||||
if (pRSmaInfo->taskInfo[1] && (qUpdateQualifiedTableId(pRSmaInfo->taskInfo[1], tbUids, true) != 0)) {
|
||||
if (pRSmaInfo->items[1].taskInfo && (qUpdateQualifiedTableId(pRSmaInfo->items[1].taskInfo, tbUids, true) < 0)) {
|
||||
smaError("vgId:%d, update tbUidList failed for uid:%" PRIi64 " since %s", SMA_VID(pSma), *suid, terrstr(terrno));
|
||||
return TSDB_CODE_FAILED;
|
||||
} else {
|
||||
smaDebug("vgId:%d, update tbUidList succeed for qTaskInfo:%p with suid:%" PRIi64 ", uid:%" PRIi64, SMA_VID(pSma),
|
||||
pRSmaInfo->taskInfo[1], *suid, *(int64_t *)taosArrayGet(tbUids, 0));
|
||||
pRSmaInfo->items[1].taskInfo, *suid, *(int64_t *)taosArrayGet(tbUids, 0));
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -144,12 +200,12 @@ int32_t tdFetchTbUidList(SSma *pSma, STbUidStore **ppStore, tb_uid_t suid, tb_ui
|
|||
ASSERT(ppStore != NULL);
|
||||
|
||||
if (!(*ppStore)) {
|
||||
if (tdUidStoreInit(ppStore) != 0) {
|
||||
if (tdUidStoreInit(ppStore) < 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (tdUidStorePut(*ppStore, suid, &uid) != 0) {
|
||||
if (tdUidStorePut(*ppStore, suid, &uid) < 0) {
|
||||
*ppStore = tdUidStoreFree(*ppStore);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
@ -172,11 +228,11 @@ int32_t tdProcessRSmaCreate(SVnode *pVnode, SVCreateStbReq *pReq) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SMeta *pMeta = pVnode->pMeta;
|
||||
SMsgCb *pMsgCb = &pVnode->msgCb;
|
||||
SMeta *pMeta = pVnode->pMeta;
|
||||
SMsgCb *pMsgCb = &pVnode->msgCb;
|
||||
SRSmaParam *param = &pReq->pRSmaParam;
|
||||
|
||||
if ((param->qmsg1Len == 0) && (param->qmsg2Len == 0)) {
|
||||
if ((param->qmsgLen[0] == 0) && (param->qmsgLen[1] == 0)) {
|
||||
smaWarn("vgId:%d, no qmsg1/qmsg2 for rollup stable %s %" PRIi64, SMA_VID(pSma), pReq->name, pReq->suid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -192,10 +248,12 @@ int32_t tdProcessRSmaCreate(SVnode *pVnode, SVCreateStbReq *pReq) {
|
|||
|
||||
pRSmaInfo = taosHashGet(SMA_STAT_INFO_HASH(pStat), &pReq->suid, sizeof(tb_uid_t));
|
||||
if (pRSmaInfo) {
|
||||
ASSERT(0); // TODO: free original pRSmaInfo is exists abnormally
|
||||
smaWarn("vgId:%d, rsma info already exists for stb: %s, %" PRIi64, SMA_VID(pSma), pReq->name, pReq->suid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// from write queue: single thead
|
||||
pRSmaInfo = (SRSmaInfo *)taosMemoryCalloc(1, sizeof(SRSmaInfo));
|
||||
if (!pRSmaInfo) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -204,9 +262,8 @@ int32_t tdProcessRSmaCreate(SVnode *pVnode, SVCreateStbReq *pReq) {
|
|||
|
||||
STqReadHandle *pReadHandle = tqInitSubmitMsgScanner(pMeta);
|
||||
if (!pReadHandle) {
|
||||
taosMemoryFree(pRSmaInfo);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_FAILED;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
SReadHandle handle = {
|
||||
|
@ -216,32 +273,33 @@ int32_t tdProcessRSmaCreate(SVnode *pVnode, SVCreateStbReq *pReq) {
|
|||
.vnode = pVnode,
|
||||
};
|
||||
|
||||
if (param->qmsg1) {
|
||||
pRSmaInfo->taskInfo[0] = qCreateStreamExecTaskInfo(param->qmsg1, &handle);
|
||||
if (!pRSmaInfo->taskInfo[0]) {
|
||||
taosMemoryFree(pRSmaInfo);
|
||||
taosMemoryFree(pReadHandle);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
STSchema *pTSchema = metaGetTbTSchema(SMA_META(pSma), pReq->suid, -1);
|
||||
if (!pTSchema) {
|
||||
terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION;
|
||||
goto _err;
|
||||
}
|
||||
pRSmaInfo->pTSchema = pTSchema;
|
||||
pRSmaInfo->pSma = pSma;
|
||||
pRSmaInfo->suid = pReq->suid;
|
||||
|
||||
if (param->qmsg2) {
|
||||
pRSmaInfo->taskInfo[1] = qCreateStreamExecTaskInfo(param->qmsg2, &handle);
|
||||
if (!pRSmaInfo->taskInfo[1]) {
|
||||
taosMemoryFree(pRSmaInfo);
|
||||
taosMemoryFree(pReadHandle);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
SRetention *pRetention = SMA_RETENTION(pSma);
|
||||
STsdbCfg *pTsdbCfg = SMA_TSDB_CFG(pSma);
|
||||
|
||||
SET_RSMA_INFO_ITEM_PARAMS(0, 1);
|
||||
SET_RSMA_INFO_ITEM_PARAMS(1, 2);
|
||||
|
||||
if (taosHashPut(SMA_STAT_INFO_HASH(pStat), &pReq->suid, sizeof(tb_uid_t), &pRSmaInfo, sizeof(pRSmaInfo)) !=
|
||||
TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_FAILED;
|
||||
goto _err;
|
||||
} else {
|
||||
smaDebug("vgId:%d, register rsma info succeed for suid:%" PRIi64, SMA_VID(pSma), pReq->suid);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
_err:
|
||||
tdFreeRSmaInfo(pRSmaInfo);
|
||||
taosMemoryFree(pReadHandle);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -291,12 +349,12 @@ static int32_t tdUidStorePut(STbUidStore *pStore, tb_uid_t suid, tb_uid_t *uid)
|
|||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
if (taosHashPut(pStore->uidHash, &suid, sizeof(suid), &pUidArray, sizeof(pUidArray)) != 0) {
|
||||
if (taosHashPut(pStore->uidHash, &suid, sizeof(suid), &pUidArray, sizeof(pUidArray)) < 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (taosHashPut(pStore->uidHash, &suid, sizeof(suid), NULL, 0) != 0) {
|
||||
if (taosHashPut(pStore->uidHash, &suid, sizeof(suid), NULL, 0) < 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
@ -367,22 +425,15 @@ static int32_t tdFetchSubmitReqSuids(SSubmitReq *pMsg, STbUidStore *pStore) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t inputType, qTaskInfo_t *taskInfo,
|
||||
STSchema *pTSchema, tb_uid_t suid, int8_t level) {
|
||||
SArray *pResult = NULL;
|
||||
static int32_t tdFetchAndSubmitRSmaResult(SRSmaInfoItem *pItem, int8_t blkType) {
|
||||
SArray *pResult = NULL;
|
||||
SRSmaInfo *pRSmaInfo = pItem->pRsmaInfo;
|
||||
SSma *pSma = pRSmaInfo->pSma;
|
||||
|
||||
if (!taskInfo) {
|
||||
smaDebug("vgId:%d, no qTaskInfo to execute rsma %" PRIi8 " task for suid:%" PRIu64, SMA_VID(pSma), level, suid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
smaDebug("vgId:%d, execute rsma %" PRIi8 " task for qTaskInfo:%p suid:%" PRIu64, SMA_VID(pSma), level, taskInfo, suid);
|
||||
|
||||
qSetStreamInput(taskInfo, pMsg, inputType, true);
|
||||
while (1) {
|
||||
SSDataBlock *output = NULL;
|
||||
uint64_t ts;
|
||||
if (qExecTask(taskInfo, &output, &ts) < 0) {
|
||||
if (qExecTask(pItem->taskInfo, &output, &ts) < 0) {
|
||||
ASSERT(false);
|
||||
}
|
||||
if (!output) {
|
||||
|
@ -402,16 +453,16 @@ static FORCE_INLINE int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int3
|
|||
if (taosArrayGetSize(pResult) > 0) {
|
||||
#if 0
|
||||
char flag[10] = {0};
|
||||
snprintf(flag, 10, "level %" PRIi8, level);
|
||||
snprintf(flag, 10, "level %" PRIi8, pItem->level);
|
||||
blockDebugShowData(pResult, flag);
|
||||
#endif
|
||||
STsdb *sinkTsdb = (level == TSDB_RETENTION_L1 ? pSma->pRSmaTsdb1 : pSma->pRSmaTsdb2);
|
||||
STsdb *sinkTsdb = (pItem->level == TSDB_RETENTION_L1 ? pSma->pRSmaTsdb1 : pSma->pRSmaTsdb2);
|
||||
SSubmitReq *pReq = NULL;
|
||||
if (buildSubmitReqFromDataBlock(&pReq, pResult, pTSchema, SMA_VID(pSma), suid) < 0) {
|
||||
if (buildSubmitReqFromDataBlock(&pReq, pResult, pRSmaInfo->pTSchema, SMA_VID(pSma), pRSmaInfo->suid) < 0) {
|
||||
taosArrayDestroy(pResult);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
|
||||
if (pReq && tdProcessSubmitReq(sinkTsdb, INT64_MAX, pReq) < 0) {
|
||||
taosArrayDestroy(pResult);
|
||||
taosMemoryFreeClear(pReq);
|
||||
|
@ -420,10 +471,63 @@ static FORCE_INLINE int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int3
|
|||
|
||||
taosMemoryFreeClear(pReq);
|
||||
} else {
|
||||
smaDebug("vgId:%d, no rsma % " PRIi8 " data generated since %s", SMA_VID(pSma), level, tstrerror(terrno));
|
||||
smaDebug("vgId:%d, no rsma % " PRIi8 " data generated since %s", SMA_VID(pSma), pItem->level, tstrerror(terrno));
|
||||
}
|
||||
|
||||
if (blkType == STREAM_DATA_TYPE_SUBMIT_BLOCK) {
|
||||
atomic_store_8(&pItem->triggerStatus, TASK_TRIGGER_STATUS__ACTIVE);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pResult);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief trigger to get rsma result
|
||||
*
|
||||
* @param param
|
||||
* @param tmrId
|
||||
*/
|
||||
static void rsmaTriggerByTimer(void *param, void *tmrId) {
|
||||
// SRSmaTriggerParam *pParam = (SRSmaTriggerParam *)param;
|
||||
// SRSmaInfoItem *pItem = pParam->pItem;
|
||||
SRSmaInfoItem *pItem = param;
|
||||
|
||||
if (atomic_load_8(&pItem->triggerStatus) == TASK_TRIGGER_STATUS__ACTIVE) {
|
||||
smaTrace("level %" PRIi8 " status is active for tb suid:%" PRIi64, pItem->level, pItem->pRsmaInfo->suid);
|
||||
SSDataBlock dataBlock = {.info.type = STREAM_GET_ALL};
|
||||
|
||||
atomic_store_8(&pItem->triggerStatus, TASK_TRIGGER_STATUS__IN_ACTIVE);
|
||||
qSetStreamInput(pItem->taskInfo, &dataBlock, STREAM_DATA_TYPE_SSDATA_BLOCK, false);
|
||||
|
||||
tdFetchAndSubmitRSmaResult(pItem, STREAM_DATA_TYPE_SSDATA_BLOCK);
|
||||
} else {
|
||||
smaTrace("level %" PRIi8 " status is inactive for tb suid:%" PRIi64, pItem->level, pItem->pRsmaInfo->suid);
|
||||
}
|
||||
|
||||
// taosTmrReset(rsmaTriggerByTimer, pItem->maxDelay, pItem, pItem->tmrHandle, &pItem->tmrId);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t inputType, SRSmaInfoItem *pItem,
|
||||
tb_uid_t suid, int8_t level) {
|
||||
if (!pItem || !pItem->taskInfo) {
|
||||
smaDebug("vgId:%d, no qTaskInfo to execute rsma %" PRIi8 " task for suid:%" PRIu64, SMA_VID(pSma), level, suid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
smaDebug("vgId:%d, execute rsma %" PRIi8 " task for qTaskInfo:%p suid:%" PRIu64, SMA_VID(pSma), level,
|
||||
pItem->taskInfo, suid);
|
||||
|
||||
// inputType = STREAM_DATA_TYPE_SUBMIT_BLOCK(1)
|
||||
if (qSetStreamInput(pItem->taskInfo, pMsg, inputType, true) < 0) {
|
||||
smaError("vgId:%d, rsma % " PRIi8 " qSetStreamInput failed since %s", SMA_VID(pSma), level, tstrerror(terrno));
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
// SRSmaTriggerParam triggerParam = {.suid = suid, .pItem = pItem, .pSma = pSma, .pTSchema = pTSchema};
|
||||
tdFetchAndSubmitRSmaResult(pItem, STREAM_DATA_TYPE_SUBMIT_BLOCK);
|
||||
atomic_store_8(&pItem->triggerStatus, TASK_TRIGGER_STATUS__ACTIVE);
|
||||
taosTmrReset(rsmaTriggerByTimer, pItem->maxDelay, pItem, pItem->tmrHandle, &pItem->tmrId);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -441,24 +545,18 @@ static int32_t tdExecuteRSma(SSma *pSma, const void *pMsg, int32_t inputType, tb
|
|||
pRSmaInfo = taosHashGet(SMA_STAT_INFO_HASH(pStat), &suid, sizeof(tb_uid_t));
|
||||
|
||||
if (!pRSmaInfo || !(pRSmaInfo = *(SRSmaInfo **)pRSmaInfo)) {
|
||||
smaDebug("vgId:%d, no rsma info for suid:%" PRIu64, SMA_VID(pSma), suid);
|
||||
smaDebug("vgId:%d, return as no rsma info for suid:%" PRIu64, SMA_VID(pSma), suid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
if (!pRSmaInfo->taskInfo[0]) {
|
||||
smaDebug("vgId:%d, no rsma qTaskInfo for suid:%" PRIu64, SMA_VID(pSma), suid);
|
||||
|
||||
if (!pRSmaInfo->items[0].taskInfo) {
|
||||
smaDebug("vgId:%d, return as no rsma qTaskInfo for suid:%" PRIu64, SMA_VID(pSma), suid);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (inputType == STREAM_DATA_TYPE_SUBMIT_BLOCK) {
|
||||
// TODO: cache STSchema
|
||||
STSchema *pTSchema = metaGetTbTSchema(SMA_META(pSma), suid, -1);
|
||||
if (!pTSchema) {
|
||||
terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
tdExecuteRSmaImpl(pSma, pMsg, inputType, pRSmaInfo->taskInfo[0], pTSchema, suid, TSDB_RETENTION_L1);
|
||||
tdExecuteRSmaImpl(pSma, pMsg, inputType, pRSmaInfo->taskInfo[1], pTSchema, suid, TSDB_RETENTION_L2);
|
||||
taosMemoryFree(pTSchema);
|
||||
tdExecuteRSmaImpl(pSma, pMsg, inputType, &pRSmaInfo->items[0], suid, TSDB_RETENTION_L1);
|
||||
tdExecuteRSmaImpl(pSma, pMsg, inputType, &pRSmaInfo->items[1], suid, TSDB_RETENTION_L2);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -125,10 +125,10 @@ int32_t tqProcessOffsetCommitReq(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
|
||||
if (offset.type == TMQ_OFFSET__SNAPSHOT) {
|
||||
tqDebug("receive offset commit msg to %s on vg %d, offset(type:snapshot) uid: %ld, ts: %ld", offset.subKey,
|
||||
pTq->pVnode->config.vgId, offset.uid, offset.ts);
|
||||
TD_VID(pTq->pVnode), offset.uid, offset.ts);
|
||||
} else if (offset.type == TMQ_OFFSET__LOG) {
|
||||
tqDebug("receive offset commit msg to %s on vg %d, offset(type:log) version: %ld", offset.subKey,
|
||||
pTq->pVnode->config.vgId, offset.version);
|
||||
TD_VID(pTq->pVnode), offset.version);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
if (pOffset != NULL) {
|
||||
ASSERT(pOffset->type == TMQ_OFFSET__LOG);
|
||||
tqDebug("consumer %ld, restore offset of %s on vg %d, offset(type:log) version: %ld", consumerId, pReq->subKey,
|
||||
pTq->pVnode->config.vgId, pOffset->version);
|
||||
TD_VID(pTq->pVnode), pOffset->version);
|
||||
fetchOffset = pOffset->version + 1;
|
||||
} else {
|
||||
if (pReq->currentOffset == TMQ_CONF__RESET_OFFSET__EARLIEAST) {
|
||||
|
@ -167,13 +167,13 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
} else if (pReq->currentOffset == TMQ_CONF__RESET_OFFSET__LATEST) {
|
||||
fetchOffset = walGetCommittedVer(pTq->pWal);
|
||||
} else if (pReq->currentOffset == TMQ_CONF__RESET_OFFSET__NONE) {
|
||||
tqError("tmq poll: no offset committed for consumer %ld in vg %d, subkey %s", consumerId,
|
||||
pTq->pVnode->config.vgId, pReq->subKey);
|
||||
tqError("tmq poll: no offset committed for consumer %ld in vg %d, subkey %s", consumerId, TD_VID(pTq->pVnode),
|
||||
pReq->subKey);
|
||||
terrno = TSDB_CODE_TQ_NO_COMMITTED_OFFSET;
|
||||
return -1;
|
||||
}
|
||||
tqDebug("consumer %ld, restore offset of %s on vg %d failed, config is %ld, set to %ld", consumerId, pReq->subKey,
|
||||
pTq->pVnode->config.vgId, pReq->currentOffset, fetchOffset);
|
||||
TD_VID(pTq->pVnode), pReq->currentOffset, fetchOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,14 +183,14 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
STqHandle* pHandle = taosHashGet(pTq->handles, pReq->subKey, strlen(pReq->subKey));
|
||||
/*ASSERT(pHandle);*/
|
||||
if (pHandle == NULL) {
|
||||
tqError("tmq poll: no consumer handle for consumer %ld in vg %d, subkey %s", consumerId, pTq->pVnode->config.vgId,
|
||||
tqError("tmq poll: no consumer handle for consumer %ld in vg %d, subkey %s", consumerId, TD_VID(pTq->pVnode),
|
||||
pReq->subKey);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pHandle->consumerId != consumerId) {
|
||||
tqError("tmq poll: consumer handle mismatch for consumer %ld in vg %d, subkey %s, handle consumer id %ld",
|
||||
consumerId, pTq->pVnode->config.vgId, pReq->subKey, pHandle->consumerId);
|
||||
consumerId, TD_VID(pTq->pVnode), pReq->subKey, pHandle->consumerId);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -304,7 +304,6 @@ int32_t tqProcessVgDeleteReq(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// TODO: persist meta into tdb
|
||||
int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen) {
|
||||
SMqRebVgReq req = {0};
|
||||
tDecodeSMqRebVgReq(msg, &req);
|
||||
|
@ -346,10 +345,10 @@ int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
pHandle->execHandle.execTb.suid = req.suid;
|
||||
SArray* tbUidList = taosArrayInit(0, sizeof(int64_t));
|
||||
tsdbGetCtbIdList(pTq->pVnode->pMeta, req.suid, tbUidList);
|
||||
tqDebug("vg %d, tq try get suid: %ld", pTq->pVnode->config.vgId, req.suid);
|
||||
tqDebug("vg %d, tq try get suid: %ld", TD_VID(pTq->pVnode), req.suid);
|
||||
for (int32_t i = 0; i < taosArrayGetSize(tbUidList); i++) {
|
||||
int64_t tbUid = *(int64_t*)taosArrayGet(tbUidList, i);
|
||||
tqDebug("vg %d, idx %d, uid: %ld", pTq->pVnode->config.vgId, i, tbUid);
|
||||
tqDebug("vg %d, idx %d, uid: %ld", TD_VID(pTq->pVnode), i, tbUid);
|
||||
}
|
||||
for (int32_t i = 0; i < 5; i++) {
|
||||
tqReadHandleSetTbUidList(pHandle->execHandle.pExecReader[i], tbUidList);
|
||||
|
@ -400,16 +399,21 @@ int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
// exec
|
||||
if (pTask->execType != TASK_EXEC__NONE) {
|
||||
// expand runners
|
||||
STqReadHandle* pStreamReader = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
|
||||
SReadHandle handle = {
|
||||
.reader = pStreamReader,
|
||||
.meta = pTq->pVnode->pMeta,
|
||||
.pMsgCb = &pTq->pVnode->msgCb,
|
||||
.vnode = pTq->pVnode,
|
||||
};
|
||||
pTask->exec.inputHandle = pStreamReader;
|
||||
pTask->exec.executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle);
|
||||
ASSERT(pTask->exec.executor);
|
||||
if (pTask->dataScan) {
|
||||
STqReadHandle* pStreamReader = tqInitSubmitMsgScanner(pTq->pVnode->pMeta);
|
||||
SReadHandle handle = {
|
||||
.reader = pStreamReader,
|
||||
.meta = pTq->pVnode->pMeta,
|
||||
.pMsgCb = &pTq->pVnode->msgCb,
|
||||
.vnode = pTq->pVnode,
|
||||
};
|
||||
/*pTask->exec.inputHandle = pStreamReader;*/
|
||||
pTask->exec.executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle);
|
||||
ASSERT(pTask->exec.executor);
|
||||
} else {
|
||||
pTask->exec.executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, NULL);
|
||||
ASSERT(pTask->exec.executor);
|
||||
}
|
||||
}
|
||||
|
||||
// sink
|
||||
|
@ -431,7 +435,7 @@ int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
|
||||
streamSetupTrigger(pTask);
|
||||
|
||||
tqInfo("deploy stream task id %d child id %d on vg %d", pTask->taskId, pTask->childId, pTq->pVnode->config.vgId);
|
||||
tqInfo("deploy stream task id %d child id %d on vg %d", pTask->taskId, pTask->childId, TD_VID(pTq->pVnode));
|
||||
|
||||
taosHashPut(pTq->pStreamTasks, &pTask->taskId, sizeof(int32_t), &pTask, sizeof(void*));
|
||||
|
||||
|
@ -464,7 +468,7 @@ int32_t tqProcessStreamTrigger(STQ* pTq, SSubmitReq* pReq) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (streamLaunchByWrite(pTask, pTq->pVnode->config.vgId, &pTq->pVnode->msgCb) < 0) {
|
||||
if (streamLaunchByWrite(pTask, TD_VID(pTq->pVnode), &pTq->pVnode->msgCb) < 0) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
|
@ -534,9 +538,9 @@ int32_t tqProcessTaskRecoverRsp(STQ* pTq, SRpcMsg* pMsg) {
|
|||
int32_t tqProcessTaskDropReq(STQ* pTq, char* msg, int32_t msgLen) {
|
||||
SVDropStreamTaskReq* pReq = (SVDropStreamTaskReq*)msg;
|
||||
int32_t code = taosHashRemove(pTq->pStreamTasks, &pReq->taskId, sizeof(int32_t));
|
||||
ASSERT(code == 0);
|
||||
if (code == 0) {
|
||||
// sendrsp
|
||||
}
|
||||
ASSERT(code == 0);
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -500,7 +500,7 @@ static int32_t setCurrentSchema(SVnode* pVnode, STsdbReadHandle* pTsdbReadHandle
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tsdbReaderT* tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, STableListInfo* tableList, uint64_t qId,
|
||||
tsdbReaderT tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, STableListInfo* tableList, uint64_t qId,
|
||||
uint64_t taskId) {
|
||||
STsdbReadHandle* pTsdbReadHandle = tsdbQueryTablesImpl(pVnode, pCond, qId, taskId);
|
||||
if (pTsdbReadHandle == NULL) {
|
||||
|
@ -508,7 +508,7 @@ tsdbReaderT* tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, STableLi
|
|||
}
|
||||
|
||||
if (emptyQueryTimewindow(pTsdbReadHandle)) {
|
||||
return (tsdbReaderT*)pTsdbReadHandle;
|
||||
return (tsdbReaderT)pTsdbReadHandle;
|
||||
}
|
||||
|
||||
// todo apply the lastkey of table check to avoid to load header file
|
||||
|
|
|
@ -106,7 +106,7 @@ int32_t vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp
|
|||
int32_t len;
|
||||
int32_t ret;
|
||||
|
||||
vError("vgId:%d, start to process write request %s, index:%" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType),
|
||||
vTrace("vgId:%d, start to process write request %s, index:%" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType),
|
||||
version);
|
||||
|
||||
pVnode->state.applied = version;
|
||||
|
@ -346,7 +346,10 @@ static int32_t vnodeProcessCreateStbReq(SVnode *pVnode, int64_t version, void *p
|
|||
goto _err;
|
||||
}
|
||||
|
||||
tdProcessRSmaCreate(pVnode, &req);
|
||||
if (tdProcessRSmaCreate(pVnode, &req) < 0) {
|
||||
pRsp->code = terrno;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
tDecoderClear(&coder);
|
||||
return 0;
|
||||
|
|
|
@ -412,6 +412,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
}
|
||||
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
|
||||
|
@ -426,27 +427,57 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
EXPLAIN_ROW_NEW(level + 1, "I/O: ");
|
||||
|
||||
int32_t nodeNum = taosArrayGetSize(pResNode->pExecInfo);
|
||||
for (int32_t i = 0; i < nodeNum; ++i) {
|
||||
struct STableScanAnalyzeInfo info = {0};
|
||||
|
||||
int32_t maxIndex = 0;
|
||||
int32_t totalRows = 0;
|
||||
for(int32_t i = 0; i < nodeNum; ++i) {
|
||||
SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, i);
|
||||
STableScanAnalyzeInfo *pScanInfo = (STableScanAnalyzeInfo *)execInfo->verboseInfo;
|
||||
|
||||
EXPLAIN_ROW_APPEND("total_blocks=%d", pScanInfo->totalBlocks);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
info.totalBlocks += pScanInfo->totalBlocks;
|
||||
info.loadBlocks += pScanInfo->loadBlocks;
|
||||
info.totalRows += pScanInfo->totalRows;
|
||||
info.skipBlocks += pScanInfo->skipBlocks;
|
||||
info.filterTime += pScanInfo->filterTime;
|
||||
info.loadBlockStatis += pScanInfo->loadBlockStatis;
|
||||
info.totalCheckedRows += pScanInfo->totalCheckedRows;
|
||||
info.filterOutBlocks += pScanInfo->filterOutBlocks;
|
||||
|
||||
EXPLAIN_ROW_APPEND("load_blocks=%d", pScanInfo->loadBlocks);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
|
||||
EXPLAIN_ROW_APPEND("load_block_SMAs=%d", pScanInfo->loadBlockStatis);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
|
||||
EXPLAIN_ROW_APPEND("total_rows=%" PRIu64, pScanInfo->totalRows);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
|
||||
EXPLAIN_ROW_APPEND("check_rows=%" PRIu64, pScanInfo->totalCheckedRows);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
if (pScanInfo->totalRows > totalRows) {
|
||||
totalRows = pScanInfo->totalRows;
|
||||
maxIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
EXPLAIN_ROW_APPEND("total_blocks=%.1f", ((double)info.totalBlocks) / nodeNum);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
|
||||
EXPLAIN_ROW_APPEND("load_blocks=%.1f", ((double)info.loadBlocks) / nodeNum);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
|
||||
EXPLAIN_ROW_APPEND("load_block_SMAs=%.1f", ((double)info.loadBlockStatis) / nodeNum);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
|
||||
EXPLAIN_ROW_APPEND("total_rows=%.1f", ((double)info.totalRows) / nodeNum);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
|
||||
EXPLAIN_ROW_APPEND("check_rows=%.1f", ((double)info.totalCheckedRows) / nodeNum);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
||||
//Rows out: Avg 4166.7 rows x 24 workers. Max 4187 rows (seg7) with 0.220 ms to first row, 1.738 ms to end, start offset by 1.470 ms.
|
||||
SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, maxIndex);
|
||||
STableScanAnalyzeInfo *p1 = (STableScanAnalyzeInfo *)execInfo->verboseInfo;
|
||||
|
||||
EXPLAIN_ROW_NEW(level + 1, " ");
|
||||
EXPLAIN_ROW_APPEND("max_row_task=%d, total_rows:%" PRId64 ", ep:%s (cost=%.3f..%.3f)", maxIndex, p1->totalRows, "tbd",
|
||||
execInfo->startupCost, execInfo->totalCost);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNod
|
|||
SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs);
|
||||
|
||||
SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput, int32_t** rowEntryInfoOffset);
|
||||
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols);
|
||||
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols, bool outputEveryColumn);
|
||||
void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow);
|
||||
|
||||
SInterval extractIntervalInfo(const STableScanPhysiNode* pTableScanNode);
|
||||
|
|
|
@ -369,6 +369,8 @@ typedef struct SSysTableScanInfo {
|
|||
typedef struct SBlockDistInfo {
|
||||
SSDataBlock* pResBlock;
|
||||
void* pHandle;
|
||||
SReadHandle readHandle;
|
||||
uint64_t uid; // table uid
|
||||
} SBlockDistInfo;
|
||||
|
||||
// todo remove this
|
||||
|
@ -740,7 +742,8 @@ SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo
|
|||
SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResultBlock, SArray* pGroupColList, SNode* pCondition,
|
||||
SExprInfo* pScalarExprInfo, int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SReadHandle* readHandle, uint64_t uid, SBlockDistScanPhysiNode* pBlockScanNode,
|
||||
SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHandle,
|
||||
STableScanPhysiNode* pTableScanNode, SExecTaskInfo* pTaskInfo, STimeWindowAggSupp* pTwSup);
|
||||
|
|
|
@ -75,12 +75,18 @@ static bool needCompress(const SSDataBlock* pData, int32_t numOfCols) {
|
|||
// The length of bitmap is decided by number of rows of this data block, and the length of each column data is
|
||||
// recorded in the first segment, next to the struct header
|
||||
static void toDataCacheEntry(SDataDispatchHandle* pHandle, const SInputData* pInput, SDataDispatchBuf* pBuf) {
|
||||
int32_t numOfCols = LIST_LENGTH(pHandle->pSchema->pSlots);
|
||||
|
||||
int32_t numOfCols = 0;
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pHandle->pSchema->pSlots) {
|
||||
SSlotDescNode* pSlotDesc = (SSlotDescNode*)pNode;
|
||||
if (pSlotDesc->output) {
|
||||
++numOfCols;
|
||||
}
|
||||
}
|
||||
SDataCacheEntry* pEntry = (SDataCacheEntry*)pBuf->pData;
|
||||
pEntry->compressed = (int8_t)needCompress(pInput->pData, numOfCols);
|
||||
pEntry->numOfRows = pInput->pData->info.rows;
|
||||
pEntry->numOfCols = pInput->pData->info.numOfCols;
|
||||
pEntry->numOfCols = numOfCols;
|
||||
pEntry->dataLen = 0;
|
||||
|
||||
pBuf->useSize = sizeof(SDataCacheEntry);
|
||||
|
|
|
@ -193,9 +193,9 @@ SSDataBlock* createResDataBlock(SDataBlockDescNode* pNode) {
|
|||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData idata = {{0}};
|
||||
SSlotDescNode* pDescNode = (SSlotDescNode*)nodesListGetNode(pNode->pSlots, i);
|
||||
// if (!pDescNode->output) { // todo disable it temporarily
|
||||
// continue;
|
||||
// }
|
||||
// if (!pDescNode->output) { // todo disable it temporarily
|
||||
// continue;
|
||||
// }
|
||||
|
||||
idata.info.type = pDescNode->dataType.type;
|
||||
idata.info.bytes = pDescNode->dataType.bytes;
|
||||
|
@ -235,7 +235,7 @@ int32_t getTableList(void* metaHandle, SScanPhysiNode* pScanNode, STableListInfo
|
|||
terrno = code;
|
||||
return code;
|
||||
} else {
|
||||
qDebug("sucess to get tableIds, size: %d, suid: %" PRIu64 "", (int)taosArrayGetSize(res), tableUid);
|
||||
qDebug("success to get tableIds, size: %d, suid: %" PRIu64 "", (int)taosArrayGetSize(res), tableUid);
|
||||
}
|
||||
|
||||
for (int i = 0; i < taosArrayGetSize(res); i++) {
|
||||
|
@ -319,7 +319,14 @@ SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNod
|
|||
continue;
|
||||
}
|
||||
|
||||
SColMatchInfo* info = taosArrayGet(pList, pNode->slotId);
|
||||
SColMatchInfo* info = NULL;
|
||||
for (int32_t j = 0; j < taosArrayGetSize(pList); ++j) {
|
||||
info = taosArrayGet(pList, j);
|
||||
if (info->targetSlotId == pNode->slotId) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pNode->output) {
|
||||
(*numOfOutputCols) += 1;
|
||||
} else {
|
||||
|
@ -578,14 +585,15 @@ SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput,
|
|||
}
|
||||
|
||||
// NOTE: sources columns are more than the destination SSDatablock columns.
|
||||
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols) {
|
||||
// doFilter in table scan needs every column even its output is false
|
||||
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols, bool outputEveryColumn) {
|
||||
size_t numOfSrcCols = taosArrayGetSize(pCols);
|
||||
|
||||
int32_t i = 0, j = 0;
|
||||
while (i < numOfSrcCols && j < taosArrayGetSize(pColMatchInfo)) {
|
||||
SColumnInfoData* p = taosArrayGet(pCols, i);
|
||||
SColMatchInfo* pmInfo = taosArrayGet(pColMatchInfo, j);
|
||||
if (!pmInfo->output) {
|
||||
if (!outputEveryColumn && !pmInfo->output) {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -41,12 +41,18 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu
|
|||
pInfo->assignBlockUid = assignUid;
|
||||
|
||||
// the block type can not be changed in the streamscan operators
|
||||
#if 0
|
||||
if (pInfo->blockType == 0) {
|
||||
pInfo->blockType = type;
|
||||
} else if (pInfo->blockType != type) {
|
||||
ASSERT(0);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
#endif
|
||||
// rollup sma, the same qTaskInfo is used to insert data by SubmitReq and fetch result by SSDataBlock
|
||||
if (pInfo->blockType != type) {
|
||||
pInfo->blockType = type;
|
||||
}
|
||||
|
||||
if (type == STREAM_DATA_TYPE_SUBMIT_BLOCK) {
|
||||
if (tqReadHandleSetMsg(pInfo->streamBlockReader, input, 0) < 0) {
|
||||
|
@ -99,7 +105,7 @@ int32_t qSetMultiStreamInput(qTaskInfo_t tinfo, const void* pBlocks, size_t numO
|
|||
}
|
||||
|
||||
qTaskInfo_t qCreateStreamExecTaskInfo(void* msg, void* streamReadHandle) {
|
||||
if (msg == NULL || streamReadHandle == NULL) {
|
||||
if (msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "tref.h"
|
||||
#include "dataSinkMgt.h"
|
||||
#include "os.h"
|
||||
#include "tmsg.h"
|
||||
#include "tref.h"
|
||||
#include "tudf.h"
|
||||
|
||||
#include "executor.h"
|
||||
|
@ -24,15 +24,13 @@
|
|||
#include "query.h"
|
||||
|
||||
static TdThreadOnce initPoolOnce = PTHREAD_ONCE_INIT;
|
||||
int32_t exchangeObjRefPool = -1;
|
||||
int32_t exchangeObjRefPool = -1;
|
||||
|
||||
static void initRefPool() {
|
||||
exchangeObjRefPool = taosOpenRef(1024, doDestroyExchangeOperatorInfo);
|
||||
}
|
||||
static void initRefPool() { exchangeObjRefPool = taosOpenRef(1024, doDestroyExchangeOperatorInfo); }
|
||||
|
||||
int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId, SSubplan* pSubplan,
|
||||
qTaskInfo_t* pTaskInfo, DataSinkHandle* handle, const char* sql, EOPTR_EXEC_MODEL model) {
|
||||
assert(readHandle != NULL && pSubplan != NULL);
|
||||
assert(pSubplan != NULL);
|
||||
SExecTaskInfo** pTask = (SExecTaskInfo**)pTaskInfo;
|
||||
|
||||
taosThreadOnce(&initPoolOnce, initRefPool);
|
||||
|
@ -47,57 +45,57 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId,
|
|||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
|
||||
if (handle) {
|
||||
void* pSinkParam = NULL;
|
||||
code = createDataSinkParam(pSubplan->pDataSink, &pSinkParam, pTaskInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
|
||||
code = dsCreateDataSinker(pSubplan->pDataSink, handle, pSinkParam);
|
||||
}
|
||||
|
||||
_error:
|
||||
_error:
|
||||
// if failed to add ref for all tables in this query, abort current query
|
||||
return code;
|
||||
}
|
||||
|
||||
#ifdef TEST_IMPL
|
||||
// wait moment
|
||||
int waitMoment(SQInfo* pQInfo){
|
||||
if(pQInfo->sql) {
|
||||
int ms = 0;
|
||||
int waitMoment(SQInfo* pQInfo) {
|
||||
if (pQInfo->sql) {
|
||||
int ms = 0;
|
||||
char* pcnt = strstr(pQInfo->sql, " count(*)");
|
||||
if(pcnt) return 0;
|
||||
|
||||
if (pcnt) return 0;
|
||||
|
||||
char* pos = strstr(pQInfo->sql, " t_");
|
||||
if(pos){
|
||||
if (pos) {
|
||||
pos += 3;
|
||||
ms = atoi(pos);
|
||||
while(*pos >= '0' && *pos <= '9'){
|
||||
pos ++;
|
||||
while (*pos >= '0' && *pos <= '9') {
|
||||
pos++;
|
||||
}
|
||||
char unit_char = *pos;
|
||||
if(unit_char == 'h'){
|
||||
ms *= 3600*1000;
|
||||
} else if(unit_char == 'm'){
|
||||
ms *= 60*1000;
|
||||
} else if(unit_char == 's'){
|
||||
if (unit_char == 'h') {
|
||||
ms *= 3600 * 1000;
|
||||
} else if (unit_char == 'm') {
|
||||
ms *= 60 * 1000;
|
||||
} else if (unit_char == 's') {
|
||||
ms *= 1000;
|
||||
}
|
||||
}
|
||||
if(ms == 0) return 0;
|
||||
if (ms == 0) return 0;
|
||||
printf("test wait sleep %dms. sql=%s ...\n", ms, pQInfo->sql);
|
||||
|
||||
if(ms < 1000) {
|
||||
|
||||
if (ms < 1000) {
|
||||
taosMsleep(ms);
|
||||
} else {
|
||||
int used_ms = 0;
|
||||
while(used_ms < ms) {
|
||||
while (used_ms < ms) {
|
||||
taosMsleep(1000);
|
||||
used_ms += 1000;
|
||||
if(isTaskKilled(pQInfo)){
|
||||
if (isTaskKilled(pQInfo)) {
|
||||
printf("test check query is canceled, sleep break.%s\n", pQInfo->sql);
|
||||
break;
|
||||
}
|
||||
|
@ -108,15 +106,14 @@ int waitMoment(SQInfo* pQInfo){
|
|||
}
|
||||
#endif
|
||||
|
||||
int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pRes, uint64_t *useconds) {
|
||||
int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pRes, uint64_t* useconds) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
int64_t threadId = taosGetSelfPthreadId();
|
||||
|
||||
*pRes = NULL;
|
||||
int64_t curOwner = 0;
|
||||
if ((curOwner = atomic_val_compare_exchange_64(&pTaskInfo->owner, 0, threadId)) != 0) {
|
||||
qError("%s-%p execTask is now executed by thread:%p", GET_TASKID(pTaskInfo), pTaskInfo,
|
||||
(void*)curOwner);
|
||||
qError("%s-%p execTask is now executed by thread:%p", GET_TASKID(pTaskInfo), pTaskInfo, (void*)curOwner);
|
||||
pTaskInfo->code = TSDB_CODE_QRY_IN_EXEC;
|
||||
return pTaskInfo->code;
|
||||
}
|
||||
|
@ -152,18 +149,18 @@ int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pRes, uint64_t *useconds) {
|
|||
|
||||
cleanUpUdfs();
|
||||
|
||||
int32_t current = (*pRes != NULL)? (*pRes)->info.rows:0;
|
||||
int32_t current = (*pRes != NULL) ? (*pRes)->info.rows : 0;
|
||||
uint64_t total = pTaskInfo->pRoot->resultInfo.totalRows;
|
||||
|
||||
qDebug("%s task suspended, %d rows returned, total:%" PRId64 " rows, in sinkNode:%d, elapsed:%.2f ms",
|
||||
GET_TASKID(pTaskInfo), current, total, 0, el/1000.0);
|
||||
GET_TASKID(pTaskInfo), current, total, 0, el / 1000.0);
|
||||
|
||||
atomic_store_64(&pTaskInfo->owner, 0);
|
||||
return pTaskInfo->code;
|
||||
}
|
||||
|
||||
int32_t qKillTask(qTaskInfo_t qinfo) {
|
||||
SExecTaskInfo *pTaskInfo = (SExecTaskInfo *)qinfo;
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)qinfo;
|
||||
|
||||
if (pTaskInfo == NULL) {
|
||||
return TSDB_CODE_QRY_INVALID_QHANDLE;
|
||||
|
@ -182,7 +179,7 @@ int32_t qKillTask(qTaskInfo_t qinfo) {
|
|||
}
|
||||
|
||||
int32_t qAsyncKillTask(qTaskInfo_t qinfo) {
|
||||
SExecTaskInfo *pTaskInfo = (SExecTaskInfo *)qinfo;
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)qinfo;
|
||||
|
||||
if (pTaskInfo == NULL) {
|
||||
return TSDB_CODE_QRY_INVALID_QHANDLE;
|
||||
|
@ -195,7 +192,7 @@ int32_t qAsyncKillTask(qTaskInfo_t qinfo) {
|
|||
}
|
||||
|
||||
int32_t qIsTaskCompleted(qTaskInfo_t qinfo) {
|
||||
SExecTaskInfo *pTaskInfo = (SExecTaskInfo *)qinfo;
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)qinfo;
|
||||
|
||||
if (pTaskInfo == NULL) {
|
||||
return TSDB_CODE_QRY_INVALID_QHANDLE;
|
||||
|
@ -205,18 +202,18 @@ int32_t qIsTaskCompleted(qTaskInfo_t qinfo) {
|
|||
}
|
||||
|
||||
void qDestroyTask(qTaskInfo_t qTaskHandle) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*) qTaskHandle;
|
||||
qDebug("%s execTask completed, numOfRows:%"PRId64, GET_TASKID(pTaskInfo), pTaskInfo->pRoot->resultInfo.totalRows);
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)qTaskHandle;
|
||||
qDebug("%s execTask completed, numOfRows:%" PRId64, GET_TASKID(pTaskInfo), pTaskInfo->pRoot->resultInfo.totalRows);
|
||||
|
||||
queryCostStatis(pTaskInfo); // print the query cost summary
|
||||
queryCostStatis(pTaskInfo); // print the query cost summary
|
||||
doDestroyTask(pTaskInfo);
|
||||
}
|
||||
|
||||
int32_t qGetExplainExecInfo(qTaskInfo_t tinfo, int32_t *resNum, SExplainExecInfo **pRes) {
|
||||
SExecTaskInfo *pTaskInfo = (SExecTaskInfo *)tinfo;
|
||||
int32_t capacity = 0;
|
||||
int32_t qGetExplainExecInfo(qTaskInfo_t tinfo, int32_t* resNum, SExplainExecInfo** pRes) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
int32_t capacity = 0;
|
||||
|
||||
return getOperatorExplainExecInfo(pTaskInfo->pRoot, pRes, &capacity, resNum);
|
||||
return getOperatorExplainExecInfo(pTaskInfo->pRoot, pRes, &capacity, resNum);
|
||||
}
|
||||
|
||||
int32_t qSerializeTaskStatus(qTaskInfo_t tinfo, char** pOutput, int32_t* len) {
|
||||
|
|
|
@ -141,8 +141,8 @@ static int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock,
|
|||
SqlFunctionCtx* pCtx, int32_t numOfExprs);
|
||||
|
||||
static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size);
|
||||
static void doSetTableGroupOutputBuf(SOperatorInfo* pOperator, SAggOperatorInfo* pAggInfo, int32_t numOfOutput, uint64_t groupId);
|
||||
|
||||
static void doSetTableGroupOutputBuf(SOperatorInfo* pOperator, SAggOperatorInfo* pAggInfo, int32_t numOfOutput,
|
||||
uint64_t groupId);
|
||||
|
||||
// setup the output buffer for each operator
|
||||
static bool hasNull(SColumn* pColumn, SColumnDataAgg* pStatis) {
|
||||
|
@ -1230,8 +1230,9 @@ void initResultRow(SResultRow* pResultRow) {
|
|||
* offset[0] offset[1] offset[2]
|
||||
*/
|
||||
// TODO refactor: some function move away
|
||||
void setFunctionResultOutput(SOperatorInfo *pOperator, SOptrBasicInfo *pInfo, SAggSupporter* pSup, int32_t stage, int32_t numOfExprs) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
void setFunctionResultOutput(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t stage,
|
||||
int32_t numOfExprs) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SqlFunctionCtx* pCtx = pOperator->exprSupp.pCtx;
|
||||
int32_t* rowEntryInfoOffset = pOperator->exprSupp.rowEntryInfoOffset;
|
||||
|
||||
|
@ -1380,9 +1381,10 @@ void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const int8_t* rowR
|
|||
}
|
||||
}
|
||||
|
||||
void doSetTableGroupOutputBuf(SOperatorInfo* pOperator, SAggOperatorInfo* pAggInfo, int32_t numOfOutput, uint64_t groupId) {
|
||||
void doSetTableGroupOutputBuf(SOperatorInfo* pOperator, SAggOperatorInfo* pAggInfo, int32_t numOfOutput,
|
||||
uint64_t groupId) {
|
||||
// for simple group by query without interval, all the tables belong to one group result.
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SResultRowInfo* pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
|
||||
SqlFunctionCtx* pCtx = pOperator->exprSupp.pCtx;
|
||||
int32_t* rowEntryInfoOffset = pOperator->exprSupp.rowEntryInfoOffset;
|
||||
|
@ -2040,8 +2042,8 @@ static int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInf
|
|||
}
|
||||
|
||||
int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadInfo, int32_t numOfRows, char* pData,
|
||||
int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
|
||||
SArray* pColList) {
|
||||
int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
|
||||
SArray* pColList) {
|
||||
if (pColList == NULL) { // data from other sources
|
||||
blockCompressDecode(pRes, numOfOutput, numOfRows, pData);
|
||||
pRes->info.rows = numOfRows;
|
||||
|
@ -2084,7 +2086,7 @@ int32_t extractDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLo
|
|||
|
||||
// data from mnode
|
||||
pRes->info.rows = numOfRows;
|
||||
relocateColumnData(pRes, pColList, pBlock->pDataBlock);
|
||||
relocateColumnData(pRes, pColList, pBlock->pDataBlock, false);
|
||||
taosArrayDestroy(pBlock->pDataBlock);
|
||||
taosMemoryFree(pBlock);
|
||||
// blockDataDestroy(pBlock);
|
||||
|
@ -2165,8 +2167,9 @@ static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SEx
|
|||
}
|
||||
|
||||
SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
|
||||
code = extractDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
|
||||
pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
|
||||
code =
|
||||
extractDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
|
||||
pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
|
||||
if (code != 0) {
|
||||
taosMemoryFreeClear(pDataInfo->pRsp);
|
||||
goto _error;
|
||||
|
@ -2281,7 +2284,7 @@ static SSDataBlock* seqLoadRemoteData(SOperatorInfo* pOperator) {
|
|||
SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
|
||||
int32_t code =
|
||||
extractDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
|
||||
pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
|
||||
pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
|
||||
|
||||
if (pRsp->completed == 1) {
|
||||
qDebug("%s fetch msg rsp from vgId:%d, taskId:0x%" PRIx64 " numOfRows:%d, rowsOfSource:%" PRIu64
|
||||
|
@ -2673,8 +2676,8 @@ static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
|
||||
pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize,
|
||||
numOfBufPage, pInfo->binfo.pRes, "GET_TASKID(pTaskInfo)");
|
||||
pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize, numOfBufPage,
|
||||
pInfo->binfo.pRes, "GET_TASKID(pTaskInfo)");
|
||||
|
||||
tsortSetFetchRawDataFp(pInfo->pSortHandle, loadNextDataBlock, NULL, NULL);
|
||||
|
||||
|
@ -2812,7 +2815,8 @@ int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t* order, int32_t* scan
|
|||
// todo add more information about exchange operation
|
||||
int32_t type = pOperator->operatorType;
|
||||
if (type == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE || type == QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN ||
|
||||
type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN || type == QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN) {
|
||||
type == QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN || type == QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN ||
|
||||
type == QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN) {
|
||||
*order = TSDB_ORDER_ASC;
|
||||
*scanFlag = MAIN_SCAN;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -2840,7 +2844,6 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
|
|||
SAggOperatorInfo* pAggInfo = pOperator->info;
|
||||
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
SOptrBasicInfo* pInfo = &pAggInfo->binfo;
|
||||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
@ -3130,7 +3133,7 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
|||
SProjectOperatorInfo* pProjectInfo = pOperator->info;
|
||||
SOptrBasicInfo* pInfo = &pProjectInfo->binfo;
|
||||
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
SSDataBlock* pRes = pInfo->pRes;
|
||||
blockDataCleanup(pRes);
|
||||
|
||||
|
@ -3403,8 +3406,8 @@ void cleanupAggSup(SAggSupporter* pAggSup) {
|
|||
destroyDiskbasedBuf(pAggSup->pResultBuf);
|
||||
}
|
||||
|
||||
int32_t initAggInfo(SExprSupp* pSup, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
size_t keyBufSize, const char* pkey) {
|
||||
int32_t initAggInfo(SExprSupp* pSup, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols, size_t keyBufSize,
|
||||
const char* pkey) {
|
||||
initExprSupp(pSup, pExprInfo, numOfCols);
|
||||
doInitAggInfoSup(pAggSup, pSup->pCtx, numOfCols, keyBufSize, pkey);
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
|
@ -3457,12 +3460,12 @@ SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
initBasicInfo(&pInfo->binfo, pResultBlock);
|
||||
initExprSupp(&pInfo->scalarExprSup, pScalarExprInfo, numOfScalarExpr);
|
||||
|
||||
pInfo->groupId = INT32_MIN;
|
||||
pOperator->name = "TableAggregate";
|
||||
pInfo->groupId = INT32_MIN;
|
||||
pOperator->name = "TableAggregate";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_HASH_AGG;
|
||||
pOperator->blocking = true;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->blocking = true;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(doOpenAggregateOptr, getAggregateResult, NULL, NULL, destroyAggOperatorInfo,
|
||||
|
@ -3578,25 +3581,26 @@ static SArray* setRowTsColumnOutputInfo(SqlFunctionCtx* pCtx, int32_t numOfCols)
|
|||
return pList;
|
||||
}
|
||||
|
||||
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhysiNode* pProjPhyNode, SExecTaskInfo* pTaskInfo) {
|
||||
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhysiNode* pProjPhyNode,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
SProjectOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SProjectOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
int32_t numOfCols = 0;
|
||||
int32_t numOfCols = 0;
|
||||
SExprInfo* pExprInfo = createExprInfo(pProjPhyNode->pProjections, NULL, &numOfCols);
|
||||
|
||||
SSDataBlock* pResBlock = createResDataBlock(pProjPhyNode->node.pOutputDataBlockDesc);
|
||||
SLimit limit = {.limit = pProjPhyNode->limit, .offset = pProjPhyNode->offset};
|
||||
SLimit slimit = {.limit = pProjPhyNode->slimit, .offset = pProjPhyNode->soffset};
|
||||
|
||||
pInfo->limit = limit;
|
||||
pInfo->slimit = slimit;
|
||||
pInfo->curOffset = limit.offset;
|
||||
pInfo->curSOffset = slimit.offset;
|
||||
pInfo->binfo.pRes = pResBlock;
|
||||
pInfo->limit = limit;
|
||||
pInfo->slimit = slimit;
|
||||
pInfo->curOffset = limit.offset;
|
||||
pInfo->curSOffset = slimit.offset;
|
||||
pInfo->binfo.pRes = pResBlock;
|
||||
pInfo->pFilterNode = pProjPhyNode->node.pConditions;
|
||||
|
||||
int32_t numOfRows = 4096;
|
||||
|
@ -3614,12 +3618,12 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SProjectPhys
|
|||
setFunctionResultOutput(pOperator, &pInfo->binfo, &pInfo->aggSup, MAIN_SCAN, numOfCols);
|
||||
|
||||
pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pOperator->exprSupp.pCtx, numOfCols);
|
||||
pOperator->name = "ProjectOperator";
|
||||
pOperator->name = "ProjectOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doProjectOperation, NULL, NULL,
|
||||
destroyProjectOperatorInfo, NULL, NULL, NULL);
|
||||
|
@ -3639,7 +3643,7 @@ _error:
|
|||
static SSDataBlock* doApplyIndefinitFunction(SOperatorInfo* pOperator) {
|
||||
SIndefOperatorInfo* pIndefInfo = pOperator->info;
|
||||
SOptrBasicInfo* pInfo = &pIndefInfo->binfo;
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
SExprSupp* pSup = &pOperator->exprSupp;
|
||||
|
||||
SSDataBlock* pRes = pInfo->pRes;
|
||||
blockDataCleanup(pRes);
|
||||
|
@ -3677,7 +3681,7 @@ static SSDataBlock* doApplyIndefinitFunction(SOperatorInfo* pOperator) {
|
|||
SExprSupp* pScalarSup = &pIndefInfo->scalarSup;
|
||||
if (pScalarSup->pExprInfo != NULL) {
|
||||
code = projectApplyFunctions(pScalarSup->pExprInfo, pBlock, pBlock, pScalarSup->pCtx, pScalarSup->numOfExprs,
|
||||
pIndefInfo->pPseudoColInfo);
|
||||
pIndefInfo->pPseudoColInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
longjmp(pTaskInfo->env, code);
|
||||
}
|
||||
|
@ -3686,8 +3690,8 @@ static SSDataBlock* doApplyIndefinitFunction(SOperatorInfo* pOperator) {
|
|||
setInputDataBlock(pOperator, pSup->pCtx, pBlock, order, scanFlag, false);
|
||||
blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);
|
||||
|
||||
code = projectApplyFunctions(pOperator->exprSupp.pExprInfo, pInfo->pRes, pBlock, pSup->pCtx, pOperator->exprSupp.numOfExprs,
|
||||
pIndefInfo->pPseudoColInfo);
|
||||
code = projectApplyFunctions(pOperator->exprSupp.pExprInfo, pInfo->pRes, pBlock, pSup->pCtx,
|
||||
pOperator->exprSupp.numOfExprs, pIndefInfo->pPseudoColInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
longjmp(pTaskInfo->env, code);
|
||||
}
|
||||
|
@ -3745,14 +3749,14 @@ SOperatorInfo* createIndefinitOutputOperatorInfo(SOperatorInfo* downstream, SPhy
|
|||
pInfo->binfo.pRes = pResBlock;
|
||||
pInfo->pPseudoColInfo = setRowTsColumnOutputInfo(pSup->pCtx, numOfExpr);
|
||||
|
||||
pOperator->name = "IndefinitOperator";
|
||||
pOperator->name = "IndefinitOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PROJECT;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->exprSupp.pExprInfo = pExprInfo;
|
||||
pOperator->exprSupp.numOfExprs = numOfExpr;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doApplyIndefinitFunction, NULL, NULL,
|
||||
destroyIndefinitOperatorInfo, NULL, NULL, NULL);
|
||||
|
@ -3827,11 +3831,11 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode*
|
|||
goto _error;
|
||||
}
|
||||
|
||||
int32_t num = 0;
|
||||
SSDataBlock* pResBlock = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc);
|
||||
SExprInfo* pExprInfo = createExprInfo(pPhyFillNode->pTargets, NULL, &num);
|
||||
SInterval* pInterval = &((SIntervalAggOperatorInfo*)downstream->info)->interval;
|
||||
int32_t type = convertFillType(pPhyFillNode->mode);
|
||||
int32_t num = 0;
|
||||
SSDataBlock* pResBlock = createResDataBlock(pPhyFillNode->node.pOutputDataBlockDesc);
|
||||
SExprInfo* pExprInfo = createExprInfo(pPhyFillNode->pTargets, NULL, &num);
|
||||
SInterval* pInterval = &((SIntervalAggOperatorInfo*)downstream->info)->interval;
|
||||
int32_t type = convertFillType(pPhyFillNode->mode);
|
||||
|
||||
SResultInfo* pResultInfo = &pOperator->resultInfo;
|
||||
initResultSizeInfo(pOperator, 4096);
|
||||
|
@ -3842,16 +3846,16 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode*
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->pRes = pResBlock;
|
||||
pInfo->pRes = pResBlock;
|
||||
pInfo->multigroupResult = multigroupResult;
|
||||
pOperator->name = "FillOperator";
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->name = "FillOperator";
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_FILL;
|
||||
pOperator->exprSupp.pExprInfo = pExprInfo;
|
||||
pOperator->exprSupp.numOfExprs = num;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->exprSupp.pExprInfo = pExprInfo;
|
||||
pOperator->exprSupp.numOfExprs = num;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
pOperator->fpSet =
|
||||
createOperatorFpSet(operatorDummyOpenFn, doFill, NULL, NULL, destroySFillOperatorInfo, NULL, NULL, NULL);
|
||||
|
@ -4050,10 +4054,14 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
STimeWindowAggSupp twSup = {
|
||||
.waterMark = pTableScanNode->watermark, .calTrigger = pTableScanNode->triggerType, .maxTs = INT64_MIN};
|
||||
tsdbReaderT pDataReader = NULL;
|
||||
if (pHandle->vnode) {
|
||||
pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableListInfo, (uint64_t)queryId, taskId, pTagCond);
|
||||
} else {
|
||||
getTableList(pHandle->meta, pScanPhyNode, pTableListInfo, pTagCond);
|
||||
|
||||
if (pHandle) {
|
||||
if (pHandle->vnode) {
|
||||
pDataReader =
|
||||
doCreateDataReader(pTableScanNode, pHandle, pTableListInfo, (uint64_t)queryId, taskId, pTagCond);
|
||||
} else {
|
||||
getTableList(pHandle->meta, pScanPhyNode, pTableListInfo, pTagCond);
|
||||
}
|
||||
}
|
||||
|
||||
if (pDataReader == NULL && terrno != 0) {
|
||||
|
@ -4087,6 +4095,46 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
}
|
||||
|
||||
return createTagScanOperatorInfo(pHandle, pScanPhyNode, pTableListInfo, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN == type) {
|
||||
SBlockDistScanPhysiNode* pBlockNode = (SBlockDistScanPhysiNode*) pPhyNode;
|
||||
pTableListInfo->pTableList = taosArrayInit(4, sizeof(STableKeyInfo));
|
||||
|
||||
if (pBlockNode->tableType == TSDB_SUPER_TABLE) {
|
||||
int32_t code = tsdbGetAllTableList(pHandle->meta, pBlockNode->uid, pTableListInfo->pTableList);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pTaskInfo->code = terrno;
|
||||
return NULL;
|
||||
}
|
||||
} else { // Create one table group.
|
||||
STableKeyInfo info = {.lastKey = 0, .uid = pBlockNode->uid};
|
||||
taosArrayPush(pTableListInfo->pTableList, &info);
|
||||
}
|
||||
|
||||
SQueryTableDataCond cond = {0};
|
||||
|
||||
{
|
||||
cond.order = TSDB_ORDER_ASC;
|
||||
cond.numOfCols = 1;
|
||||
cond.colList = taosMemoryCalloc(1, sizeof(SColumnInfo));
|
||||
if (cond.colList == NULL) {
|
||||
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cond.colList->colId = 1;
|
||||
cond.colList->type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
cond.colList->bytes = sizeof(TSKEY);
|
||||
|
||||
cond.numOfTWindows = 1;
|
||||
cond.twindows = taosMemoryCalloc(1, sizeof(STimeWindow));
|
||||
cond.twindows[0] = (STimeWindow){.skey = INT64_MIN, .ekey = INT64_MAX};
|
||||
cond.suid = pBlockNode->suid;
|
||||
cond.type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
|
||||
}
|
||||
tsdbReaderT* pReader = tsdbReaderOpen(pHandle->vnode, &cond, pTableListInfo, queryId, taskId);
|
||||
cleanupQueryTableDataCond(&cond);
|
||||
|
||||
return createDataBlockInfoScanOperator(pReader, pHandle, cond.suid, pBlockNode, pTaskInfo);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
@ -4270,7 +4318,7 @@ SArray* extractColumnInfo(SNodeList* pNodeList) {
|
|||
SColumn c = {0};
|
||||
c.slotId = pNode->slotId;
|
||||
c.colId = pNode->slotId;
|
||||
c.type = pValNode->node.type;
|
||||
c.type = pValNode->node.type;
|
||||
c.bytes = pValNode->node.resType.bytes;
|
||||
c.scale = pValNode->node.resType.scale;
|
||||
c.precision = pValNode->node.resType.precision;
|
||||
|
@ -4284,8 +4332,7 @@ SArray* extractColumnInfo(SNodeList* pNodeList) {
|
|||
|
||||
tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
|
||||
STableListInfo* pTableListInfo, uint64_t queryId, uint64_t taskId, SNode* pTagCond) {
|
||||
int32_t code =
|
||||
getTableList(pHandle->meta, &pTableScanNode->scan, pTableListInfo, pTagCond);
|
||||
int32_t code = getTableList(pHandle->meta, &pTableScanNode->scan, pTableListInfo, pTagCond);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
@ -4374,7 +4421,7 @@ int32_t decodeOperator(SOperatorInfo* ops, const char* result, int32_t length) {
|
|||
ASSERT(length == *(int32_t*)result);
|
||||
|
||||
const char* data = result + sizeof(int32_t);
|
||||
code = ops->fpSet.decodeResultRow(ops, (char*) data);
|
||||
code = ops->fpSet.decodeResultRow(ops, (char*)data);
|
||||
if (code != TDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <vnode.h>
|
||||
#include "filter.h"
|
||||
#include "function.h"
|
||||
#include "functionMgt.h"
|
||||
|
@ -258,7 +259,7 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanInfo* pTableSca
|
|||
return terrno;
|
||||
}
|
||||
|
||||
relocateColumnData(pBlock, pTableScanInfo->pColMatchInfo, pCols);
|
||||
relocateColumnData(pBlock, pTableScanInfo->pColMatchInfo, pCols, true);
|
||||
|
||||
// currently only the tbname pseudo column
|
||||
if (pTableScanInfo->pseudoSup.numOfExprs > 0) {
|
||||
|
@ -367,13 +368,14 @@ void setTbNameColData(void* pMeta, const SSDataBlock* pBlock, SColumnInfoData* p
|
|||
|
||||
static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) {
|
||||
STableScanInfo* pTableScanInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SSDataBlock* pBlock = pTableScanInfo->pResBlock;
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
while (tsdbNextDataBlock(pTableScanInfo->dataReader)) {
|
||||
if (isTaskKilled(pOperator->pTaskInfo)) {
|
||||
longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED);
|
||||
if (isTaskKilled(pTaskInfo)) {
|
||||
longjmp(pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED);
|
||||
}
|
||||
|
||||
// process this data block based on the probabilities
|
||||
|
@ -396,7 +398,7 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) {
|
|||
continue;
|
||||
}
|
||||
|
||||
uint64_t* groupId = taosHashGet(pOperator->pTaskInfo->tableqinfoList.map, &pBlock->info.uid, sizeof(int64_t));
|
||||
uint64_t* groupId = taosHashGet(pTaskInfo->tableqinfoList.map, &pBlock->info.uid, sizeof(int64_t));
|
||||
if (groupId) {
|
||||
pBlock->info.groupId = *groupId;
|
||||
}
|
||||
|
@ -525,7 +527,7 @@ SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode,
|
|||
goto _error;
|
||||
}
|
||||
|
||||
//taosSsleep(20);
|
||||
// taosSsleep(20);
|
||||
|
||||
SDataBlockDescNode* pDescNode = pTableScanNode->scan.node.pOutputDataBlockDesc;
|
||||
|
||||
|
@ -589,44 +591,76 @@ SOperatorInfo* createTableSeqScanOperatorInfo(void* pReadHandle, SExecTaskInfo*
|
|||
pInfo->dataReader = pReadHandle;
|
||||
// pInfo->prevGroupId = -1;
|
||||
|
||||
pOperator->name = "TableSeqScanOperator";
|
||||
pOperator->name = "TableSeqScanOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doTableScanImpl, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
return pOperator;
|
||||
}
|
||||
|
||||
static int32_t doGetTableRowSize(void* pMeta, uint64_t uid) {
|
||||
int32_t rowLen = 0;
|
||||
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, pMeta, 0);
|
||||
metaGetTableEntryByUid(&mr, uid);
|
||||
if (mr.me.type == TSDB_SUPER_TABLE) {
|
||||
int32_t numOfCols = mr.me.stbEntry.schemaRow.nCols;
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
rowLen += mr.me.stbEntry.schemaRow.pSchema[i].bytes;
|
||||
}
|
||||
} else if (mr.me.type == TSDB_CHILD_TABLE) {
|
||||
uint64_t suid = mr.me.ctbEntry.suid;
|
||||
metaGetTableEntryByUid(&mr, suid);
|
||||
int32_t numOfCols = mr.me.stbEntry.schemaRow.nCols;
|
||||
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
rowLen += mr.me.stbEntry.schemaRow.pSchema[i].bytes;
|
||||
}
|
||||
} else if (mr.me.type == TSDB_NORMAL_TABLE) {
|
||||
int32_t numOfCols = mr.me.ntbEntry.schemaRow.nCols;
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
rowLen += mr.me.ntbEntry.schemaRow.pSchema[i].bytes;
|
||||
}
|
||||
}
|
||||
|
||||
metaReaderClear(&mr);
|
||||
return rowLen;
|
||||
}
|
||||
|
||||
static SSDataBlock* doBlockInfoScan(SOperatorInfo* pOperator) {
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STableScanInfo* pTableScanInfo = pOperator->info;
|
||||
SBlockDistInfo* pBlockScanInfo = pOperator->info;
|
||||
|
||||
STableBlockDistInfo blockDistInfo = {0};
|
||||
blockDistInfo.maxRows = INT_MIN;
|
||||
blockDistInfo.minRows = INT_MAX;
|
||||
STableBlockDistInfo blockDistInfo = {.minRows = INT_MAX, .maxRows = INT_MIN};
|
||||
blockDistInfo.rowSize = doGetTableRowSize(pBlockScanInfo->readHandle.meta, pBlockScanInfo->uid);
|
||||
|
||||
tsdbGetFileBlocksDistInfo(pTableScanInfo->dataReader, &blockDistInfo);
|
||||
blockDistInfo.numOfInmemRows = (int32_t)tsdbGetNumOfRowsInMemTable(pTableScanInfo->dataReader);
|
||||
tsdbGetFileBlocksDistInfo(pBlockScanInfo->pHandle, &blockDistInfo);
|
||||
blockDistInfo.numOfInmemRows = (int32_t)tsdbGetNumOfRowsInMemTable(pBlockScanInfo->pHandle);
|
||||
|
||||
SSDataBlock* pBlock = pTableScanInfo->pResBlock;
|
||||
pBlock->info.rows = 1;
|
||||
SSDataBlock* pBlock = pBlockScanInfo->pResBlock;
|
||||
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
int32_t slotId = pOperator->exprSupp.pExprInfo->base.resSchema.slotId;
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
|
||||
int32_t len = tSerializeBlockDistInfo(NULL, 0, &blockDistInfo);
|
||||
char* p = taosMemoryCalloc(1, len + VARSTR_HEADER_SIZE);
|
||||
tSerializeBlockDistInfo(varDataVal(p), len, &blockDistInfo);
|
||||
varDataSetLen(p, len);
|
||||
|
||||
blockDataEnsureCapacity(pBlock, 1);
|
||||
colDataAppend(pColInfo, 0, p, false);
|
||||
taosMemoryFree(p);
|
||||
|
||||
pBlock->info.rows = 1;
|
||||
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
return pBlock;
|
||||
}
|
||||
|
@ -636,7 +670,8 @@ static void destroyBlockDistScanOperatorInfo(void* param, int32_t numOfOutput) {
|
|||
blockDataDestroy(pDistInfo->pResBlock);
|
||||
}
|
||||
|
||||
SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo* pTaskInfo) {
|
||||
SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SReadHandle* readHandle, uint64_t uid,
|
||||
SBlockDistScanPhysiNode* pBlockScanNode, SExecTaskInfo* pTaskInfo) {
|
||||
SBlockDistInfo* pInfo = taosMemoryCalloc(1, sizeof(SBlockDistInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
|
@ -644,21 +679,20 @@ SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo*
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->pHandle = dataReader;
|
||||
pInfo->pHandle = dataReader;
|
||||
pInfo->readHandle = *readHandle;
|
||||
pInfo->uid = uid;
|
||||
pInfo->pResBlock = createResDataBlock(pBlockScanNode->node.pOutputDataBlockDesc);
|
||||
|
||||
pInfo->pResBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
|
||||
int32_t numOfCols = 0;
|
||||
SExprInfo* pExprInfo = createExprInfo(pBlockScanNode->pScanPseudoCols, NULL, &numOfCols);
|
||||
initExprSupp(&pOperator->exprSupp, pExprInfo, numOfCols);
|
||||
|
||||
SColumnInfoData infoData = {0};
|
||||
infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
|
||||
infoData.info.bytes = 1024;
|
||||
|
||||
taosArrayPush(pInfo->pResBlock->pDataBlock, &infoData);
|
||||
|
||||
pOperator->name = "DataBlockInfoScanOperator";
|
||||
// pOperator->operatorType = OP_TableBlockInfoScan;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->name = "DataBlockDistScanOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doBlockInfoScan, NULL, NULL,
|
||||
|
@ -706,9 +740,8 @@ static bool prepareDataScan(SStreamBlockScanInfo* pInfo) {
|
|||
SStreamAggSupporter* pAggSup = pInfo->sessionSup.pStreamAggSup;
|
||||
int64_t gap = pInfo->sessionSup.gap;
|
||||
int32_t winIndex = 0;
|
||||
SResultWindowInfo* pCurWin =
|
||||
getSessionTimeWindow(pAggSup, tsCols[pInfo->updateResIndex], INT64_MIN,
|
||||
pSDB->info.groupId, gap, &winIndex);
|
||||
SResultWindowInfo* pCurWin =
|
||||
getSessionTimeWindow(pAggSup, tsCols[pInfo->updateResIndex], INT64_MIN, pSDB->info.groupId, gap, &winIndex);
|
||||
win = pCurWin->win;
|
||||
pInfo->updateResIndex +=
|
||||
updateSessionWindowInfo(pCurWin, tsCols, NULL, pSDB->info.rows, pInfo->updateResIndex, gap, NULL);
|
||||
|
@ -789,23 +822,23 @@ static SSDataBlock* doDataScan(SStreamBlockScanInfo* pInfo) {
|
|||
if (!pResult) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (pResult->info.groupId == pInfo->groupId) {
|
||||
return pResult;
|
||||
}
|
||||
}
|
||||
|
||||
/* Todo(liuyao) for partition by column
|
||||
SSDataBlock* pBlock = createOneDataBlock(pResult, true);
|
||||
blockDataCleanup(pResult);
|
||||
for (int32_t i = 0; i < pBlock->info.rows; i++) {
|
||||
uint64_t id = getGroupId(pInfo->pOperatorDumy, pBlock, i);
|
||||
if (id == pInfo->groupId) {
|
||||
copyOneRow(pResult, pBlock, i);
|
||||
/* Todo(liuyao) for partition by column
|
||||
SSDataBlock* pBlock = createOneDataBlock(pResult, true);
|
||||
blockDataCleanup(pResult);
|
||||
for (int32_t i = 0; i < pBlock->info.rows; i++) {
|
||||
uint64_t id = getGroupId(pInfo->pOperatorDumy, pBlock, i);
|
||||
if (id == pInfo->groupId) {
|
||||
copyOneRow(pResult, pBlock, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pResult;
|
||||
*/
|
||||
return pResult;
|
||||
*/
|
||||
}
|
||||
|
||||
static void setUpdateData(SStreamBlockScanInfo* pInfo, SSDataBlock* pBlock, SSDataBlock* pUpdateBlock) {
|
||||
|
@ -820,7 +853,7 @@ static void setUpdateData(SStreamBlockScanInfo* pInfo, SSDataBlock* pBlock, SSDa
|
|||
int32_t rowId = *(int32_t*)taosArrayGet(pInfo->tsArray, pInfo->tsArrayIndex);
|
||||
pInfo->groupId = getGroupId(pInfo->pOperatorDumy, pBlock, rowId);
|
||||
int32_t i = 0;
|
||||
for ( ; i < size; i++) {
|
||||
for (; i < size; i++) {
|
||||
rowId = *(int32_t*)taosArrayGet(pInfo->tsArray, i + pInfo->tsArrayIndex);
|
||||
uint64_t id = getGroupId(pInfo->pOperatorDumy, pBlock, rowId);
|
||||
if (pInfo->groupId != id) {
|
||||
|
@ -1050,9 +1083,6 @@ SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHan
|
|||
SScanPhysiNode* pScanPhyNode = &pTableScanNode->scan;
|
||||
|
||||
SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc;
|
||||
SOperatorInfo* pTableScanDummy = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, pTaskInfo);
|
||||
|
||||
STableScanInfo* pSTInfo = (STableScanInfo*)pTableScanDummy->info;
|
||||
|
||||
int32_t numOfCols = 0;
|
||||
pInfo->pColMatchInfo = extractColMatchInfo(pScanPhyNode->pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID);
|
||||
|
@ -1069,16 +1099,6 @@ SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHan
|
|||
}
|
||||
}
|
||||
|
||||
// set the extract column id to streamHandle
|
||||
tqReadHandleSetColIdList((STqReadHandle*)pHandle->reader, pColIds);
|
||||
SArray* tableIdList = extractTableIdList(&pTaskInfo->tableqinfoList);
|
||||
int32_t code = tqReadHandleSetTbUidList(pHandle->reader, tableIdList);
|
||||
if (code != 0) {
|
||||
taosArrayDestroy(tableIdList);
|
||||
goto _error;
|
||||
}
|
||||
taosArrayDestroy(tableIdList);
|
||||
|
||||
pInfo->pBlockLists = taosArrayInit(4, POINTER_BYTES);
|
||||
if (pInfo->pBlockLists == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -1090,10 +1110,31 @@ SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHan
|
|||
goto _error;
|
||||
}
|
||||
|
||||
if (pSTInfo->interval.interval > 0 && pDataReader) {
|
||||
pInfo->pUpdateInfo = updateInfoInitP(&pSTInfo->interval, pTwSup->waterMark);
|
||||
} else {
|
||||
pInfo->pUpdateInfo = NULL;
|
||||
if (pHandle) {
|
||||
SOperatorInfo* pTableScanDummy = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, pTaskInfo);
|
||||
STableScanInfo* pSTInfo = (STableScanInfo*)pTableScanDummy->info;
|
||||
if (pSTInfo->interval.interval > 0) {
|
||||
pInfo->pUpdateInfo = updateInfoInitP(&pSTInfo->interval, pTwSup->waterMark);
|
||||
} else {
|
||||
pInfo->pUpdateInfo = NULL;
|
||||
}
|
||||
pInfo->pOperatorDumy = pTableScanDummy;
|
||||
pInfo->interval = pSTInfo->interval;
|
||||
|
||||
pInfo->readHandle = *pHandle;
|
||||
ASSERT(pHandle->reader);
|
||||
pInfo->streamBlockReader = pHandle->reader;
|
||||
pInfo->tableUid = pScanPhyNode->uid;
|
||||
|
||||
// set the extract column id to streamHandle
|
||||
tqReadHandleSetColIdList((STqReadHandle*)pHandle->reader, pColIds);
|
||||
SArray* tableIdList = extractTableIdList(&pTaskInfo->tableqinfoList);
|
||||
int32_t code = tqReadHandleSetTbUidList(pHandle->reader, tableIdList);
|
||||
if (code != 0) {
|
||||
taosArrayDestroy(tableIdList);
|
||||
goto _error;
|
||||
}
|
||||
taosArrayDestroy(tableIdList);
|
||||
}
|
||||
|
||||
// create the pseduo columns info
|
||||
|
@ -1101,19 +1142,14 @@ SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHan
|
|||
pInfo->pPseudoExpr = createExprInfo(pTableScanNode->scan.pScanPseudoCols, NULL, &pInfo->numOfPseudoExpr);
|
||||
}
|
||||
|
||||
pInfo->readHandle = *pHandle;
|
||||
pInfo->tableUid = pScanPhyNode->uid;
|
||||
pInfo->streamBlockReader = pHandle->reader;
|
||||
pInfo->pRes = createResDataBlock(pDescNode);
|
||||
pInfo->pUpdateRes = createResDataBlock(pDescNode);
|
||||
pInfo->pCondition = pScanPhyNode->node.pConditions;
|
||||
pInfo->pDataReader = pDataReader;
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE;
|
||||
pInfo->pOperatorDumy = pTableScanDummy;
|
||||
pInfo->interval = pSTInfo->interval;
|
||||
pInfo->sessionSup = (SessionWindowSupporter){.pStreamAggSup = NULL, .gap = -1};
|
||||
pInfo->groupId = 0;
|
||||
|
||||
|
||||
pOperator->name = "StreamBlockScanOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN;
|
||||
pOperator->blocking = false;
|
||||
|
@ -1392,15 +1428,15 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
|||
|
||||
// table comment
|
||||
pColInfoData = taosArrayGet(p->pDataBlock, 8);
|
||||
if(pInfo->pCur->mr.me.ctbEntry.commentLen > 0) {
|
||||
if (pInfo->pCur->mr.me.ctbEntry.commentLen > 0) {
|
||||
char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(comment, pInfo->pCur->mr.me.ctbEntry.comment);
|
||||
colDataAppend(pColInfoData, numOfRows, comment, false);
|
||||
}else if(pInfo->pCur->mr.me.ctbEntry.commentLen == 0) {
|
||||
} else if (pInfo->pCur->mr.me.ctbEntry.commentLen == 0) {
|
||||
char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(comment, "");
|
||||
colDataAppend(pColInfoData, numOfRows, comment, false);
|
||||
}else{
|
||||
} else {
|
||||
colDataAppendNULL(pColInfoData, numOfRows);
|
||||
}
|
||||
|
||||
|
@ -1428,15 +1464,15 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
|||
|
||||
// table comment
|
||||
pColInfoData = taosArrayGet(p->pDataBlock, 8);
|
||||
if(pInfo->pCur->mr.me.ntbEntry.commentLen > 0) {
|
||||
if (pInfo->pCur->mr.me.ntbEntry.commentLen > 0) {
|
||||
char comment[TSDB_TB_COMMENT_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(comment, pInfo->pCur->mr.me.ntbEntry.comment);
|
||||
colDataAppend(pColInfoData, numOfRows, comment, false);
|
||||
}else if(pInfo->pCur->mr.me.ntbEntry.commentLen == 0) {
|
||||
} else if (pInfo->pCur->mr.me.ntbEntry.commentLen == 0) {
|
||||
char comment[VARSTR_HEADER_SIZE + VARSTR_HEADER_SIZE] = {0};
|
||||
STR_TO_VARSTR(comment, "");
|
||||
colDataAppend(pColInfoData, numOfRows, comment, false);
|
||||
}else{
|
||||
} else {
|
||||
colDataAppendNULL(pColInfoData, numOfRows);
|
||||
}
|
||||
|
||||
|
@ -1469,7 +1505,7 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
|||
p->info.rows = numOfRows;
|
||||
pInfo->pRes->info.rows = numOfRows;
|
||||
|
||||
relocateColumnData(pInfo->pRes, pInfo->scanCols, p->pDataBlock);
|
||||
relocateColumnData(pInfo->pRes, pInfo->scanCols, p->pDataBlock, false);
|
||||
doFilterResult(pInfo);
|
||||
|
||||
blockDataDestroy(p);
|
||||
|
@ -1536,7 +1572,7 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
extractDataBlockFromFetchRsp(pInfo->pRes, &pInfo->loadInfo, pRsp->numOfRows, pRsp->data, pRsp->compLen,
|
||||
pOperator->exprSupp.numOfExprs, startTs, NULL, pInfo->scanCols);
|
||||
pOperator->exprSupp.numOfExprs, startTs, NULL, pInfo->scanCols);
|
||||
|
||||
// todo log the filter info
|
||||
doFilterResult(pInfo);
|
||||
|
@ -1561,7 +1597,7 @@ int32_t buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capacity) {
|
|||
getPerfDbMeta(&pSysDbTableMeta, &size);
|
||||
p->info.rows = buildDbTableInfoBlock(p, pSysDbTableMeta, size, TSDB_PERFORMANCE_SCHEMA_DB);
|
||||
|
||||
relocateColumnData(pInfo->pRes, pInfo->scanCols, p->pDataBlock);
|
||||
relocateColumnData(pInfo->pRes, pInfo->scanCols, p->pDataBlock, false);
|
||||
pInfo->pRes->info.rows = p->info.rows;
|
||||
blockDataDestroy(p);
|
||||
|
||||
|
@ -1833,7 +1869,10 @@ SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysi
|
|||
int32_t num = 0;
|
||||
int32_t numOfExprs = 0;
|
||||
SExprInfo* pExprInfo = createExprInfo(pPhyNode->pScanPseudoCols, NULL, &numOfExprs);
|
||||
SArray* colList = extractColMatchInfo(pPhyNode->pScanPseudoCols, pDescNode, &num, COL_MATCH_FROM_COL_ID);
|
||||
SArray* colList = extractColMatchInfo(pPhyNode->pScanPseudoCols, pDescNode, &num, COL_MATCH_FROM_COL_ID);
|
||||
|
||||
|
||||
initExprSupp(&pOperator->exprSupp, pExprInfo, numOfExprs);
|
||||
|
||||
pInfo->pTableList = pTableListInfo;
|
||||
pInfo->pColMatchInfo = colList;
|
||||
|
@ -1842,13 +1881,12 @@ SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysi
|
|||
pInfo->curPos = 0;
|
||||
pInfo->pFilterNode = pPhyNode->node.pConditions;
|
||||
|
||||
pOperator->name = "TagScanOperator";
|
||||
pOperator->name = "TagScanOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN;
|
||||
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->exprSupp.pExprInfo = pExprInfo;
|
||||
pOperator->exprSupp.numOfExprs = numOfExprs;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
initResultSizeInfo(pOperator, 4096);
|
||||
|
@ -1918,8 +1956,7 @@ typedef struct STableMergeScanInfo {
|
|||
int32_t createMultipleDataReaders(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
|
||||
STableListInfo* pTableListInfo, SArray* arrayReader, uint64_t queryId,
|
||||
uint64_t taskId, SNode* pTagCond) {
|
||||
int32_t code =
|
||||
getTableList(pHandle->meta, &pTableScanNode->scan, pTableListInfo, pTagCond);
|
||||
int32_t code = getTableList(pHandle->meta, &pTableScanNode->scan, pTableListInfo, pTagCond);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
@ -1956,7 +1993,7 @@ _error:
|
|||
|
||||
static int32_t loadDataBlockFromOneTable(SOperatorInfo* pOperator, STableMergeScanInfo* pTableScanInfo,
|
||||
int32_t readerIdx, SSDataBlock* pBlock, uint32_t* status) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
STableMergeScanInfo* pInfo = pOperator->info;
|
||||
|
||||
SFileBlockLoadRecorder* pCost = &pTableScanInfo->readRecorder;
|
||||
|
@ -2042,7 +2079,7 @@ static int32_t loadDataBlockFromOneTable(SOperatorInfo* pOperator, STableMergeSc
|
|||
return terrno;
|
||||
}
|
||||
|
||||
relocateColumnData(pBlock, pTableScanInfo->pColMatchInfo, pCols);
|
||||
relocateColumnData(pBlock, pTableScanInfo->pColMatchInfo, pCols, true);
|
||||
|
||||
// currently only the tbname pseudo column
|
||||
if (pTableScanInfo->numOfPseudoExpr > 0) {
|
||||
|
@ -2143,9 +2180,8 @@ int32_t doOpenTableMergeScanOperator(SOperatorInfo* pOperator) {
|
|||
|
||||
int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
|
||||
|
||||
pInfo->pSortHandle =
|
||||
tsortCreateSortHandle(pInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize,
|
||||
numOfBufPage, pInfo->pSortInputBlock, pTaskInfo->id.str);
|
||||
pInfo->pSortHandle = tsortCreateSortHandle(pInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pInfo->bufPageSize, numOfBufPage,
|
||||
pInfo->pSortInputBlock, pTaskInfo->id.str);
|
||||
|
||||
tsortSetFetchRawDataFp(pInfo->pSortHandle, getTableDataBlock, NULL, NULL);
|
||||
|
||||
|
@ -2209,8 +2245,7 @@ SSDataBlock* doTableMergeScan(SOperatorInfo* pOperator) {
|
|||
longjmp(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
SSDataBlock* pBlock =
|
||||
getSortedTableMergeScanBlockData(pInfo->pSortHandle, pOperator->resultInfo.capacity, pOperator);
|
||||
SSDataBlock* pBlock = getSortedTableMergeScanBlockData(pInfo->pSortHandle, pOperator->resultInfo.capacity, pOperator);
|
||||
|
||||
if (pBlock != NULL) {
|
||||
pOperator->resultInfo.totalRows += pBlock->info.rows;
|
||||
|
@ -2243,20 +2278,20 @@ void destroyTableMergeScanOperatorInfo(void* param, int32_t numOfOutput) {
|
|||
|
||||
typedef struct STableMergeScanExecInfo {
|
||||
SFileBlockLoadRecorder blockRecorder;
|
||||
SSortExecInfo sortExecInfo;
|
||||
SSortExecInfo sortExecInfo;
|
||||
} STableMergeScanExecInfo;
|
||||
|
||||
int32_t getTableMergeScanExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) {
|
||||
ASSERT(pOptr != NULL);
|
||||
// TODO: merge these two info into one struct
|
||||
STableMergeScanExecInfo* execInfo = taosMemoryCalloc(1, sizeof(STableMergeScanExecInfo));
|
||||
STableMergeScanInfo* pInfo = pOptr->info;
|
||||
STableMergeScanInfo* pInfo = pOptr->info;
|
||||
execInfo->blockRecorder = pInfo->readRecorder;
|
||||
execInfo->sortExecInfo = tsortGetSortExecInfo(pInfo->pSortHandle);
|
||||
|
||||
*pOptrExplain = execInfo;
|
||||
*len = sizeof(STableMergeScanExecInfo);
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2271,8 +2306,7 @@ SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanN
|
|||
SDataBlockDescNode* pDescNode = pTableScanNode->scan.node.pOutputDataBlockDesc;
|
||||
|
||||
int32_t numOfCols = 0;
|
||||
SArray* pColList =
|
||||
extractColMatchInfo(pTableScanNode->scan.pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID);
|
||||
SArray* pColList = extractColMatchInfo(pTableScanNode->scan.pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID);
|
||||
|
||||
int32_t code = initQueryTableDataCond(&pInfo->cond, pTableScanNode);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -2286,16 +2320,16 @@ SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanN
|
|||
|
||||
pInfo->scanInfo = (SScanInfo){.numOfAsc = pTableScanNode->scanSeq[0], .numOfDesc = pTableScanNode->scanSeq[1]};
|
||||
|
||||
pInfo->readHandle = *readHandle;
|
||||
pInfo->interval = extractIntervalInfo(pTableScanNode);
|
||||
pInfo->readHandle = *readHandle;
|
||||
pInfo->interval = extractIntervalInfo(pTableScanNode);
|
||||
pInfo->sample.sampleRatio = pTableScanNode->ratio;
|
||||
pInfo->sample.seed = taosGetTimestampSec();
|
||||
pInfo->dataBlockLoadFlag = pTableScanNode->dataRequired;
|
||||
pInfo->pFilterNode = pTableScanNode->scan.node.pConditions;
|
||||
pInfo->dataReaders = dataReaders;
|
||||
pInfo->scanFlag = MAIN_SCAN;
|
||||
pInfo->pColMatchInfo = pColList;
|
||||
pInfo->curTWinIdx = 0;
|
||||
pInfo->sample.seed = taosGetTimestampSec();
|
||||
pInfo->dataBlockLoadFlag = pTableScanNode->dataRequired;
|
||||
pInfo->pFilterNode = pTableScanNode->scan.node.pConditions;
|
||||
pInfo->dataReaders = dataReaders;
|
||||
pInfo->scanFlag = MAIN_SCAN;
|
||||
pInfo->pColMatchInfo = pColList;
|
||||
pInfo->curTWinIdx = 0;
|
||||
|
||||
pInfo->pResBlock = createResDataBlock(pDescNode);
|
||||
|
||||
|
@ -2313,22 +2347,22 @@ SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanN
|
|||
pInfo->pSortInputBlock = createOneDataBlock(pInfo->pResBlock, false);
|
||||
|
||||
int32_t rowSize = pInfo->pResBlock->info.rowSize;
|
||||
pInfo->bufPageSize = getProperSortPageSize(rowSize);
|
||||
pInfo->bufPageSize = getProperSortPageSize(rowSize);
|
||||
|
||||
// todo the total available buffer should be determined by total capacity of buffer of this task.
|
||||
// the additional one is reserved for merge result
|
||||
pInfo->sortBufSize = pInfo->bufPageSize * (taosArrayGetSize(dataReaders) + 1);
|
||||
pInfo->hasGroupId = false;
|
||||
pInfo->sortBufSize = pInfo->bufPageSize * (taosArrayGetSize(dataReaders) + 1);
|
||||
pInfo->hasGroupId = false;
|
||||
pInfo->prefetchedTuple = NULL;
|
||||
|
||||
pOperator->name = "TableMergeScanOperator";
|
||||
pOperator->name = "TableMergeScanOperator";
|
||||
// TODO : change it
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->exprSupp.numOfExprs = numOfCols;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->exprSupp.numOfExprs = numOfCols;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
initResultSizeInfo(pOperator, 1024);
|
||||
|
||||
pOperator->fpSet =
|
||||
|
|
|
@ -2892,7 +2892,10 @@ static void rebuildTimeWindow(SStreamSessionAggOperatorInfo* pInfo, SArray* pWin
|
|||
SArray* pChWins = getWinInfos(&pChInfo->streamAggSup, groupId);
|
||||
int32_t chWinSize = taosArrayGetSize(pChWins);
|
||||
int32_t index = binarySearch(pChWins, chWinSize, pParentWin->win.skey, TSDB_ORDER_DESC, getSessionWindowEndkey);
|
||||
for (int32_t k = index; k > 0 && k < chWinSize; k++) {
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
for (int32_t k = index; k < chWinSize; k++) {
|
||||
SResultWindowInfo* pcw = taosArrayGet(pChWins, k);
|
||||
if (pParentWin->win.skey <= pcw->win.skey && pcw->win.ekey <= pParentWin->win.ekey) {
|
||||
SResultRow* pChResult = NULL;
|
||||
|
|
|
@ -192,6 +192,8 @@ int32_t twaFunction(SqlFunctionCtx *pCtx);
|
|||
int32_t twaFinalize(struct SqlFunctionCtx *pCtx, SSDataBlock* pBlock);
|
||||
|
||||
bool getSelectivityFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
|
||||
bool blockDistSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||
int32_t blockDistFunction(SqlFunctionCtx *pCtx);
|
||||
int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
|
||||
|
|
|
@ -419,7 +419,7 @@ static int32_t translateTopBot(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t topCreateMergePara(SNodeList* pRawParameters, SNode* pPartialRes, SNodeList** pParameters) {
|
||||
int32_t topBotCreateMergePara(SNodeList* pRawParameters, SNode* pPartialRes, SNodeList** pParameters) {
|
||||
int32_t code = nodesListMakeAppend(pParameters, pPartialRes);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodesListStrictAppend(*pParameters, nodesCloneNode(nodesListGetNode(pRawParameters, 1)));
|
||||
|
@ -427,65 +427,6 @@ int32_t topCreateMergePara(SNodeList* pRawParameters, SNode* pPartialRes, SNodeL
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateTopBotImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) {
|
||||
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||
|
||||
if (isPartial) {
|
||||
if (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;
|
||||
if (!IS_NUMERIC_TYPE(para1Type) || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param1
|
||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
if (nodeType(pParamNode1) != QUERY_NODE_VALUE) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SValueNode* pValue = (SValueNode*)pParamNode1;
|
||||
if (pValue->node.resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (pValue->datum.i < 1 || pValue->datum.i > 100) {
|
||||
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pValue->notReserved = true;
|
||||
|
||||
// set result type
|
||||
pFunc->node.resType =
|
||||
(SDataType){.bytes = getTopBotInfoSize(pValue->datum.i) + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||
} else {
|
||||
if (1 != numOfParams) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
if (TSDB_DATA_TYPE_BINARY != para1Type) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// Do nothing. We can only access output of partial functions as input,
|
||||
// so original input type cannot be obtained, resType will be set same
|
||||
// as original function input type after merge function created.
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateTopBotPartial(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
return translateTopBotImpl(pFunc, pErrBuf, len, true);
|
||||
}
|
||||
|
||||
static int32_t translateTopBotMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
return translateTopBotImpl(pFunc, pErrBuf, len, false);
|
||||
}
|
||||
|
||||
static int32_t translateSpread(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -1735,31 +1676,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = topFunction,
|
||||
.finalizeFunc = topBotFinalize,
|
||||
.combineFunc = topCombine,
|
||||
.pPartialFunc = "_top_partial",
|
||||
.pMergeFunc = "_top_merge",
|
||||
// .createMergeParaFuc = topCreateMergePara
|
||||
},
|
||||
{
|
||||
.name = "_top_partial",
|
||||
.type = FUNCTION_TYPE_TOP_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC,
|
||||
.translateFunc = translateTopBotPartial,
|
||||
.getEnvFunc = getTopBotFuncEnv,
|
||||
.initFunc = topBotFunctionSetup,
|
||||
.processFunc = topFunction,
|
||||
.finalizeFunc = topBotPartialFinalize,
|
||||
.combineFunc = topCombine,
|
||||
},
|
||||
{
|
||||
.name = "_top_merge",
|
||||
.type = FUNCTION_TYPE_TOP_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC,
|
||||
.translateFunc = translateTopBotMerge,
|
||||
.getEnvFunc = getTopBotMergeFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = topFunctionMerge,
|
||||
.finalizeFunc = topBotMergeFinalize,
|
||||
.combineFunc = topCombine,
|
||||
.pPartialFunc = "top",
|
||||
.pMergeFunc = "top",
|
||||
.createMergeParaFuc = topBotCreateMergePara
|
||||
},
|
||||
{
|
||||
.name = "bottom",
|
||||
|
@ -1771,30 +1690,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = bottomFunction,
|
||||
.finalizeFunc = topBotFinalize,
|
||||
.combineFunc = bottomCombine,
|
||||
.pPartialFunc = "_bottom_partial",
|
||||
.pMergeFunc = "_bottom_merge"
|
||||
},
|
||||
{
|
||||
.name = "_bottom_partial",
|
||||
.type = FUNCTION_TYPE_BOTTOM_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC,
|
||||
.translateFunc = translateTopBotPartial,
|
||||
.getEnvFunc = getTopBotFuncEnv,
|
||||
.initFunc = topBotFunctionSetup,
|
||||
.processFunc = bottomFunction,
|
||||
.finalizeFunc = topBotPartialFinalize,
|
||||
.combineFunc = bottomCombine,
|
||||
},
|
||||
{
|
||||
.name = "_bottom_merge",
|
||||
.type = FUNCTION_TYPE_BOTTOM_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_INDEFINITE_ROWS_FUNC,
|
||||
.translateFunc = translateTopBotMerge,
|
||||
.getEnvFunc = getTopBotMergeFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = bottomFunctionMerge,
|
||||
.finalizeFunc = topBotMergeFinalize,
|
||||
.combineFunc = bottomCombine,
|
||||
.pPartialFunc = "bottom",
|
||||
.pMergeFunc = "bottom",
|
||||
.createMergeParaFuc = topBotCreateMergePara
|
||||
},
|
||||
{
|
||||
.name = "spread",
|
||||
|
@ -2524,7 +2422,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.getEnvFunc = getSelectivityFuncEnv, // todo remove this function later.
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = NULL,
|
||||
.finalizeFunc = NULL
|
||||
.finalizeFunc = NULL,
|
||||
.pPartialFunc = "_select_value",
|
||||
.pMergeFunc = "_select_value"
|
||||
},
|
||||
{
|
||||
.name = "_block_dist",
|
||||
|
@ -2532,6 +2432,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateBlockDistFunc,
|
||||
.getEnvFunc = getBlockDistFuncEnv,
|
||||
.initFunc = blockDistSetup,
|
||||
.processFunc = blockDistFunction,
|
||||
.finalizeFunc = blockDistFinalize
|
||||
},
|
||||
|
|
|
@ -67,8 +67,7 @@ typedef struct STopBotResItem {
|
|||
|
||||
typedef struct STopBotRes {
|
||||
int32_t maxSize;
|
||||
int16_t type; // store the original input type, used in merge function
|
||||
int32_t numOfItems;
|
||||
int16_t type;
|
||||
STopBotResItem* pItems;
|
||||
} STopBotRes;
|
||||
|
||||
|
@ -1481,11 +1480,13 @@ int32_t minMaxCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx, int3
|
|||
if (pSBuf->assign && ((((*(double*)&pDBuf->v) < (*(double*)&pSBuf->v)) ^ isMinFunc) || !pDBuf->assign)) {
|
||||
*(double*)&pDBuf->v = *(double*)&pSBuf->v;
|
||||
replaceTupleData(&pDBuf->tuplePos, &pSBuf->tuplePos);
|
||||
pDBuf->assign = true;
|
||||
}
|
||||
} else {
|
||||
if (pSBuf->assign && (((pDBuf->v < pSBuf->v) ^ isMinFunc) || !pDBuf->assign)) {
|
||||
pDBuf->v = pSBuf->v;
|
||||
replaceTupleData(&pDBuf->tuplePos, &pSBuf->tuplePos);
|
||||
pDBuf->assign = true;
|
||||
}
|
||||
}
|
||||
pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes);
|
||||
|
@ -1745,10 +1746,10 @@ int32_t stddevFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
|
||||
if (IS_INTEGER_TYPE(type)) {
|
||||
avg = pStddevRes->isum / ((double)pStddevRes->count);
|
||||
pStddevRes->result = sqrt(pStddevRes->quadraticISum / ((double)pStddevRes->count) - avg * avg);
|
||||
pStddevRes->result = sqrt(fabs(pStddevRes->quadraticISum / ((double)pStddevRes->count) - avg * avg));
|
||||
} else {
|
||||
avg = pStddevRes->dsum / ((double)pStddevRes->count);
|
||||
pStddevRes->result = sqrt(pStddevRes->quadraticDSum / ((double)pStddevRes->count) - avg * avg);
|
||||
pStddevRes->result = sqrt(fabs(pStddevRes->quadraticDSum / ((double)pStddevRes->count) - avg * avg));
|
||||
}
|
||||
|
||||
return functionFinalize(pCtx, pBlock);
|
||||
|
@ -2561,9 +2562,6 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
|||
}
|
||||
|
||||
static void firstLastTransferInfo(SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst) {
|
||||
if (!pInput->hasResult) {
|
||||
return;
|
||||
}
|
||||
pOutput->bytes = pInput->bytes;
|
||||
TSKEY* tsIn = (TSKEY*)(pInput->buf + pInput->bytes);
|
||||
TSKEY* tsOut = (TSKEY*)(pOutput->buf + pInput->bytes);
|
||||
|
@ -2597,7 +2595,9 @@ static int32_t firstLastFunctionMergeImpl(SqlFunctionCtx* pCtx, bool isFirstQuer
|
|||
|
||||
firstLastTransferInfo(pInputInfo, pInfo, isFirstQuery);
|
||||
|
||||
SET_VAL(GET_RES_INFO(pCtx), 1, 1);
|
||||
int32_t numOfElems = pInputInfo->hasResult ? 1 : 0;
|
||||
|
||||
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -2622,6 +2622,7 @@ int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
int32_t firstLastPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
|
||||
SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
|
||||
int32_t resultBytes = getFirstLastInfoSize(pRes->bytes);
|
||||
char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char));
|
||||
|
||||
|
@ -2870,12 +2871,6 @@ bool getTopBotFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool getTopBotMergeFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||
// intermediate result is binary and length contains VAR header size
|
||||
pEnv->calcMemSize = pFunc->node.resType.bytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool topBotFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResInfo) {
|
||||
if (!functionSetup(pCtx, pResInfo)) {
|
||||
return false;
|
||||
|
@ -2950,50 +2945,6 @@ int32_t bottomFunction(SqlFunctionCtx* pCtx) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void topBotTransferInfo(SqlFunctionCtx* pCtx, STopBotRes* pInput, bool isTopQuery) {
|
||||
for (int32_t i = 0; i < pInput->numOfItems; i++) {
|
||||
addResult(pCtx, &pInput->pItems[i], pInput->type, isTopQuery);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t topFunctionMerge(SqlFunctionCtx* pCtx) {
|
||||
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
SColumnInfoData* pCol = pInput->pData[0];
|
||||
ASSERT(pCol->info.type == TSDB_DATA_TYPE_BINARY);
|
||||
|
||||
int32_t start = pInput->startRowIndex;
|
||||
char* data = colDataGetData(pCol, start);
|
||||
STopBotRes* pInputInfo = (STopBotRes*)varDataVal(data);
|
||||
STopBotRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
|
||||
pInfo->maxSize = pInputInfo->maxSize;
|
||||
pInfo->type = pInputInfo->type;
|
||||
topBotTransferInfo(pCtx, pInputInfo, true);
|
||||
SET_VAL(GET_RES_INFO(pCtx), pEntryInfo->numOfRes, pEntryInfo->numOfRes);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t bottomFunctionMerge(SqlFunctionCtx* pCtx) {
|
||||
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
SColumnInfoData* pCol = pInput->pData[0];
|
||||
ASSERT(pCol->info.type == TSDB_DATA_TYPE_BINARY);
|
||||
|
||||
int32_t start = pInput->startRowIndex;
|
||||
char* data = colDataGetData(pCol, start);
|
||||
STopBotRes* pInputInfo = (STopBotRes*)varDataVal(data);
|
||||
STopBotRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
|
||||
pInfo->maxSize = pInputInfo->maxSize;
|
||||
pInfo->type = pInputInfo->type;
|
||||
topBotTransferInfo(pCtx, pInputInfo, false);
|
||||
SET_VAL(GET_RES_INFO(pCtx), pEntryInfo->numOfRes, pEntryInfo->numOfRes);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t topBotResComparFn(const void* p1, const void* p2, const void* param) {
|
||||
uint16_t type = *(uint16_t*)param;
|
||||
|
||||
|
@ -3042,8 +2993,6 @@ void doAddIntoResult(SqlFunctionCtx* pCtx, void* pData, int32_t rowIndex, SSData
|
|||
|
||||
// allocate the buffer and keep the data of this row into the new allocated buffer
|
||||
pEntryInfo->numOfRes++;
|
||||
// accumulate number of items for each vgroup, this info is needed for merge
|
||||
pRes->numOfItems++;
|
||||
taosheapsort((void*)pItems, sizeof(STopBotResItem), pEntryInfo->numOfRes, (const void*)&type, topBotResComparFn,
|
||||
!isTopQuery);
|
||||
} else { // replace the minimum value in the result
|
||||
|
@ -3142,7 +3091,7 @@ void copyTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pS
|
|||
releaseBufPage(pCtx->pBuf, pPage);
|
||||
}
|
||||
|
||||
int32_t topBotFinalizeImpl(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, bool isMerge) {
|
||||
int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
|
||||
STopBotRes* pRes = GET_ROWCELL_INTERBUF(pEntryInfo);
|
||||
|
||||
|
@ -3162,39 +3111,13 @@ int32_t topBotFinalizeImpl(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, bool isMer
|
|||
colDataAppend(pCol, currentRow, (const char*)&pItem->v.i, false);
|
||||
}
|
||||
|
||||
if (!isMerge) {
|
||||
setSelectivityValue(pCtx, pBlock, &pRes->pItems[i].tuplePos, currentRow);
|
||||
}
|
||||
setSelectivityValue(pCtx, pBlock, &pRes->pItems[i].tuplePos, currentRow);
|
||||
currentRow += 1;
|
||||
}
|
||||
|
||||
return pEntryInfo->numOfRes;
|
||||
}
|
||||
|
||||
int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { return topBotFinalizeImpl(pCtx, pBlock, false); }
|
||||
|
||||
int32_t topBotMergeFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
return topBotFinalizeImpl(pCtx, pBlock, true);
|
||||
}
|
||||
|
||||
int32_t topBotPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
|
||||
STopBotRes* pRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
int32_t resultBytes = getTopBotInfoSize(pRes->maxSize);
|
||||
char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char));
|
||||
|
||||
memcpy(varDataVal(res), pRes, resultBytes);
|
||||
varDataSetLen(res, resultBytes);
|
||||
|
||||
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
|
||||
colDataAppend(pCol, pBlock->info.rows, res, false);
|
||||
|
||||
taosMemoryFree(res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void addResult(SqlFunctionCtx* pCtx, STopBotResItem* pSourceItem, int16_t type, bool isTopQuery) {
|
||||
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
|
||||
STopBotRes* pRes = getTopBotOutputInfo(pCtx);
|
||||
|
@ -3209,8 +3132,6 @@ void addResult(SqlFunctionCtx* pCtx, STopBotResItem* pSourceItem, int16_t type,
|
|||
pItem->tuplePos.pageId = -1;
|
||||
replaceTupleData(&pItem->tuplePos, &pSourceItem->tuplePos);
|
||||
pEntryInfo->numOfRes++;
|
||||
// accumulate number of items for each vgroup, this info is needed for merge
|
||||
pRes->numOfItems++;
|
||||
taosheapsort((void*)pItems, sizeof(STopBotResItem), pEntryInfo->numOfRes, (const void*)&type, topBotResComparFn,
|
||||
!isTopQuery);
|
||||
} else { // replace the minimum value in the result
|
||||
|
@ -5002,7 +4923,19 @@ int32_t twaFinalize(struct SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
return functionFinalize(pCtx, pBlock);
|
||||
}
|
||||
|
||||
bool blockDistSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
|
||||
if (!functionSetup(pCtx, pResultInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
STableBlockDistInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
pInfo->minRows = INT32_MAX;
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t blockDistFunction(SqlFunctionCtx* pCtx) {
|
||||
const int32_t BLOCK_DIST_RESULT_ROWS = 24;
|
||||
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||
|
||||
|
@ -5020,6 +4953,11 @@ int32_t blockDistFunction(SqlFunctionCtx* pCtx) {
|
|||
pDistInfo->totalRows += p1.totalRows;
|
||||
pDistInfo->numOfFiles += p1.numOfFiles;
|
||||
|
||||
pDistInfo->defMinRows = p1.defMinRows;
|
||||
pDistInfo->defMaxRows = p1.defMaxRows;
|
||||
pDistInfo->rowSize = p1.rowSize;
|
||||
pDistInfo->numOfSmallBlocks = p1.numOfSmallBlocks;
|
||||
|
||||
if (pDistInfo->minRows > p1.minRows) {
|
||||
pDistInfo->minRows = p1.minRows;
|
||||
}
|
||||
|
@ -5031,7 +4969,7 @@ int32_t blockDistFunction(SqlFunctionCtx* pCtx) {
|
|||
pDistInfo->blockRowsHisto[i] += p1.blockRowsHisto[i];
|
||||
}
|
||||
|
||||
pResInfo->numOfRes = 1;
|
||||
pResInfo->numOfRes = BLOCK_DIST_RESULT_ROWS; // default output rows
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -5043,7 +4981,7 @@ int32_t tSerializeBlockDistInfo(void* buf, int32_t bufLen, const STableBlockDist
|
|||
if (tEncodeU32(&encoder, pInfo->rowSize) < 0) return -1;
|
||||
|
||||
if (tEncodeU16(&encoder, pInfo->numOfFiles) < 0) return -1;
|
||||
if (tEncodeU32(&encoder, pInfo->rowSize) < 0) return -1;
|
||||
if (tEncodeU32(&encoder, pInfo->numOfBlocks) < 0) return -1;
|
||||
if (tEncodeU32(&encoder, pInfo->numOfTables) < 0) return -1;
|
||||
|
||||
if (tEncodeU64(&encoder, pInfo->totalSize) < 0) return -1;
|
||||
|
@ -5074,7 +5012,7 @@ int32_t tDeserializeBlockDistInfo(void* buf, int32_t bufLen, STableBlockDistInfo
|
|||
if (tDecodeU32(&decoder, &pInfo->rowSize) < 0) return -1;
|
||||
|
||||
if (tDecodeU16(&decoder, &pInfo->numOfFiles) < 0) return -1;
|
||||
if (tDecodeU32(&decoder, &pInfo->rowSize) < 0) return -1;
|
||||
if (tDecodeU32(&decoder, &pInfo->numOfBlocks) < 0) return -1;
|
||||
if (tDecodeU32(&decoder, &pInfo->numOfTables) < 0) return -1;
|
||||
|
||||
if (tDecodeU64(&decoder, &pInfo->totalSize) < 0) return -1;
|
||||
|
@ -5096,32 +5034,29 @@ int32_t tDeserializeBlockDistInfo(void* buf, int32_t bufLen, STableBlockDistInfo
|
|||
|
||||
int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
char* pData = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
STableBlockDistInfo* pData = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
|
||||
int32_t row = 0;
|
||||
|
||||
STableBlockDistInfo info = {0};
|
||||
tDeserializeBlockDistInfo(varDataVal(pData), varDataLen(pData), &info);
|
||||
|
||||
char st[256] = {0};
|
||||
double totalRawSize = pData->totalRows * pData->rowSize;
|
||||
int32_t len =
|
||||
sprintf(st + VARSTR_HEADER_SIZE, "Blocks=[%d] Size=[%.3fKb] Average_Block_size=[%.3fKb] Compression_Ratio=[%.3f]",
|
||||
info.numOfBlocks, info.totalSize / 1024.0, info.totalSize / (info.numOfBlocks * 1024.0),
|
||||
info.totalSize / (info.totalRows * info.rowSize * 1.0));
|
||||
sprintf(st + VARSTR_HEADER_SIZE, "Total_Blocks=[%d] Total_Size=[%.2f Kb] Average_size=[%.2f Kb] Compression_Ratio=[%.2f %c]",
|
||||
pData->numOfBlocks, pData->totalSize / 1024.0, ((double)pData->totalSize) / pData->numOfBlocks,
|
||||
pData->totalSize * 100 / totalRawSize, '%');
|
||||
|
||||
varDataSetLen(st, len);
|
||||
colDataAppend(pColInfo, row++, st, false);
|
||||
|
||||
len = sprintf(st + VARSTR_HEADER_SIZE, "Total_Rows=[%ld] MinRows=[%d] MaxRows=[%d] Averge_Rows=[%ld] Inmem_Rows=[%d]",
|
||||
info.totalRows, info.minRows, info.maxRows, info.totalRows / info.numOfBlocks, info.numOfInmemRows);
|
||||
len = sprintf(st + VARSTR_HEADER_SIZE, "Total_Rows=[%"PRId64"] Inmem_Rows=[%d] MinRows=[%d] MaxRows=[%d] Average_Rows=[%"PRId64"]",
|
||||
pData->totalRows, pData->numOfInmemRows, pData->minRows, pData->maxRows, pData->totalRows / pData->numOfBlocks);
|
||||
|
||||
varDataSetLen(st, len);
|
||||
colDataAppend(pColInfo, row++, st, false);
|
||||
|
||||
len = sprintf(st + VARSTR_HEADER_SIZE, "Total_Tables=[%d] Total_Files=[%d] Total_Vgroups=[%d]", info.numOfTables,
|
||||
info.numOfFiles, 0);
|
||||
len = sprintf(st + VARSTR_HEADER_SIZE, "Total_Tables=[%d] Total_Files=[%d] Total_Vgroups=[%d]", pData->numOfTables,
|
||||
pData->numOfFiles, 0);
|
||||
|
||||
varDataSetLen(st, len);
|
||||
colDataAppend(pColInfo, row++, st, false);
|
||||
|
@ -5133,40 +5068,56 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
|
||||
int32_t maxVal = 0;
|
||||
int32_t minVal = INT32_MAX;
|
||||
for (int32_t i = 0; i < sizeof(info.blockRowsHisto) / sizeof(info.blockRowsHisto[0]); ++i) {
|
||||
if (maxVal < info.blockRowsHisto[i]) {
|
||||
maxVal = info.blockRowsHisto[i];
|
||||
for (int32_t i = 0; i < tListLen(pData->blockRowsHisto); ++i) {
|
||||
if (maxVal < pData->blockRowsHisto[i]) {
|
||||
maxVal = pData->blockRowsHisto[i];
|
||||
}
|
||||
|
||||
if (minVal > info.blockRowsHisto[i]) {
|
||||
minVal = info.blockRowsHisto[i];
|
||||
if (minVal > pData->blockRowsHisto[i]) {
|
||||
minVal = pData->blockRowsHisto[i];
|
||||
}
|
||||
}
|
||||
|
||||
int32_t delta = maxVal - minVal;
|
||||
int32_t step = delta / 50;
|
||||
if (step == 0) {
|
||||
step = 1;
|
||||
}
|
||||
|
||||
int32_t numOfBuckets = sizeof(info.blockRowsHisto) / sizeof(info.blockRowsHisto[0]);
|
||||
int32_t bucketRange = (info.maxRows - info.minRows) / numOfBuckets;
|
||||
int32_t numOfBuckets = sizeof(pData->blockRowsHisto) / sizeof(pData->blockRowsHisto[0]);
|
||||
int32_t bucketRange = (pData->maxRows - pData->minRows) / numOfBuckets;
|
||||
|
||||
for (int32_t i = 0; i < 20; ++i) {
|
||||
len += sprintf(st + VARSTR_HEADER_SIZE, "%04d |", info.defMinRows + bucketRange * (i + 1));
|
||||
bool singleModel = false;
|
||||
if (bucketRange == 0) {
|
||||
singleModel = true;
|
||||
step = 20;
|
||||
bucketRange = (pData->defMaxRows - pData->defMinRows) / numOfBuckets;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < tListLen(pData->blockRowsHisto); ++i) {
|
||||
len = sprintf(st + VARSTR_HEADER_SIZE, "%04d |", pData->defMinRows + bucketRange * (i + 1));
|
||||
|
||||
int32_t num = 0;
|
||||
if (singleModel && pData->blockRowsHisto[i] > 0) {
|
||||
num = 20;
|
||||
} else {
|
||||
num = (pData->blockRowsHisto[i] + step - 1) / step;
|
||||
}
|
||||
|
||||
int32_t num = (info.blockRowsHisto[i] + step - 1) / step;
|
||||
for (int32_t j = 0; j < num; ++j) {
|
||||
int32_t x = sprintf(st + VARSTR_HEADER_SIZE + len, "%c", '|');
|
||||
len += x;
|
||||
}
|
||||
|
||||
double v = info.blockRowsHisto[i] * 100.0 / info.numOfBlocks;
|
||||
len += sprintf(st + VARSTR_HEADER_SIZE + len, " %d (%.3f%c)", info.blockRowsHisto[i], v, '%');
|
||||
double v = pData->blockRowsHisto[i] * 100.0 / pData->numOfBlocks;
|
||||
len += sprintf(st + VARSTR_HEADER_SIZE + len, " %d (%.2f%c)", pData->blockRowsHisto[i], v, '%');
|
||||
printf("%s\n", st);
|
||||
|
||||
varDataSetLen(st, len);
|
||||
colDataAppend(pColInfo, row++, st, false);
|
||||
}
|
||||
|
||||
return row;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct SDerivInfo {
|
||||
|
@ -5362,4 +5313,4 @@ int32_t interpFunction(SqlFunctionCtx* pCtx) {
|
|||
#endif
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -972,6 +972,11 @@ void releaseUdfFuncHandle(char* udfName) {
|
|||
}
|
||||
|
||||
int32_t cleanUpUdfs() {
|
||||
int8_t initialized = atomic_load_8(&gUdfdProxy.initialized);
|
||||
if (!initialized) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
uv_mutex_lock(&gUdfdProxy.udfStubsMutex);
|
||||
int32_t i = 0;
|
||||
SArray* udfStubs = taosArrayInit(16, sizeof(SUdfcFuncStub));
|
||||
|
|
|
@ -464,6 +464,9 @@ static SNode* logicInterpFuncCopy(const SInterpFuncLogicNode* pSrc, SInterpFuncL
|
|||
CLONE_NODE_LIST_FIELD(pFuncs);
|
||||
COPY_OBJECT_FIELD(timeRange, sizeof(STimeWindow));
|
||||
COPY_SCALAR_FIELD(interval);
|
||||
COPY_SCALAR_FIELD(fillMode);
|
||||
CLONE_NODE_FIELD(pFillValues);
|
||||
CLONE_NODE_FIELD(pTimeSeries);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
|
|
|
@ -2133,6 +2133,9 @@ static const char* jkInterpFuncPhysiPlanFuncs = "Funcs";
|
|||
static const char* jkInterpFuncPhysiPlanStartTime = "StartTime";
|
||||
static const char* jkInterpFuncPhysiPlanEndTime = "EndTime";
|
||||
static const char* jkInterpFuncPhysiPlanInterval = "Interval";
|
||||
static const char* jkInterpFuncPhysiPlanFillMode = "FillMode";
|
||||
static const char* jkInterpFuncPhysiPlanFillValues = "FillValues";
|
||||
static const char* jkInterpFuncPhysiPlanTimeSeries = "TimeSeries";
|
||||
|
||||
static int32_t physiInterpFuncNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SInterpFuncPhysiNode* pNode = (const SInterpFuncPhysiNode*)pObj;
|
||||
|
@ -2153,6 +2156,15 @@ static int32_t physiInterpFuncNodeToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkInterpFuncPhysiPlanInterval, pNode->interval);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkInterpFuncPhysiPlanFillMode, pNode->fillMode);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkInterpFuncPhysiPlanFillValues, nodeToJson, pNode->pFillValues);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkInterpFuncPhysiPlanTimeSeries, nodeToJson, pNode->pTimeSeries);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -2176,6 +2188,15 @@ static int32_t jsonToPhysiInterpFuncNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkInterpFuncPhysiPlanInterval, &pNode->interval);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
tjsonGetNumberValue(pJson, jkInterpFuncPhysiPlanFillMode, pNode->fillMode, code);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkInterpFuncPhysiPlanFillValues, &pNode->pFillValues);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkInterpFuncPhysiPlanTimeSeries, &pNode->pTimeSeries);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -700,8 +700,11 @@ SNode* addEveryClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pEvery) {
|
|||
|
||||
SNode* addFillClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pFill) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
|
||||
((SSelectStmt*)pStmt)->pFill = pFill;
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(pStmt) && NULL != pFill) {
|
||||
SFillNode* pFillClause = (SFillNode*)pFill;
|
||||
nodesDestroyNode(pFillClause->pWStartTs);
|
||||
pFillClause->pWStartTs = createPrimaryKeyCol(pCxt);
|
||||
((SSelectStmt*)pStmt)->pFill = (SNode*)pFillClause;
|
||||
}
|
||||
return pStmt;
|
||||
}
|
||||
|
@ -909,7 +912,7 @@ SNode* createDefaultTableOptions(SAstCreateContext* pCxt) {
|
|||
pOptions->watermark1 = TSDB_DEFAULT_ROLLUP_WATERMARK;
|
||||
pOptions->watermark2 = TSDB_DEFAULT_ROLLUP_WATERMARK;
|
||||
pOptions->ttl = TSDB_DEFAULT_TABLE_TTL;
|
||||
pOptions->commentNull = true; // mark null
|
||||
pOptions->commentNull = true; // mark null
|
||||
return (SNode*)pOptions;
|
||||
}
|
||||
|
||||
|
@ -918,7 +921,7 @@ SNode* createAlterTableOptions(SAstCreateContext* pCxt) {
|
|||
STableOptions* pOptions = (STableOptions*)nodesMakeNode(QUERY_NODE_TABLE_OPTIONS);
|
||||
CHECK_OUT_OF_MEM(pOptions);
|
||||
pOptions->ttl = -1;
|
||||
pOptions->commentNull = true; // mark null
|
||||
pOptions->commentNull = true; // mark null
|
||||
return (SNode*)pOptions;
|
||||
}
|
||||
|
||||
|
@ -940,9 +943,9 @@ SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType
|
|||
case TABLE_OPTION_ROLLUP:
|
||||
((STableOptions*)pOptions)->pRollupFuncs = pVal;
|
||||
break;
|
||||
case TABLE_OPTION_TTL:{
|
||||
case TABLE_OPTION_TTL: {
|
||||
int64_t ttl = taosStr2Int64(((SToken*)pVal)->z, NULL, 10);
|
||||
if (ttl > INT32_MAX){
|
||||
if (ttl > INT32_MAX) {
|
||||
ttl = INT32_MAX;
|
||||
}
|
||||
// ttl can not be smaller than 0, because there is a limitation in sql.y (TTL NK_INTEGER)
|
||||
|
|
|
@ -419,6 +419,24 @@ static int32_t collectMetaKeyFromDelete(SCollectMetaKeyCxt* pCxt, SDeleteStmt* p
|
|||
return collectMetaKeyFromRealTableImpl(pCxt, (SRealTableNode*)pStmt->pFromTable, AUTH_TYPE_WRITE);
|
||||
}
|
||||
|
||||
static int32_t collectMetaKeyFromShowBlockDist(SCollectMetaKeyCxt* pCxt, SShowTableDistributedStmt* pStmt) {
|
||||
SName name = {.type = TSDB_TABLE_NAME_T, .acctId = pCxt->pParseCxt->acctId};
|
||||
strcpy(name.dbname, pStmt->dbName);
|
||||
strcpy(name.tname, pStmt->tableName);
|
||||
int32_t code = catalogRemoveTableMeta(pCxt->pParseCxt->pCatalog, &name);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = reserveDbVgInfoInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
|
||||
pCxt->pStmt = pStmt;
|
||||
switch (nodeType(pStmt)) {
|
||||
|
@ -497,6 +515,8 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
|
|||
return collectMetaKeyFromShowTransactions(pCxt, (SShowStmt*)pStmt);
|
||||
case QUERY_NODE_DELETE_STMT:
|
||||
return collectMetaKeyFromDelete(pCxt, (SDeleteStmt*)pStmt);
|
||||
case QUERY_NODE_SHOW_TABLE_DISTRIBUTED_STMT:
|
||||
return collectMetaKeyFromShowBlockDist(pCxt, (SShowTableDistributedStmt*)pStmt);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1932,26 +1932,33 @@ static int32_t getFillTimeRange(STranslateContext* pCxt, SNode* pWhere, STimeWin
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t checkFill(STranslateContext* pCxt, SIntervalWindowNode* pInterval) {
|
||||
SFillNode* pFill = (SFillNode*)pInterval->pFill;
|
||||
static int32_t checkFill(STranslateContext* pCxt, SFillNode* pFill, SValueNode* pInterval) {
|
||||
if (FILL_MODE_NONE == pFill->mode) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (TSWINDOW_IS_EQUAL(pFill->timeRange, TSWINDOW_INITIALIZER) ||
|
||||
TSWINDOW_IS_EQUAL(pFill->timeRange, TSWINDOW_DESC_INITIALIZER)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE);
|
||||
}
|
||||
|
||||
int64_t timeRange = TABS(pFill->timeRange.skey - pFill->timeRange.ekey);
|
||||
int64_t intervalRange = 0;
|
||||
SValueNode* pInter = (SValueNode*)pInterval->pInterval;
|
||||
if (TIME_IS_VAR_DURATION(pInter->unit)) {
|
||||
// interp FILL clause
|
||||
if (NULL == pInterval) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t timeRange = TABS(pFill->timeRange.skey - pFill->timeRange.ekey);
|
||||
int64_t intervalRange = 0;
|
||||
if (TIME_IS_VAR_DURATION(pInterval->unit)) {
|
||||
int64_t f = 1;
|
||||
if (pInter->unit == 'n') {
|
||||
if (pInterval->unit == 'n') {
|
||||
f = 30L * MILLISECOND_PER_DAY;
|
||||
} else if (pInter->unit == 'y') {
|
||||
} else if (pInterval->unit == 'y') {
|
||||
f = 365L * MILLISECOND_PER_DAY;
|
||||
}
|
||||
intervalRange = pInter->datum.i * f;
|
||||
intervalRange = pInterval->datum.i * f;
|
||||
} else {
|
||||
intervalRange = pInter->datum.i;
|
||||
intervalRange = pInterval->datum.i;
|
||||
}
|
||||
if ((timeRange == 0) || (timeRange / intervalRange) >= MAX_INTERVAL_TIME_WINDOW) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE);
|
||||
|
@ -1967,7 +1974,7 @@ static int32_t translateFill(STranslateContext* pCxt, SNode* pWhere, SIntervalWi
|
|||
|
||||
int32_t code = getFillTimeRange(pCxt, pWhere, &(((SFillNode*)pInterval->pFill)->timeRange));
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkFill(pCxt, pInterval);
|
||||
code = checkFill(pCxt, (SFillNode*)pInterval->pFill, (SValueNode*)pInterval->pInterval);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
@ -2109,6 +2116,64 @@ static int32_t translateWindow(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t createDefaultFillNode(STranslateContext* pCxt, SNode** pOutput) {
|
||||
SFillNode* pFill = (SFillNode*)nodesMakeNode(QUERY_NODE_FILL);
|
||||
if (NULL == pFill) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pFill->mode = FILL_MODE_NONE;
|
||||
|
||||
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
if (NULL == pCol) {
|
||||
nodesDestroyNode((SNode*)pFill);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
strcpy(pCol->colName, PK_TS_COL_INTERNAL_NAME);
|
||||
pFill->pWStartTs = (SNode*)pCol;
|
||||
|
||||
*pOutput = (SNode*)pFill;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateInterpFill(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
if (NULL == pSelect->pFill) {
|
||||
code = createDefaultFillNode(pCxt, &pSelect->pFill);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateExpr(pCxt, &pSelect->pFill);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = getFillTimeRange(pCxt, pSelect->pRange, &(((SFillNode*)pSelect->pFill)->timeRange));
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkFill(pCxt, (SFillNode*)pSelect->pFill, (SValueNode*)pSelect->pEvery);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t translateInterp(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (!pSelect->hasInterpFunc) {
|
||||
if (NULL != pSelect->pRange || NULL != pSelect->pEvery || NULL != pSelect->pFill) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_INTERP_CLAUSE);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t code = translateExpr(pCxt, &pSelect->pRange);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateExpr(pCxt, &pSelect->pEvery);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateInterpFill(pCxt, pSelect);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t translatePartitionBy(STranslateContext* pCxt, SNodeList* pPartitionByList) {
|
||||
pCxt->currClause = SQL_CLAUSE_PARTITION_BY;
|
||||
return translateExprList(pCxt, pPartitionByList);
|
||||
|
@ -2378,6 +2443,9 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkLimit(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = translateInterp(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = rewriteUniqueStmt(pCxt, pSelect);
|
||||
}
|
||||
|
@ -3388,18 +3456,18 @@ static int32_t buildCreateStbReq(STranslateContext* pCxt, SCreateTableStmt* pStm
|
|||
pReq->delay2 = pStmt->pOptions->maxDelay2;
|
||||
pReq->watermark1 = pStmt->pOptions->watermark1;
|
||||
pReq->watermark2 = pStmt->pOptions->watermark2;
|
||||
// pReq->ttl = pStmt->pOptions->ttl;
|
||||
// pReq->ttl = pStmt->pOptions->ttl;
|
||||
columnDefNodeToField(pStmt->pCols, &pReq->pColumns);
|
||||
columnDefNodeToField(pStmt->pTags, &pReq->pTags);
|
||||
pReq->numOfColumns = LIST_LENGTH(pStmt->pCols);
|
||||
pReq->numOfTags = LIST_LENGTH(pStmt->pTags);
|
||||
if(pStmt->pOptions->commentNull == false){
|
||||
if (pStmt->pOptions->commentNull == false) {
|
||||
pReq->comment = strdup(pStmt->pOptions->comment);
|
||||
if (NULL == pReq->comment) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pReq->commentLen = strlen(pStmt->pOptions->comment);
|
||||
}else{
|
||||
} else {
|
||||
pReq->commentLen = -1;
|
||||
}
|
||||
|
||||
|
@ -3452,14 +3520,14 @@ static int32_t buildAlterSuperTableReq(STranslateContext* pCxt, SAlterTableStmt*
|
|||
pAlterReq->alterType = pStmt->alterType;
|
||||
|
||||
if (TSDB_ALTER_TABLE_UPDATE_OPTIONS == pStmt->alterType) {
|
||||
// pAlterReq->ttl = pStmt->pOptions->ttl;
|
||||
// pAlterReq->ttl = pStmt->pOptions->ttl;
|
||||
if (pStmt->pOptions->commentNull == false) {
|
||||
pAlterReq->comment = strdup(pStmt->pOptions->comment);
|
||||
if (NULL == pAlterReq->comment) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pAlterReq->commentLen = strlen(pStmt->pOptions->comment);
|
||||
}else{
|
||||
} else {
|
||||
pAlterReq->commentLen = -1;
|
||||
}
|
||||
|
||||
|
@ -4725,7 +4793,7 @@ static int32_t buildNormalTableBatchReq(int32_t acctId, const SCreateTableStmt*
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
req.commentLen = strlen(pStmt->pOptions->comment);
|
||||
}else{
|
||||
} else {
|
||||
req.commentLen = -1;
|
||||
}
|
||||
req.ntb.schemaRow.nCols = LIST_LENGTH(pStmt->pCols);
|
||||
|
@ -4878,11 +4946,11 @@ static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, S
|
|||
struct SVCreateTbReq req = {0};
|
||||
req.type = TD_CHILD_TABLE;
|
||||
req.name = strdup(pStmt->tableName);
|
||||
req.ttl = pStmt->pOptions->ttl;
|
||||
req.ttl = pStmt->pOptions->ttl;
|
||||
if (pStmt->pOptions->commentNull == false) {
|
||||
req.comment = strdup(pStmt->pOptions->comment);
|
||||
req.commentLen = strlen(pStmt->pOptions->comment);
|
||||
} else{
|
||||
} else {
|
||||
req.commentLen = -1;
|
||||
}
|
||||
req.ctb.suid = suid;
|
||||
|
@ -5460,15 +5528,14 @@ static int32_t buildUpdateOptionsReq(STranslateContext* pCxt, SAlterTableStmt* p
|
|||
pReq->newTTL = pStmt->pOptions->ttl;
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code){
|
||||
if(pStmt->pOptions->commentNull == false) {
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (pStmt->pOptions->commentNull == false) {
|
||||
pReq->newComment = strdup(pStmt->pOptions->comment);
|
||||
if (NULL == pReq->newComment) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pReq->newCommentLen = strlen(pReq->newComment);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
pReq->newCommentLen = -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,6 +196,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
|||
return "%s function does not supportted in group query";
|
||||
case TSDB_CODE_PAR_INVALID_TABLE_OPTION:
|
||||
return "Invalid option %s";
|
||||
case TSDB_CODE_PAR_INVALID_INTERP_CLAUSE:
|
||||
return "Invalid usage of RANGE clause, EVERY clause or FILL clause";
|
||||
case TSDB_CODE_OUT_OF_MEMORY:
|
||||
return "Out of memory";
|
||||
default:
|
||||
|
|
|
@ -267,8 +267,6 @@ TEST_F(ParserSelectTest, interp) {
|
|||
|
||||
run("SELECT INTERP(c1) FROM t1 EVERY(5s)");
|
||||
|
||||
run("SELECT INTERP(c1) FROM t1 EVERY(5s) FILL(LINEAR)");
|
||||
|
||||
run("SELECT INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00') EVERY(5s)");
|
||||
|
||||
run("SELECT INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR)");
|
||||
|
|
|
@ -508,10 +508,15 @@ static int32_t createInterpFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* p
|
|||
code = rewriteExprsForSelect(pInterpFunc->pFuncs, pSelect, SQL_CLAUSE_SELECT);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pRange) {
|
||||
// SRangeNode* pRange = (SRangeNode*)pSelect->pRange;
|
||||
// pInterpFunc->timeRange.skey = ((SValueNode*)pRange->pStart)->datum.i;
|
||||
// pInterpFunc->timeRange.ekey = ((SValueNode*)pRange->pEnd)->datum.i;
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pFill) {
|
||||
SFillNode* pFill = (SFillNode*)pSelect->pFill;
|
||||
pInterpFunc->timeRange = pFill->timeRange;
|
||||
pInterpFunc->fillMode = pFill->mode;
|
||||
pInterpFunc->pTimeSeries = nodesCloneNode(pFill->pWStartTs);
|
||||
pInterpFunc->pFillValues = nodesCloneNode(pFill->pValues);
|
||||
if (NULL == pInterpFunc->pTimeSeries || (NULL != pFill->pValues && NULL == pInterpFunc->pFillValues)) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pEvery) {
|
||||
|
|
|
@ -1082,13 +1082,89 @@ static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
|
|||
return code;
|
||||
}
|
||||
|
||||
static bool eliminateProjOptMayBeOptimized(SLogicNode* pNode) {
|
||||
//TODO: enable this optimization after new mechanising that map projection and targets of project node
|
||||
if (NULL != pNode->pParent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SProjectLogicNode* pProjectNode = (SProjectLogicNode*)pNode;
|
||||
if (-1 != pProjectNode->limit || -1 != pProjectNode->slimit || -1 != pProjectNode->offset || -1 != pProjectNode->soffset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SHashObj* pProjColNameHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
|
||||
SNode* pProjection;
|
||||
FOREACH(pProjection, pProjectNode->pProjections) {
|
||||
SExprNode* pExprNode = (SExprNode*)pProjection;
|
||||
if (QUERY_NODE_COLUMN != nodeType(pExprNode)) {
|
||||
taosHashCleanup(pProjColNameHash);
|
||||
return false;
|
||||
}
|
||||
|
||||
char* projColumnName = ((SColumnNode*)pProjection)->colName;
|
||||
int32_t* pExist = taosHashGet(pProjColNameHash, projColumnName, strlen(projColumnName));
|
||||
if (NULL != pExist) {
|
||||
taosHashCleanup(pProjColNameHash);
|
||||
return false;
|
||||
} else {
|
||||
int32_t exist = 1;
|
||||
taosHashPut(pProjColNameHash, projColumnName, strlen(projColumnName), &exist, sizeof(exist));
|
||||
}
|
||||
}
|
||||
taosHashCleanup(pProjColNameHash);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t eliminateProjOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SProjectLogicNode* pProjectNode) {
|
||||
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pProjectNode->node.pChildren, 0);
|
||||
SNodeList* pNewChildTargets = nodesMakeList();
|
||||
|
||||
SNode* pProjection = NULL;
|
||||
FOREACH(pProjection, pProjectNode->pProjections) {
|
||||
SNode* pChildTarget = NULL;
|
||||
FOREACH(pChildTarget, pChild->pTargets) {
|
||||
if (strcmp(((SColumnNode*)pProjection)->colName, ((SColumnNode*)pChildTarget)->colName) == 0) {
|
||||
nodesListAppend(pNewChildTargets, nodesCloneNode(pChildTarget));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
nodesDestroyList(pChild->pTargets);
|
||||
pChild->pTargets = pNewChildTargets;
|
||||
|
||||
int32_t code = replaceLogicNode(pLogicSubplan, (SLogicNode*)pProjectNode, pChild);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
NODES_CLEAR_LIST(pProjectNode->node.pChildren);
|
||||
nodesDestroyNode((SNode*)pProjectNode);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t eliminateProjOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||
SProjectLogicNode* pProjectNode =
|
||||
(SProjectLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, eliminateProjOptMayBeOptimized);
|
||||
|
||||
if (NULL == pProjectNode) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
return eliminateProjOptimizeImpl(pCxt, pLogicSubplan, pProjectNode);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static const SOptimizeRule optimizeRuleSet[] = {
|
||||
{.pName = "OptimizeScanData", .optimizeFunc = osdOptimize},
|
||||
{.pName = "ConditionPushDown", .optimizeFunc = cpdOptimize},
|
||||
{.pName = "OrderByPrimaryKey", .optimizeFunc = opkOptimize},
|
||||
{.pName = "SmaIndex", .optimizeFunc = smaOptimize},
|
||||
{.pName = "PartitionByTags", .optimizeFunc = partTagsOptimize}
|
||||
{.pName = "PartitionByTags", .optimizeFunc = partTagsOptimize},
|
||||
{.pName = "EliminateProject", .optimizeFunc = eliminateProjOptimize}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
|
|
@ -877,6 +877,12 @@ static int32_t createInterpFuncPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pCh
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pInterpFunc->timeRange = pFuncLogicNode->timeRange;
|
||||
pInterpFunc->interval = pFuncLogicNode->interval;
|
||||
pInterpFunc->fillMode = pFuncLogicNode->fillMode;
|
||||
pInterpFunc->pFillValues = nodesCloneNode(pFuncLogicNode->pFillValues);
|
||||
pInterpFunc->pTimeSeries = nodesCloneNode(pFuncLogicNode->pTimeSeries);
|
||||
if (NULL == pInterpFunc->pTimeSeries || (NULL != pFuncLogicNode->pFillValues && NULL == pInterpFunc->pFillValues)) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
|
@ -107,6 +107,7 @@ int32_t createColumnByRewriteExpr(SNode* pExpr, SNodeList** pList) {
|
|||
int32_t replaceLogicNode(SLogicSubplan* pSubplan, SLogicNode* pOld, SLogicNode* pNew) {
|
||||
if (NULL == pOld->pParent) {
|
||||
pSubplan->pNode = (SLogicNode*)pNew;
|
||||
pNew->pParent = NULL;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,3 +52,13 @@ TEST_F(PlanOptimizeTest, orderByPrimaryKey) {
|
|||
|
||||
run("SELECT COUNT(*) FROM t1 INTERVAL(10S) ORDER BY _WSTARTTS DESC");
|
||||
}
|
||||
|
||||
TEST_F(PlanOptimizeTest, eliminateProjection) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT c1, sum(c3) FROM t1 GROUP BY c1");
|
||||
run("SELECT c1 FROM t1");
|
||||
run("SELECT * FROM st1");
|
||||
run("SELECT c1 FROM st1s3");
|
||||
//run("select 1-abs(c1) from (select unique(c1) c1 from st1s3) order by 1 nulls first");
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include "qwInt.h"
|
||||
#include "dataSinkMgt.h"
|
||||
|
||||
int32_t qwAbortPrerocessQuery(QW_FPARAMS_DEF);
|
||||
int32_t qwPrerocessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg);
|
||||
int32_t qwProcessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg, int8_t taskType, int8_t explain, const char* sql);
|
||||
int32_t qwProcessCQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg);
|
||||
|
|
|
@ -283,6 +283,26 @@ int32_t qWorkerPreprocessQueryMsg(void *qWorkerMgmt, SRpcMsg *pMsg) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qWorkerAbortPreprocessQueryMsg(void *qWorkerMgmt, SRpcMsg *pMsg) {
|
||||
if (NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SSubQueryMsg *msg = pMsg->pCont;
|
||||
SQWorker * mgmt = (SQWorker *)qWorkerMgmt;
|
||||
|
||||
uint64_t sId = msg->sId;
|
||||
uint64_t qId = msg->queryId;
|
||||
uint64_t tId = msg->taskId;
|
||||
int64_t rId = msg->refId;
|
||||
|
||||
QW_SCH_TASK_DLOG("Abort prerocessQuery start, handle:%p", pMsg->info.handle);
|
||||
qwAbortPrerocessQuery(QW_FPARAMS());
|
||||
QW_SCH_TASK_DLOG("Abort prerocessQuery end, handle:%p", pMsg->info.handle);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, int64_t ts) {
|
||||
if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) {
|
||||
QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
|
|
|
@ -482,6 +482,13 @@ _return:
|
|||
QW_RET(code);
|
||||
}
|
||||
|
||||
int32_t qwAbortPrerocessQuery(QW_FPARAMS_DEF) {
|
||||
QW_ERR_RET(qwDropTask(QW_FPARAMS()));
|
||||
|
||||
QW_RET(TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
int32_t qwPrerocessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg) {
|
||||
int32_t code = 0;
|
||||
bool queryRsped = false;
|
||||
|
@ -526,7 +533,7 @@ int32_t qwProcessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg, int8_t taskType, int8_t ex
|
|||
atomic_store_8(&ctx->taskType, taskType);
|
||||
atomic_store_8(&ctx->explain, explain);
|
||||
|
||||
/*QW_TASK_DLOGL("subplan json string, len:%d, %s", qwMsg->msgLen, qwMsg->msg);*/
|
||||
QW_TASK_DLOGL("subplan json string, len:%d, %s", qwMsg->msgLen, qwMsg->msg);
|
||||
|
||||
code = qStringToSubplan(qwMsg->msg, &plan);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
|
|
|
@ -36,11 +36,11 @@ int32_t tEncodeSStreamTask(SEncoder* pEncoder, const SStreamTask* pTask) {
|
|||
if (tEncodeI32(pEncoder, pTask->taskId) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pTask->inputType) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pTask->status) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pTask->sourceType) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pTask->execType) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pTask->sinkType) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pTask->dispatchType) < 0) return -1;
|
||||
if (tEncodeI16(pEncoder, pTask->dispatchMsgType) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pTask->dataScan) < 0) return -1;
|
||||
|
||||
if (tEncodeI32(pEncoder, pTask->childId) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pTask->nodeId) < 0) return -1;
|
||||
|
@ -84,11 +84,11 @@ int32_t tDecodeSStreamTask(SDecoder* pDecoder, SStreamTask* pTask) {
|
|||
if (tDecodeI32(pDecoder, &pTask->taskId) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pTask->inputType) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pTask->status) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pTask->sourceType) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pTask->execType) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pTask->sinkType) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pTask->dispatchType) < 0) return -1;
|
||||
if (tDecodeI16(pDecoder, &pTask->dispatchMsgType) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pTask->dataScan) < 0) return -1;
|
||||
|
||||
if (tDecodeI32(pDecoder, &pTask->childId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pTask->nodeId) < 0) return -1;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#define TDB_BTREE_ROOT 0x1
|
||||
#define TDB_BTREE_LEAF 0x2
|
||||
#define TDB_BTREE_OVFL 0x4
|
||||
|
||||
struct SBTree {
|
||||
SPgno root;
|
||||
|
@ -38,9 +39,11 @@ struct SBTree {
|
|||
#define TDB_BTREE_PAGE_SET_FLAGS(PAGE, flags) ((PAGE)->pData[0] = (flags))
|
||||
#define TDB_BTREE_PAGE_IS_ROOT(PAGE) (TDB_BTREE_PAGE_GET_FLAGS(PAGE) & TDB_BTREE_ROOT)
|
||||
#define TDB_BTREE_PAGE_IS_LEAF(PAGE) (TDB_BTREE_PAGE_GET_FLAGS(PAGE) & TDB_BTREE_LEAF)
|
||||
#define TDB_BTREE_PAGE_IS_OVFL(PAGE) (TDB_BTREE_PAGE_GET_FLAGS(PAGE) & TDB_BTREE_OVFL)
|
||||
#define TDB_BTREE_ASSERT_FLAG(flags) \
|
||||
ASSERT(TDB_FLAG_IS(flags, TDB_BTREE_ROOT) || TDB_FLAG_IS(flags, TDB_BTREE_LEAF) || \
|
||||
TDB_FLAG_IS(flags, TDB_BTREE_ROOT | TDB_BTREE_LEAF) || TDB_FLAG_IS(flags, 0))
|
||||
TDB_FLAG_IS(flags, TDB_BTREE_ROOT | TDB_BTREE_LEAF) || TDB_FLAG_IS(flags, 0) || \
|
||||
TDB_FLAG_IS(flags, TDB_BTREE_OVFL))
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
|
@ -62,10 +65,10 @@ static int tdbDefaultKeyCmprFn(const void *pKey1, int keyLen1, const void *pKey2
|
|||
static int tdbBtreeOpenImpl(SBTree *pBt);
|
||||
static int tdbBtreeInitPage(SPage *pPage, void *arg, int init);
|
||||
static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const void *pVal, int vLen, SCell *pCell,
|
||||
int *szCell);
|
||||
static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pDecoder);
|
||||
int *szCell, TXN *pTxn, SBTree *pBt);
|
||||
static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pDecoder, TXN *pTxn, SBTree *pBt);
|
||||
static int tdbBtreeBalance(SBTC *pBtc);
|
||||
static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell);
|
||||
static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell, int dropOfp, TXN *pTxn, SBTree *pBt);
|
||||
static int tdbBtcMoveDownward(SBTC *pBtc);
|
||||
static int tdbBtcMoveUpward(SBTC *pBtc);
|
||||
|
||||
|
@ -255,7 +258,7 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
|
|||
}
|
||||
|
||||
pCell = tdbPageGetCell(btc.pPage, btc.idx);
|
||||
tdbBtreeDecodeCell(btc.pPage, pCell, &cd);
|
||||
tdbBtreeDecodeCell(btc.pPage, pCell, &cd, btc.pTxn, pBt);
|
||||
|
||||
if (ppKey) {
|
||||
pTKey = tdbRealloc(*ppKey, cd.kLen);
|
||||
|
@ -281,6 +284,14 @@ int tdbBtreePGet(SBTree *pBt, const void *pKey, int kLen, void **ppKey, int *pkL
|
|||
memcpy(*ppVal, cd.pVal, cd.vLen);
|
||||
}
|
||||
|
||||
if (TDB_CELLDECODER_FREE_KEY(&cd)) {
|
||||
tdbFree(cd.pKey);
|
||||
}
|
||||
|
||||
if (TDB_CELLDECODER_FREE_VAL(&cd)) {
|
||||
tdbFree(cd.pVal);
|
||||
}
|
||||
|
||||
tdbBtcClose(&btc);
|
||||
|
||||
return 0;
|
||||
|
@ -375,6 +386,11 @@ static int tdbBtreeInitPage(SPage *pPage, void *arg, int init) {
|
|||
pPage->vLen = pBt->valLen;
|
||||
pPage->maxLocal = pBt->maxLeaf;
|
||||
pPage->minLocal = pBt->minLeaf;
|
||||
} else if (TDB_BTREE_PAGE_IS_OVFL(pPage)) {
|
||||
pPage->kLen = pBt->keyLen;
|
||||
pPage->vLen = pBt->valLen;
|
||||
pPage->maxLocal = tdbPageCapacity(pBt->pageSize, sizeof(SIntHdr));
|
||||
pPage->minLocal = pBt->minLocal;
|
||||
} else {
|
||||
pPage->kLen = pBt->keyLen;
|
||||
pPage->vLen = sizeof(SPgno);
|
||||
|
@ -499,7 +515,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
for (int i = 0; i < nOlds; i++) {
|
||||
if (sIdx + i < TDB_PAGE_TOTAL_CELLS(pParent)) {
|
||||
pCell = tdbPageGetCell(pParent, sIdx + i);
|
||||
szDivCell[i] = tdbBtreeCellSize(pParent, pCell);
|
||||
szDivCell[i] = tdbBtreeCellSize(pParent, pCell, 0, NULL, NULL);
|
||||
pDivCell[i] = tdbOsMalloc(szDivCell[i]);
|
||||
memcpy(pDivCell[i], pCell, szDivCell[i]);
|
||||
}
|
||||
|
@ -524,7 +540,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
for (int i = 0; i < nOlds; i++) {
|
||||
nCells = TDB_PAGE_TOTAL_CELLS(pParent);
|
||||
if (sIdx < nCells) {
|
||||
tdbPageDropCell(pParent, sIdx);
|
||||
tdbPageDropCell(pParent, sIdx, pTxn, pBt);
|
||||
} else {
|
||||
((SIntHdr *)pParent->pData)->pgno = 0;
|
||||
}
|
||||
|
@ -582,7 +598,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
for (;;) {
|
||||
pCell = tdbPageGetCell(pOlds[infoNews[iNew - 1].iPage], infoNews[iNew - 1].oIdx);
|
||||
|
||||
szLCell = tdbBtreeCellSize(pOlds[infoNews[iNew - 1].iPage], pCell);
|
||||
szLCell = tdbBtreeCellSize(pOlds[infoNews[iNew - 1].iPage], pCell, 0, NULL, NULL);
|
||||
if (!childNotLeaf) {
|
||||
szRCell = szLCell;
|
||||
} else {
|
||||
|
@ -600,7 +616,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
}
|
||||
|
||||
pCell = tdbPageGetCell(pPage, oIdx);
|
||||
szRCell = tdbBtreeCellSize(pPage, pCell);
|
||||
szRCell = tdbBtreeCellSize(pPage, pCell, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
ASSERT(infoNews[iNew - 1].cnt > 0);
|
||||
|
@ -687,7 +703,7 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
|
||||
for (int oIdx = 0; oIdx < TDB_PAGE_TOTAL_CELLS(pPage); oIdx++) {
|
||||
pCell = tdbPageGetCell(pPage, oIdx);
|
||||
szCell = tdbBtreeCellSize(pPage, pCell);
|
||||
szCell = tdbBtreeCellSize(pPage, pCell, 0, NULL, NULL);
|
||||
|
||||
ASSERT(nNewCells <= infoNews[iNew].cnt);
|
||||
ASSERT(iNew < nNews);
|
||||
|
@ -703,14 +719,14 @@ static int tdbBtreeBalanceNonRoot(SBTree *pBt, SPage *pParent, int idx, TXN *pTx
|
|||
if (iNew == nNews - 1 && pIntHdr->pgno == 0) {
|
||||
pIntHdr->pgno = TDB_PAGE_PGNO(pNews[iNew]);
|
||||
} else {
|
||||
tdbBtreeDecodeCell(pPage, pCell, &cd);
|
||||
tdbBtreeDecodeCell(pPage, pCell, &cd, pTxn, pBt);
|
||||
|
||||
// TODO: pCell here may be inserted as an overflow cell, handle it
|
||||
SCell *pNewCell = tdbOsMalloc(cd.kLen + 9);
|
||||
int szNewCell;
|
||||
SPgno pgno;
|
||||
pgno = TDB_PAGE_PGNO(pNews[iNew]);
|
||||
tdbBtreeEncodeCell(pParent, cd.pKey, cd.kLen, (void *)&pgno, sizeof(SPgno), pNewCell, &szNewCell);
|
||||
tdbBtreeEncodeCell(pParent, cd.pKey, cd.kLen, (void *)&pgno, sizeof(SPgno), pNewCell, &szNewCell, pTxn, pBt);
|
||||
tdbPageInsertCell(pParent, sIdx++, pNewCell, szNewCell, 0);
|
||||
tdbOsFree(pNewCell);
|
||||
}
|
||||
|
@ -846,13 +862,50 @@ static int tdbBtreeBalance(SBTC *pBtc) {
|
|||
}
|
||||
// TDB_BTREE_BALANCE
|
||||
|
||||
static int tdbFetchOvflPage(SPager *pPager, SPgno *pPgno, SPage **ppOfp, TXN *pTxn, SBTree *pBt) {
|
||||
int ret = 0;
|
||||
|
||||
*pPgno = 0;
|
||||
SBtreeInitPageArg iArg;
|
||||
iArg.pBt = pBt;
|
||||
iArg.flags = TDB_FLAG_ADD(0, TDB_BTREE_OVFL);
|
||||
ret = tdbPagerFetchPage(pPager, pPgno, ppOfp, tdbBtreeInitPage, &iArg, pTxn);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// mark dirty
|
||||
ret = tdbPagerWrite(pPager, *ppOfp);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tdbLoadOvflPage(SPager *pPager, SPgno *pPgno, SPage **ppOfp, TXN *pTxn, SBTree *pBt) {
|
||||
int ret = 0;
|
||||
|
||||
SBtreeInitPageArg iArg;
|
||||
iArg.pBt = pBt;
|
||||
iArg.flags = TDB_FLAG_ADD(0, TDB_BTREE_OVFL);
|
||||
ret = tdbPagerFetchPage(pPager, pPgno, ppOfp, tdbBtreeInitPage, &iArg, pTxn);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TDB_BTREE_CELL =====================
|
||||
static int tdbBtreeEncodePayload(SPage *pPage, SCell *pCell, int nHeader, const void *pKey, int kLen, const void *pVal,
|
||||
int vLen, int *szPayload) {
|
||||
int nPayload;
|
||||
int vLen, int *szPayload, TXN *pTxn, SBTree *pBt) {
|
||||
int ret = 0;
|
||||
int nPayload = kLen + vLen;
|
||||
int maxLocal = pPage->maxLocal;
|
||||
|
||||
nPayload = kLen + vLen;
|
||||
if (nPayload + nHeader <= pPage->maxLocal) {
|
||||
if (nPayload + nHeader <= maxLocal) {
|
||||
// no overflow page is needed
|
||||
memcpy(pCell + nHeader, pKey, kLen);
|
||||
if (pVal) {
|
||||
|
@ -861,18 +914,190 @@ static int tdbBtreeEncodePayload(SPage *pPage, SCell *pCell, int nHeader, const
|
|||
|
||||
*szPayload = nPayload;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// handle overflow case
|
||||
// calc local storage size
|
||||
int minLocal = pPage->minLocal;
|
||||
int surplus = minLocal + (nPayload + nHeader - minLocal) % (maxLocal - sizeof(SPgno));
|
||||
int nLocal = surplus <= maxLocal ? surplus : minLocal;
|
||||
|
||||
{
|
||||
// TODO: handle overflow case
|
||||
ASSERT(0);
|
||||
//int ofpCap = tdbPageCapacity(pBt->pageSize, sizeof(SIntHdr));
|
||||
|
||||
// fetch a new ofp and make it dirty
|
||||
SPgno pgno = 0;
|
||||
SPage *ofp, *nextOfp;
|
||||
|
||||
ret = tdbFetchOvflPage(pPage->pPager, &pgno, &ofp, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// local buffer for cell
|
||||
SCell *pBuf = tdbRealloc(NULL, pBt->pageSize);
|
||||
if (pBuf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int nLeft = nPayload;
|
||||
int bytes;
|
||||
int lastPage = 0;
|
||||
if (nLocal >= kLen + 4) {
|
||||
// pack key to local
|
||||
memcpy(pCell + nHeader, pKey, kLen);
|
||||
nLeft -= kLen;
|
||||
// pack partial val to local if any space left
|
||||
if (nLocal > kLen + 4) {
|
||||
memcpy(pCell + nHeader + kLen, pVal, nLocal - kLen - sizeof(SPgno));
|
||||
nLeft -= nLocal - kLen - sizeof(SPgno);
|
||||
}
|
||||
|
||||
// pack nextPgno
|
||||
memcpy(pCell + nHeader + nPayload - nLeft, &pgno, sizeof(pgno));
|
||||
|
||||
// pack left val data to ovpages
|
||||
do {
|
||||
lastPage = 0;
|
||||
if (nLeft <= ofp->maxLocal - sizeof(SPgno)) {
|
||||
bytes = nLeft;
|
||||
lastPage = 1;
|
||||
} else {
|
||||
bytes = ofp->maxLocal - sizeof(SPgno);
|
||||
}
|
||||
|
||||
// fetch next ofp if not last page
|
||||
if (!lastPage) {
|
||||
// fetch a new ofp and make it dirty
|
||||
ret = tdbFetchOvflPage(pPage->pPager, &pgno, &nextOfp, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
tdbFree(pBuf);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
pgno = 0;
|
||||
}
|
||||
|
||||
memcpy(pBuf, ((SCell *)pVal) + vLen - nLeft, bytes);
|
||||
memcpy(pBuf + bytes, &pgno, sizeof(pgno));
|
||||
|
||||
ret = tdbPageInsertCell(ofp, 0, pBuf, bytes + sizeof(pgno), 0);
|
||||
if (ret < 0) {
|
||||
tdbFree(pBuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ofp = nextOfp;
|
||||
nLeft -= bytes;
|
||||
} while (nLeft > 0);
|
||||
} else {
|
||||
int nLeftKey = kLen;
|
||||
// pack partial key and nextPgno
|
||||
memcpy(pCell + nHeader, pKey, nLocal - 4);
|
||||
nLeft -= nLocal - 4;
|
||||
nLeftKey -= nLocal -4;
|
||||
|
||||
memcpy(pCell + nHeader + nLocal - 4, &pgno, sizeof(pgno));
|
||||
|
||||
int lastKeyPageSpace = 0;
|
||||
// pack left key & val to ovpages
|
||||
do {
|
||||
// cal key to cpy
|
||||
int lastKeyPage = 0;
|
||||
if (nLeftKey <= ofp->maxLocal - sizeof(SPgno)) {
|
||||
bytes = nLeftKey;
|
||||
lastKeyPage = 1;
|
||||
lastKeyPageSpace = ofp->maxLocal - sizeof(SPgno) - nLeftKey;
|
||||
} else {
|
||||
bytes = ofp->maxLocal - sizeof(SPgno);
|
||||
}
|
||||
|
||||
// cpy key
|
||||
memcpy(pBuf, ((SCell *)pKey) + kLen - nLeftKey, bytes);
|
||||
|
||||
if (lastKeyPage) {
|
||||
if (lastKeyPageSpace >= vLen) {
|
||||
memcpy(pBuf + kLen -nLeftKey, pVal, vLen);
|
||||
|
||||
nLeft -= vLen;
|
||||
pgno = 0;
|
||||
} else {
|
||||
memcpy(pBuf + kLen -nLeftKey, pVal, lastKeyPageSpace);
|
||||
nLeft -= lastKeyPageSpace;
|
||||
|
||||
// fetch next ofp, a new ofp and make it dirty
|
||||
ret = tdbFetchOvflPage(pPage->pPager, &pgno, &nextOfp, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// fetch next ofp, a new ofp and make it dirty
|
||||
ret = tdbFetchOvflPage(pPage->pPager, &pgno, &nextOfp, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(pBuf + kLen - nLeft, &pgno, sizeof(pgno));
|
||||
|
||||
ret = tdbPageInsertCell(ofp, 0, pBuf, bytes + sizeof(pgno), 0);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ofp = nextOfp;
|
||||
nLeftKey -= bytes;
|
||||
nLeft -= bytes;
|
||||
} while (nLeftKey > 0);
|
||||
|
||||
while (nLeft > 0) {
|
||||
// pack left val data to ovpages
|
||||
lastPage = 0;
|
||||
if (nLeft <= maxLocal - sizeof(SPgno)) {
|
||||
bytes = nLeft;
|
||||
lastPage = 1;
|
||||
} else {
|
||||
bytes = maxLocal - sizeof(SPgno);
|
||||
}
|
||||
|
||||
// fetch next ofp if not last page
|
||||
if (!lastPage) {
|
||||
// fetch a new ofp and make it dirty
|
||||
ret = tdbFetchOvflPage(pPage->pPager, &pgno, &nextOfp, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
tdbFree(pBuf);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
pgno = 0;
|
||||
}
|
||||
|
||||
memcpy(pBuf, ((SCell *)pVal) + vLen - nLeft, bytes);
|
||||
memcpy(pBuf + bytes, &pgno, sizeof(pgno));
|
||||
|
||||
ret = tdbPageInsertCell(ofp, 0, pBuf, bytes + sizeof(pgno), 0);
|
||||
if (ret < 0) {
|
||||
tdbFree(pBuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ofp = nextOfp;
|
||||
nLeft -= bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// free local buffer
|
||||
tdbFree(pBuf);
|
||||
|
||||
*szPayload = nLocal;
|
||||
|
||||
// ASSERT(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const void *pVal, int vLen, SCell *pCell,
|
||||
int *szCell) {
|
||||
int *szCell, TXN *pTxn, SBTree *pBt) {
|
||||
u8 leaf;
|
||||
int nHeader;
|
||||
int nPayload;
|
||||
|
@ -911,7 +1136,7 @@ static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const vo
|
|||
vLen = 0;
|
||||
}
|
||||
|
||||
ret = tdbBtreeEncodePayload(pPage, pCell, nHeader, pKey, kLen, pVal, vLen, &nPayload);
|
||||
ret = tdbBtreeEncodePayload(pPage, pCell, nHeader, pKey, kLen, pVal, vLen, &nPayload, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
// TODO
|
||||
ASSERT(0);
|
||||
|
@ -922,8 +1147,13 @@ static int tdbBtreeEncodeCell(SPage *pPage, const void *pKey, int kLen, const vo
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tdbBtreeDecodePayload(SPage *pPage, const SCell *pCell, int nHeader, SCellDecoder *pDecoder) {
|
||||
static int tdbBtreeDecodePayload(SPage *pPage, const SCell *pCell, int nHeader, SCellDecoder *pDecoder, TXN *pTxn, SBTree *pBt) {
|
||||
int ret = 0;
|
||||
int nPayload;
|
||||
int maxLocal = pPage->maxLocal;
|
||||
|
||||
int kLen = pDecoder->kLen;
|
||||
int vLen = pDecoder->vLen;
|
||||
|
||||
if (pDecoder->pVal) {
|
||||
ASSERT(!TDB_BTREE_PAGE_IS_LEAF(pPage));
|
||||
|
@ -932,24 +1162,171 @@ static int tdbBtreeDecodePayload(SPage *pPage, const SCell *pCell, int nHeader,
|
|||
nPayload = pDecoder->kLen + pDecoder->vLen;
|
||||
}
|
||||
|
||||
if (nHeader + nPayload <= pPage->maxLocal) {
|
||||
if (nHeader + nPayload <= maxLocal) {
|
||||
// no over flow case
|
||||
pDecoder->pKey = pCell + nHeader;
|
||||
pDecoder->pKey = (SCell *)pCell + nHeader;
|
||||
if (pDecoder->pVal == NULL && pDecoder->vLen > 0) {
|
||||
pDecoder->pVal = pCell + nHeader + pDecoder->kLen;
|
||||
pDecoder->pVal = (SCell *)pCell + nHeader + pDecoder->kLen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// handle overflow case
|
||||
// calc local storage size
|
||||
int minLocal = pPage->minLocal;
|
||||
int surplus = minLocal + (nPayload + nHeader - minLocal) % (maxLocal - sizeof(SPgno));
|
||||
int nLocal = surplus <= maxLocal ? surplus : minLocal;
|
||||
|
||||
{
|
||||
// TODO: handle overflow case
|
||||
ASSERT(0);
|
||||
int nLeft = nPayload;
|
||||
SPgno pgno = 0;
|
||||
SPage *ofp;
|
||||
SCell *ofpCell;
|
||||
int bytes;
|
||||
int lastPage = 0;
|
||||
|
||||
if (nLocal >= pDecoder->kLen + 4) {
|
||||
pDecoder->pKey = (SCell *)pCell + nHeader;
|
||||
nLeft -= kLen;
|
||||
if (nLocal > kLen + 4) {
|
||||
// read partial val to local
|
||||
pDecoder->pVal = tdbRealloc(pDecoder->pVal, vLen);
|
||||
if (pDecoder->pVal == NULL) {
|
||||
return -1;
|
||||
}
|
||||
TDB_CELLDECODER_SET_FREE_VAL(pDecoder);
|
||||
|
||||
memcpy(pDecoder->pVal, pCell + nHeader + kLen, nLocal - kLen - sizeof(SPgno));
|
||||
|
||||
nLeft -= nLocal - kLen - sizeof(SPgno);
|
||||
}
|
||||
|
||||
memcpy(&pgno, pCell + nHeader + nPayload - nLeft, sizeof(pgno));
|
||||
|
||||
// unpack left val data from ovpages
|
||||
while (pgno != 0) {
|
||||
ret = tdbLoadOvflPage(pPage->pPager, &pgno, &ofp, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ofpCell = tdbPageGetCell(ofp, 0);
|
||||
|
||||
if (nLeft <= ofp->maxLocal - sizeof(SPgno)) {
|
||||
bytes = nLeft;
|
||||
lastPage = 1;
|
||||
} else {
|
||||
bytes = ofp->maxLocal - sizeof(SPgno);
|
||||
}
|
||||
|
||||
memcpy(pDecoder->pVal + vLen - nLeft, ofpCell, bytes);
|
||||
nLeft -= bytes;
|
||||
|
||||
memcpy(&pgno, ofpCell + bytes, sizeof(pgno));
|
||||
}
|
||||
} else {
|
||||
int nLeftKey = kLen;
|
||||
// load partial key and nextPgno
|
||||
pDecoder->pKey = tdbRealloc(pDecoder->pKey, kLen);
|
||||
if (pDecoder->pKey == NULL) {
|
||||
return -1;
|
||||
}
|
||||
TDB_CELLDECODER_SET_FREE_KEY(pDecoder);
|
||||
|
||||
memcpy(pDecoder->pKey, pCell + nHeader, nLocal - 4);
|
||||
nLeft -= nLocal - 4;
|
||||
nLeftKey -= nLocal -4;
|
||||
|
||||
memcpy(&pgno, pCell + nHeader + nLocal - 4, sizeof(pgno));
|
||||
|
||||
int lastKeyPageSpace = 0;
|
||||
// load left key & val to ovpages
|
||||
while (pgno != 0) {
|
||||
ret = tdbLoadOvflPage(pPage->pPager, &pgno, &ofp, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ofpCell = tdbPageGetCell(ofp, 0);
|
||||
|
||||
int lastKeyPage = 0;
|
||||
if (nLeftKey <= maxLocal - sizeof(SPgno)) {
|
||||
bytes = nLeftKey;
|
||||
lastKeyPage = 1;
|
||||
lastKeyPageSpace = ofp->maxLocal - sizeof(SPgno) - nLeftKey;
|
||||
} else {
|
||||
bytes = ofp->maxLocal - sizeof(SPgno);
|
||||
}
|
||||
|
||||
// cpy key
|
||||
memcpy(pDecoder->pKey + kLen - nLeftKey, ofpCell, bytes);
|
||||
|
||||
if (lastKeyPage) {
|
||||
if (lastKeyPageSpace >= vLen) {
|
||||
pDecoder->pVal = ofpCell + kLen -nLeftKey;
|
||||
|
||||
nLeft -= vLen;
|
||||
pgno = 0;
|
||||
} else {
|
||||
// read partial val to local
|
||||
pDecoder->pVal = tdbRealloc(pDecoder->pVal, vLen);
|
||||
if (pDecoder->pVal == NULL) {
|
||||
return -1;
|
||||
}
|
||||
TDB_CELLDECODER_SET_FREE_VAL(pDecoder);
|
||||
|
||||
memcpy(pDecoder->pVal, ofpCell + kLen -nLeftKey, lastKeyPageSpace);
|
||||
nLeft -= lastKeyPageSpace;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&pgno, ofpCell + bytes, sizeof(pgno));
|
||||
|
||||
nLeftKey -= bytes;
|
||||
nLeft -= bytes;
|
||||
}
|
||||
|
||||
while (nLeft > 0) {
|
||||
ret = tdbLoadOvflPage(pPage->pPager, &pgno, &ofp, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ofpCell = tdbPageGetCell(ofp, 0);
|
||||
|
||||
// load left val data to ovpages
|
||||
lastPage = 0;
|
||||
if (nLeft <= ofp->maxLocal - sizeof(SPgno)) {
|
||||
bytes = nLeft;
|
||||
lastPage = 1;
|
||||
} else {
|
||||
bytes = ofp->maxLocal - sizeof(SPgno);
|
||||
}
|
||||
|
||||
if (lastPage) {
|
||||
pgno = 0;
|
||||
}
|
||||
|
||||
if (!pDecoder->pVal) {
|
||||
pDecoder->pVal = tdbRealloc(pDecoder->pVal, vLen);
|
||||
if (pDecoder->pVal == NULL) {
|
||||
return -1;
|
||||
}
|
||||
TDB_CELLDECODER_SET_FREE_VAL(pDecoder);
|
||||
}
|
||||
|
||||
memcpy(pDecoder->pVal, ofpCell + vLen - nLeft, bytes);
|
||||
nLeft -= bytes;
|
||||
|
||||
memcpy(&pgno, ofpCell + vLen - nLeft + bytes, sizeof(pgno));
|
||||
|
||||
nLeft -= bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pDecoder) {
|
||||
static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pDecoder, TXN *pTxn, SBTree *pBt) {
|
||||
u8 leaf;
|
||||
int nHeader;
|
||||
int ret;
|
||||
|
@ -963,6 +1340,7 @@ static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pD
|
|||
pDecoder->vLen = -1;
|
||||
pDecoder->pVal = NULL;
|
||||
pDecoder->pgno = 0;
|
||||
TDB_CELLDECODER_SET_FREE_NIL(pDecoder);
|
||||
|
||||
// 1. Decode header part
|
||||
if (!leaf) {
|
||||
|
@ -987,7 +1365,7 @@ static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pD
|
|||
}
|
||||
|
||||
// 2. Decode payload part
|
||||
ret = tdbBtreeDecodePayload(pPage, pCell, nHeader, pDecoder);
|
||||
ret = tdbBtreeDecodePayload(pPage, pCell, nHeader, pDecoder, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -995,41 +1373,71 @@ static int tdbBtreeDecodeCell(SPage *pPage, const SCell *pCell, SCellDecoder *pD
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell) {
|
||||
static int tdbBtreeCellSize(const SPage *pPage, SCell *pCell, int dropOfp, TXN *pTxn, SBTree *pBt) {
|
||||
u8 leaf;
|
||||
int szCell;
|
||||
int kLen = 0, vLen = 0;
|
||||
int kLen = 0, vLen = 0, nHeader = 0;
|
||||
|
||||
leaf = TDB_BTREE_PAGE_IS_LEAF(pPage);
|
||||
szCell = 0;
|
||||
|
||||
if (!leaf) {
|
||||
szCell += sizeof(SPgno);
|
||||
nHeader += sizeof(SPgno);
|
||||
}
|
||||
|
||||
if (pPage->kLen == TDB_VARIANT_LEN) {
|
||||
szCell += tdbGetVarInt(pCell + szCell, &kLen);
|
||||
nHeader += tdbGetVarInt(pCell + nHeader, &kLen);
|
||||
} else {
|
||||
kLen = pPage->kLen;
|
||||
}
|
||||
|
||||
if (pPage->vLen == TDB_VARIANT_LEN) {
|
||||
ASSERT(leaf);
|
||||
szCell += tdbGetVarInt(pCell + szCell, &vLen);
|
||||
nHeader += tdbGetVarInt(pCell + nHeader, &vLen);
|
||||
} else if (leaf) {
|
||||
vLen = pPage->vLen;
|
||||
}
|
||||
|
||||
szCell = szCell + kLen + vLen;
|
||||
int nPayload = kLen + vLen;
|
||||
if (nHeader + nPayload <= pPage->maxLocal) {
|
||||
return nHeader + kLen + vLen;
|
||||
} else {
|
||||
int maxLocal = pPage->maxLocal;
|
||||
|
||||
if (szCell <= pPage->maxLocal) {
|
||||
return szCell;
|
||||
}
|
||||
// calc local storage size
|
||||
int minLocal = pPage->minLocal;
|
||||
int surplus = minLocal + (nPayload + nHeader - minLocal) % (maxLocal - sizeof(SPgno));
|
||||
int nLocal = surplus <= maxLocal ? surplus : minLocal;
|
||||
|
||||
{
|
||||
// TODO
|
||||
ASSERT(0);
|
||||
return 0;
|
||||
// free ofp pages' cells
|
||||
if (dropOfp) {
|
||||
int ret = 0;
|
||||
SPgno pgno = *(SPgno *) (pCell + nHeader + nLocal - sizeof(SPgno));
|
||||
int nLeft = nPayload - nLocal + sizeof(SPgno);
|
||||
SPage *ofp;
|
||||
int bytes;
|
||||
|
||||
while (pgno != 0) {
|
||||
ret = tdbLoadOvflPage(pPage->pPager, &pgno, &ofp, pTxn, pBt);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SCell *ofpCell = tdbPageGetCell(ofp, 0);
|
||||
|
||||
if (nLeft <= ofp->maxLocal - sizeof(SPgno)) {
|
||||
bytes = nLeft;
|
||||
} else {
|
||||
bytes = ofp->maxLocal - sizeof(SPgno);
|
||||
}
|
||||
|
||||
memcpy(&pgno, ofpCell + bytes, sizeof(pgno));
|
||||
|
||||
tdbPagerReturnPage(pPage->pPager, ofp, pTxn);
|
||||
|
||||
nLeft -= bytes;
|
||||
}
|
||||
}
|
||||
|
||||
return nHeader + nLocal;
|
||||
}
|
||||
}
|
||||
// TDB_BTREE_CELL
|
||||
|
@ -1212,7 +1620,7 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
|
|||
|
||||
pCell = tdbPageGetCell(pBtc->pPage, pBtc->idx);
|
||||
|
||||
tdbBtreeDecodeCell(pBtc->pPage, pCell, &cd);
|
||||
tdbBtreeDecodeCell(pBtc->pPage, pCell, &cd, pBtc->pTxn, pBtc->pBt);
|
||||
|
||||
pKey = tdbRealloc(*ppKey, cd.kLen);
|
||||
if (pKey == NULL) {
|
||||
|
@ -1258,7 +1666,7 @@ int tdbBtreePrev(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
|
|||
|
||||
pCell = tdbPageGetCell(pBtc->pPage, pBtc->idx);
|
||||
|
||||
tdbBtreeDecodeCell(pBtc->pPage, pCell, &cd);
|
||||
tdbBtreeDecodeCell(pBtc->pPage, pCell, &cd, pBtc->pTxn, pBtc->pBt);
|
||||
|
||||
pKey = tdbRealloc(*ppKey, cd.kLen);
|
||||
if (pKey == NULL) {
|
||||
|
@ -1427,7 +1835,7 @@ int tdbBtcGet(SBTC *pBtc, const void **ppKey, int *kLen, const void **ppVal, int
|
|||
}
|
||||
|
||||
pCell = tdbPageGetCell(pBtc->pPage, pBtc->idx);
|
||||
tdbBtreeDecodeCell(pBtc->pPage, pCell, &pBtc->coder);
|
||||
tdbBtreeDecodeCell(pBtc->pPage, pCell, &pBtc->coder, pBtc->pTxn, pBtc->pBt);
|
||||
|
||||
if (ppKey) {
|
||||
*ppKey = (void *)pBtc->coder.pKey;
|
||||
|
@ -1464,7 +1872,7 @@ int tdbBtcDelete(SBTC *pBtc) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
tdbPageDropCell(pBtc->pPage, idx);
|
||||
tdbPageDropCell(pBtc->pPage, idx, pBtc->pTxn, pBtc->pBt);
|
||||
|
||||
// update interior page or do balance
|
||||
if (idx == nCells - 1) {
|
||||
|
@ -1488,9 +1896,9 @@ int tdbBtcDelete(SBTC *pBtc) {
|
|||
|
||||
// update the cell with new key
|
||||
pCell = tdbOsMalloc(nKey + 9);
|
||||
tdbBtreeEncodeCell(pPage, pKey, nKey, &pgno, sizeof(pgno), pCell, &szCell);
|
||||
tdbBtreeEncodeCell(pPage, pKey, nKey, &pgno, sizeof(pgno), pCell, &szCell, pBtc->pTxn, pBtc->pBt);
|
||||
|
||||
ret = tdbPageUpdateCell(pPage, idx, pCell, szCell);
|
||||
ret = tdbPageUpdateCell(pPage, idx, pCell, szCell, pBtc->pTxn, pBtc->pBt);
|
||||
if (ret < 0) {
|
||||
tdbOsFree(pCell);
|
||||
ASSERT(0);
|
||||
|
@ -1529,7 +1937,7 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int
|
|||
|
||||
// alloc space
|
||||
szBuf = kLen + nData + 14;
|
||||
pBuf = tdbRealloc(pBtc->pBt->pBuf, pBtc->pBt->pageSize > szBuf ? szBuf : pBtc->pBt->pageSize);
|
||||
pBuf = tdbRealloc(pBtc->pBt->pBuf, pBtc->pBt->pageSize > szBuf ? szBuf : pBtc->pBt->pageSize);
|
||||
if (pBuf == NULL) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
|
@ -1538,7 +1946,7 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int
|
|||
pCell = (SCell *)pBtc->pBt->pBuf;
|
||||
|
||||
// encode cell
|
||||
ret = tdbBtreeEncodeCell(pBtc->pPage, pKey, kLen, pData, nData, pCell, &szCell);
|
||||
ret = tdbBtreeEncodeCell(pBtc->pPage, pKey, kLen, pData, nData, pCell, &szCell, pBtc->pTxn, pBtc->pBt);
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
|
@ -1559,7 +1967,7 @@ int tdbBtcUpsert(SBTC *pBtc, const void *pKey, int kLen, const void *pData, int
|
|||
} else {
|
||||
ASSERT(pBtc->idx < nCells);
|
||||
|
||||
ret = tdbPageUpdateCell(pBtc->pPage, pBtc->idx, pCell, szCell);
|
||||
ret = tdbPageUpdateCell(pBtc->pPage, pBtc->idx, pCell, szCell, pBtc->pTxn, pBtc->pBt);
|
||||
}
|
||||
if (ret < 0) {
|
||||
ASSERT(0);
|
||||
|
@ -1620,7 +2028,7 @@ int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
|
|||
// check if key <= current position
|
||||
if (idx < nCells) {
|
||||
pCell = tdbPageGetCell(pPage, idx);
|
||||
tdbBtreeDecodeCell(pPage, pCell, &cd);
|
||||
tdbBtreeDecodeCell(pPage, pCell, &cd, pBtc->pTxn, pBtc->pBt);
|
||||
c = pBt->kcmpr(pKey, kLen, cd.pKey, cd.kLen);
|
||||
if (c > 0) break;
|
||||
}
|
||||
|
@ -1629,7 +2037,7 @@ int tdbBtcMoveTo(SBTC *pBtc, const void *pKey, int kLen, int *pCRst) {
|
|||
if (idx > 0) {
|
||||
pCell = tdbPageGetCell(pPage, idx - 1);
|
||||
tdbBtreeDecodeCell(pPage, pCell, &cd);
|
||||
c = pBt->kcmpr(pKey, kLen, cd.pKey, cd.kLen);
|
||||
c = pBt->kcmpr(pKey, kLen, cd.pKey, cd.kLen, pBtc->pTxn, pBtc->pBt);
|
||||
if (c <= 0) break;
|
||||
}
|
||||
}
|
||||
|
@ -1769,4 +2177,4 @@ void tdbBtPageInfo(SPage *pPage, int idx) {
|
|||
pBtPageInfo->nOvfl = pPage->nOverflow;
|
||||
}
|
||||
#endif
|
||||
// TDB_BTREE_DEBUG
|
||||
// TDB_BTREE_DEBUG
|
||||
|
|
|
@ -82,7 +82,8 @@ int tdbPageDestroy(SPage *pPage, void (*xFree)(void *arg, void *ptr), void *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tdbPageZero(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *)) {
|
||||
void tdbPageZero(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *, int,
|
||||
TXN *, SBTree *pBt)) {
|
||||
pPage->pPageHdr = pPage->pData + szAmHdr;
|
||||
TDB_PAGE_NCELLS_SET(pPage, 0);
|
||||
TDB_PAGE_CCELLS_SET(pPage, pPage->pageSize - sizeof(SPageFtr));
|
||||
|
@ -98,7 +99,8 @@ void tdbPageZero(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell
|
|||
ASSERT((u8 *)pPage->pPageFtr == pPage->pFreeEnd);
|
||||
}
|
||||
|
||||
void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *)) {
|
||||
void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *, int,
|
||||
TXN *, SBTree *pBt)) {
|
||||
pPage->pPageHdr = pPage->pData + szAmHdr;
|
||||
pPage->pCellIdx = pPage->pPageHdr + TDB_PAGE_HDR_SIZE(pPage);
|
||||
pPage->pFreeStart = pPage->pCellIdx + TDB_PAGE_OFFSET_SIZE(pPage) * TDB_PAGE_NCELLS(pPage);
|
||||
|
@ -171,12 +173,12 @@ int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell, u8 asOvfl
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tdbPageUpdateCell(SPage *pPage, int idx, SCell *pCell, int szCell) {
|
||||
tdbPageDropCell(pPage, idx);
|
||||
int tdbPageUpdateCell(SPage *pPage, int idx, SCell *pCell, int szCell, TXN *pTxn, SBTree *pBt) {
|
||||
tdbPageDropCell(pPage, idx, pTxn, pBt);
|
||||
return tdbPageInsertCell(pPage, idx, pCell, szCell, 0);
|
||||
}
|
||||
|
||||
int tdbPageDropCell(SPage *pPage, int idx) {
|
||||
int tdbPageDropCell(SPage *pPage, int idx, TXN *pTxn, SBTree *pBt) {
|
||||
int lidx;
|
||||
SCell *pCell;
|
||||
int szCell;
|
||||
|
@ -205,7 +207,7 @@ int tdbPageDropCell(SPage *pPage, int idx) {
|
|||
|
||||
lidx = idx - iOvfl;
|
||||
pCell = TDB_PAGE_CELL_AT(pPage, lidx);
|
||||
szCell = (*pPage->xCellSize)(pPage, pCell);
|
||||
szCell = (*pPage->xCellSize)(pPage, pCell, 1, pTxn, pBt);
|
||||
tdbPageFree(pPage, lidx, pCell, szCell);
|
||||
TDB_PAGE_NCELLS_SET(pPage, nCells - 1);
|
||||
|
||||
|
@ -420,7 +422,7 @@ static int tdbPageDefragment(SPage *pPage) {
|
|||
|
||||
ASSERT(pCell != NULL);
|
||||
|
||||
szCell = (*pPage->xCellSize)(pPage, pCell);
|
||||
szCell = (*pPage->xCellSize)(pPage, pCell, 0, NULL, NULL);
|
||||
|
||||
ASSERT(pCell + szCell <= pNextCell);
|
||||
if (pCell + szCell < pNextCell) {
|
||||
|
|
|
@ -116,13 +116,25 @@ typedef struct SBtInfo {
|
|||
int nData;
|
||||
} SBtInfo;
|
||||
|
||||
#define TDB_CELLD_F_NIL 0x0
|
||||
#define TDB_CELLD_F_KEY 0x1
|
||||
#define TDB_CELLD_F_VAL 0x2
|
||||
|
||||
#define TDB_CELLDECODER_SET_FREE_NIL(pCellDecoder) ((pCellDecoder)->freeKV = TDB_CELLD_F_NIL)
|
||||
#define TDB_CELLDECODER_SET_FREE_KEY(pCellDecoder) ((pCellDecoder)->freeKV |= TDB_CELLD_F_KEY)
|
||||
#define TDB_CELLDECODER_SET_FREE_VAL(pCellDecoder) ((pCellDecoder)->freeKV |= TDB_CELLD_F_VAL)
|
||||
|
||||
#define TDB_CELLDECODER_FREE_KEY(pCellDecoder) ((pCellDecoder)->freeKV & TDB_CELLD_F_KEY)
|
||||
#define TDB_CELLDECODER_FREE_VAL(pCellDecoder) ((pCellDecoder)->freeKV & TDB_CELLD_F_VAL)
|
||||
|
||||
typedef struct {
|
||||
int kLen;
|
||||
const u8 *pKey;
|
||||
u8 *pKey;
|
||||
int vLen;
|
||||
const u8 *pVal;
|
||||
u8 *pVal;
|
||||
SPgno pgno;
|
||||
u8 *pBuf;
|
||||
u8 freeKV;
|
||||
} SCellDecoder;
|
||||
|
||||
struct SBTC {
|
||||
|
@ -251,7 +263,7 @@ struct SPage {
|
|||
int vLen; // value length of the page, -1 for unknown
|
||||
int maxLocal;
|
||||
int minLocal;
|
||||
int (*xCellSize)(const SPage *, SCell *);
|
||||
int (*xCellSize)(const SPage *, SCell *, int, TXN *pTxn, SBTree *pBt);
|
||||
// Fields used by SPCache
|
||||
TDB_PCACHE_PAGE
|
||||
};
|
||||
|
@ -298,16 +310,18 @@ static inline int tdbTryLockPage(tdb_spinlock_t *pLock) {
|
|||
#define TDB_PAGE_USABLE_SIZE(pPage) ((u8 *)(pPage)->pPageFtr - (pPage)->pCellIdx)
|
||||
#define TDB_PAGE_FREE_SIZE(pPage) (*(pPage)->pPageMethods->getFreeBytes)(pPage)
|
||||
#define TDB_PAGE_PGNO(pPage) ((pPage)->pgid.pgno)
|
||||
#define TDB_BYTES_CELL_TAKEN(pPage, pCell) ((*(pPage)->xCellSize)(pPage, pCell) + (pPage)->pPageMethods->szOffset)
|
||||
#define TDB_BYTES_CELL_TAKEN(pPage, pCell) ((*(pPage)->xCellSize)(pPage, pCell, 0, NULL, NULL) + (pPage)->pPageMethods->szOffset)
|
||||
#define TDB_PAGE_OFFSET_SIZE(pPage) ((pPage)->pPageMethods->szOffset)
|
||||
|
||||
int tdbPageCreate(int pageSize, SPage **ppPage, void *(*xMalloc)(void *, size_t), void *arg);
|
||||
int tdbPageDestroy(SPage *pPage, void (*xFree)(void *arg, void *ptr), void *arg);
|
||||
void tdbPageZero(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *));
|
||||
void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *));
|
||||
void tdbPageZero(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *, int,
|
||||
TXN *, SBTree *pBt));
|
||||
void tdbPageInit(SPage *pPage, u8 szAmHdr, int (*xCellSize)(const SPage *, SCell *, int,
|
||||
TXN *, SBTree *pBt));
|
||||
int tdbPageInsertCell(SPage *pPage, int idx, SCell *pCell, int szCell, u8 asOvfl);
|
||||
int tdbPageDropCell(SPage *pPage, int idx);
|
||||
int tdbPageUpdateCell(SPage *pPage, int idx, SCell *pCell, int szCell);
|
||||
int tdbPageDropCell(SPage *pPage, int idx, TXN *pTxn, SBTree *pBt);
|
||||
int tdbPageUpdateCell(SPage *pPage, int idx, SCell *pCell, int szCell, TXN *pTxn, SBTree *pBt);
|
||||
void tdbPageCopy(SPage *pFromPage, SPage *pToPage);
|
||||
int tdbPageCapacity(int pageSize, int amHdrSize);
|
||||
|
||||
|
|
|
@ -4,4 +4,9 @@ target_link_libraries(tdbTest tdb gtest gtest_main)
|
|||
|
||||
# tdbUtilTest
|
||||
add_executable(tdbUtilTest "tdbUtilTest.cpp")
|
||||
target_link_libraries(tdbUtilTest tdb gtest gtest_main)
|
||||
target_link_libraries(tdbUtilTest tdb gtest gtest_main)
|
||||
|
||||
# tdbUtilTest
|
||||
add_executable(tdbExOVFLTest "tdbExOVFLTest.cpp")
|
||||
target_link_libraries(tdbExOVFLTest tdb gtest gtest_main)
|
||||
|
||||
|
|
|
@ -0,0 +1,469 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#define ALLOW_FORBID_FUNC
|
||||
#include "os.h"
|
||||
#include "tdb.h"
|
||||
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
typedef struct SPoolMem {
|
||||
int64_t size;
|
||||
struct SPoolMem *prev;
|
||||
struct SPoolMem *next;
|
||||
} SPoolMem;
|
||||
|
||||
static SPoolMem *openPool() {
|
||||
SPoolMem *pPool = (SPoolMem *)taosMemoryMalloc(sizeof(*pPool));
|
||||
|
||||
pPool->prev = pPool->next = pPool;
|
||||
pPool->size = 0;
|
||||
|
||||
return pPool;
|
||||
}
|
||||
|
||||
static void clearPool(SPoolMem *pPool) {
|
||||
SPoolMem *pMem;
|
||||
|
||||
do {
|
||||
pMem = pPool->next;
|
||||
|
||||
if (pMem == pPool) break;
|
||||
|
||||
pMem->next->prev = pMem->prev;
|
||||
pMem->prev->next = pMem->next;
|
||||
pPool->size -= pMem->size;
|
||||
|
||||
taosMemoryFree(pMem);
|
||||
} while (1);
|
||||
|
||||
assert(pPool->size == 0);
|
||||
}
|
||||
|
||||
static void closePool(SPoolMem *pPool) {
|
||||
clearPool(pPool);
|
||||
taosMemoryFree(pPool);
|
||||
}
|
||||
|
||||
static void *poolMalloc(void *arg, size_t size) {
|
||||
void *ptr = NULL;
|
||||
SPoolMem *pPool = (SPoolMem *)arg;
|
||||
SPoolMem *pMem;
|
||||
|
||||
pMem = (SPoolMem *)taosMemoryMalloc(sizeof(*pMem) + size);
|
||||
if (pMem == NULL) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
pMem->size = sizeof(*pMem) + size;
|
||||
pMem->next = pPool->next;
|
||||
pMem->prev = pPool;
|
||||
|
||||
pPool->next->prev = pMem;
|
||||
pPool->next = pMem;
|
||||
pPool->size += pMem->size;
|
||||
|
||||
ptr = (void *)(&pMem[1]);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void poolFree(void *arg, void *ptr) {
|
||||
SPoolMem *pPool = (SPoolMem *)arg;
|
||||
SPoolMem *pMem;
|
||||
|
||||
pMem = &(((SPoolMem *)ptr)[-1]);
|
||||
|
||||
pMem->next->prev = pMem->prev;
|
||||
pMem->prev->next = pMem->next;
|
||||
pPool->size -= pMem->size;
|
||||
|
||||
taosMemoryFree(pMem);
|
||||
}
|
||||
|
||||
static int tKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2) {
|
||||
int k1, k2;
|
||||
|
||||
std::string s1((char *)pKey1 + 3, kLen1 - 3);
|
||||
std::string s2((char *)pKey2 + 3, kLen2 - 3);
|
||||
k1 = stoi(s1);
|
||||
k2 = stoi(s2);
|
||||
|
||||
if (k1 < k2) {
|
||||
return -1;
|
||||
} else if (k1 > k2) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int tDefaultKeyCmpr(const void *pKey1, int keyLen1, const void *pKey2, int keyLen2) {
|
||||
int mlen;
|
||||
int cret;
|
||||
|
||||
ASSERT(keyLen1 > 0 && keyLen2 > 0 && pKey1 != NULL && pKey2 != NULL);
|
||||
|
||||
mlen = keyLen1 < keyLen2 ? keyLen1 : keyLen2;
|
||||
cret = memcmp(pKey1, pKey2, mlen);
|
||||
if (cret == 0) {
|
||||
if (keyLen1 < keyLen2) {
|
||||
cret = -1;
|
||||
} else if (keyLen1 > keyLen2) {
|
||||
cret = 1;
|
||||
} else {
|
||||
cret = 0;
|
||||
}
|
||||
}
|
||||
return cret;
|
||||
}
|
||||
|
||||
TEST(TdbOVFLPagesTest, TbUpsertTest) {
|
||||
|
||||
}
|
||||
|
||||
TEST(TdbOVFLPagesTest, TbPGetTest) {
|
||||
|
||||
}
|
||||
|
||||
static void generateBigVal(char *val, int valLen) {
|
||||
for (int i = 0; i < valLen; ++i) {
|
||||
char c = char(i & 0xff);
|
||||
if (c == 0) {
|
||||
c = 1;
|
||||
}
|
||||
val[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
static TDB *openEnv(char const *envName, int const pageSize, int const pageNum) {
|
||||
TDB *pEnv = NULL;
|
||||
|
||||
int ret = tdbOpen(envName, pageSize, pageNum, &pEnv);
|
||||
if (ret) {
|
||||
pEnv = NULL;
|
||||
}
|
||||
|
||||
return pEnv;
|
||||
}
|
||||
|
||||
static void insertOfp(void) {
|
||||
int ret = 0;
|
||||
|
||||
taosRemoveDir("tdb");
|
||||
|
||||
// open Env
|
||||
int const pageSize = 4096;
|
||||
int const pageNum = 64;
|
||||
TDB *pEnv = openEnv("tdb", pageSize, pageNum);
|
||||
GTEST_ASSERT_NE(pEnv, nullptr);
|
||||
|
||||
// open db
|
||||
TTB *pDb = NULL;
|
||||
tdb_cmpr_fn_t compFunc = tKeyCmpr;
|
||||
ret = tdbTbOpen("ofp_insert.db", -1, -1, compFunc, pEnv, &pDb);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
// open the pool
|
||||
SPoolMem *pPool = openPool();
|
||||
|
||||
// start a transaction
|
||||
TXN txn;
|
||||
int64_t txnid = 0;
|
||||
++txnid;
|
||||
tdbTxnOpen(&txn, txnid, poolMalloc, poolFree, pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
|
||||
tdbBegin(pEnv, &txn);
|
||||
|
||||
// generate value payload
|
||||
char val[((4083 - 4 - 3 - 2)+1)*100]; // pSize(4096) - amSize(1) - pageHdr(8) - footerSize(4)
|
||||
int valLen = sizeof(val) / sizeof(val[0]);
|
||||
generateBigVal(val, valLen);
|
||||
|
||||
// insert the generated big data
|
||||
ret = tdbTbInsert(pDb, "key1", strlen("key1"), val, valLen, &txn);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
// commit current transaction
|
||||
tdbCommit(pEnv, &txn);
|
||||
tdbTxnClose(&txn);
|
||||
}
|
||||
|
||||
//TEST(TdbOVFLPagesTest, DISABLED_TbInsertTest) {
|
||||
TEST(TdbOVFLPagesTest, TbInsertTest) {
|
||||
insertOfp();
|
||||
}
|
||||
|
||||
//TEST(TdbOVFLPagesTest, DISABLED_TbGetTest) {
|
||||
TEST(TdbOVFLPagesTest, TbGetTest) {
|
||||
insertOfp();
|
||||
|
||||
// open Env
|
||||
int const pageSize = 4096;
|
||||
int const pageNum = 64;
|
||||
TDB *pEnv = openEnv("tdb", pageSize, pageNum);
|
||||
GTEST_ASSERT_NE(pEnv, nullptr);
|
||||
|
||||
// open db
|
||||
TTB *pDb = NULL;
|
||||
tdb_cmpr_fn_t compFunc = tKeyCmpr;
|
||||
int ret = tdbTbOpen("ofp_insert.db", -1, -1, compFunc, pEnv, &pDb);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
// generate value payload
|
||||
char val[((4083 - 4 - 3 - 2)+1)*100]; // pSize(4096) - amSize(1) - pageHdr(8) - footerSize(4)
|
||||
int valLen = sizeof(val) / sizeof(val[0]);
|
||||
generateBigVal(val, valLen);
|
||||
|
||||
{ // Query the data
|
||||
void *pVal = NULL;
|
||||
int vLen;
|
||||
|
||||
ret = tdbTbGet(pDb, "key1", strlen("key1"), &pVal, &vLen);
|
||||
ASSERT(ret == 0);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
GTEST_ASSERT_EQ(vLen, valLen);
|
||||
GTEST_ASSERT_EQ(memcmp(val, pVal, vLen), 0);
|
||||
|
||||
tdbFree(pVal);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TdbOVFLPagesTest, TbDeleteTest) {
|
||||
int ret = 0;
|
||||
|
||||
taosRemoveDir("tdb");
|
||||
|
||||
// open Env
|
||||
int const pageSize = 4096;
|
||||
int const pageNum = 64;
|
||||
TDB *pEnv = openEnv("tdb", pageSize, pageNum);
|
||||
GTEST_ASSERT_NE(pEnv, nullptr);
|
||||
|
||||
// open db
|
||||
TTB *pDb = NULL;
|
||||
tdb_cmpr_fn_t compFunc = tKeyCmpr;
|
||||
ret = tdbTbOpen("ofp_insert.db", -1, -1, compFunc, pEnv, &pDb);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
// open the pool
|
||||
SPoolMem *pPool = openPool();
|
||||
|
||||
// start a transaction
|
||||
TXN txn;
|
||||
int64_t txnid = 0;
|
||||
++txnid;
|
||||
tdbTxnOpen(&txn, txnid, poolMalloc, poolFree, pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
|
||||
tdbBegin(pEnv, &txn);
|
||||
|
||||
// generate value payload
|
||||
char val[((4083 - 4 - 3 - 2)+1)*100]; // pSize(4096) - amSize(1) - pageHdr(8) - footerSize(4)
|
||||
int valLen = sizeof(val) / sizeof(val[0]);
|
||||
generateBigVal(val, valLen);
|
||||
|
||||
{ // insert the generated big data
|
||||
ret = tdbTbInsert(pDb, "key1", strlen("key1"), val, valLen, &txn);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
}
|
||||
|
||||
{ // query the data
|
||||
void *pVal = NULL;
|
||||
int vLen;
|
||||
|
||||
ret = tdbTbGet(pDb, "key1", strlen("key1"), &pVal, &vLen);
|
||||
ASSERT(ret == 0);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
GTEST_ASSERT_EQ(vLen, valLen);
|
||||
GTEST_ASSERT_EQ(memcmp(val, pVal, vLen), 0);
|
||||
|
||||
tdbFree(pVal);
|
||||
}
|
||||
/* open to debug committed file
|
||||
tdbCommit(pEnv, &txn);
|
||||
tdbTxnClose(&txn);
|
||||
|
||||
++txnid;
|
||||
tdbTxnOpen(&txn, txnid, poolMalloc, poolFree, pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
|
||||
tdbBegin(pEnv, &txn);
|
||||
*/
|
||||
{ // upsert the data
|
||||
ret = tdbTbUpsert(pDb, "key1", strlen("key1"), "value1", strlen("value1"), &txn);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
}
|
||||
|
||||
{ // query the upserted data
|
||||
void *pVal = NULL;
|
||||
int vLen;
|
||||
|
||||
ret = tdbTbGet(pDb, "key1", strlen("key1"), &pVal, &vLen);
|
||||
ASSERT(ret == 0);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
GTEST_ASSERT_EQ(vLen, strlen("value1"));
|
||||
GTEST_ASSERT_EQ(memcmp("value1", pVal, vLen), 0);
|
||||
|
||||
tdbFree(pVal);
|
||||
}
|
||||
|
||||
{ // delete the data
|
||||
ret = tdbTbDelete(pDb, "key1", strlen("key1"), &txn);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
}
|
||||
|
||||
{ // query the deleted data
|
||||
void *pVal = NULL;
|
||||
int vLen = -1;
|
||||
|
||||
ret = tdbTbGet(pDb, "key1", strlen("key1"), &pVal, &vLen);
|
||||
ASSERT(ret == -1);
|
||||
GTEST_ASSERT_EQ(ret, -1);
|
||||
|
||||
GTEST_ASSERT_EQ(vLen, -1);
|
||||
GTEST_ASSERT_EQ(pVal, nullptr);
|
||||
|
||||
tdbFree(pVal);
|
||||
}
|
||||
|
||||
// commit current transaction
|
||||
tdbCommit(pEnv, &txn);
|
||||
tdbTxnClose(&txn);
|
||||
}
|
||||
|
||||
TEST(tdb_test, DISABLED_simple_insert1) {
|
||||
//TEST(tdb_test, simple_insert1) {
|
||||
int ret;
|
||||
TDB *pEnv;
|
||||
TTB *pDb;
|
||||
tdb_cmpr_fn_t compFunc;
|
||||
int nData = 1;
|
||||
TXN txn;
|
||||
int const pageSize = 4096;
|
||||
|
||||
taosRemoveDir("tdb");
|
||||
|
||||
// Open Env
|
||||
ret = tdbOpen("tdb", pageSize, 64, &pEnv);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
// Create a database
|
||||
compFunc = tKeyCmpr;
|
||||
ret = tdbTbOpen("db.db", -1, -1, compFunc, pEnv, &pDb);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
{
|
||||
char key[64];
|
||||
//char val[(4083 - 4 - 3 - 2)]; // pSize(4096) - amSize(1) - pageHdr(8) - footerSize(4)
|
||||
char val[(4083 - 4 - 3 - 2)+1]; // pSize(4096) - amSize(1) - pageHdr(8) - footerSize(4)
|
||||
int64_t poolLimit = 4096; // 1M pool limit
|
||||
int64_t txnid = 0;
|
||||
SPoolMem *pPool;
|
||||
|
||||
// open the pool
|
||||
pPool = openPool();
|
||||
|
||||
// start a transaction
|
||||
txnid++;
|
||||
tdbTxnOpen(&txn, txnid, poolMalloc, poolFree, pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
|
||||
tdbBegin(pEnv, &txn);
|
||||
|
||||
for (int iData = 1; iData <= nData; iData++) {
|
||||
sprintf(key, "key0");
|
||||
sprintf(val, "value%d", iData);
|
||||
|
||||
//ret = tdbTbInsert(pDb, key, strlen(key), val, strlen(val), &txn);
|
||||
//GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
// generate value payload
|
||||
int valLen = sizeof(val) / sizeof(val[0]);
|
||||
for (int i = 6; i < valLen; ++i) {
|
||||
char c = char(i & 0xff);
|
||||
if (c == 0) {
|
||||
c = 1;
|
||||
}
|
||||
val[i] = c;
|
||||
}
|
||||
|
||||
ret = tdbTbInsert(pDb, "key1", strlen("key1"), val, valLen, &txn);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
// if pool is full, commit the transaction and start a new one
|
||||
if (pPool->size >= poolLimit) {
|
||||
// commit current transaction
|
||||
tdbCommit(pEnv, &txn);
|
||||
tdbTxnClose(&txn);
|
||||
|
||||
// start a new transaction
|
||||
clearPool(pPool);
|
||||
txnid++;
|
||||
tdbTxnOpen(&txn, txnid, poolMalloc, poolFree, pPool, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED);
|
||||
tdbBegin(pEnv, &txn);
|
||||
}
|
||||
}
|
||||
|
||||
// commit the transaction
|
||||
tdbCommit(pEnv, &txn);
|
||||
tdbTxnClose(&txn);
|
||||
|
||||
{ // Query the data
|
||||
void *pVal = NULL;
|
||||
int vLen;
|
||||
|
||||
for (int i = 1; i <= nData; i++) {
|
||||
sprintf(key, "key%d", i);
|
||||
sprintf(val, "value%d", i);
|
||||
|
||||
ret = tdbTbGet(pDb, key, strlen(key), &pVal, &vLen);
|
||||
ASSERT(ret == 0);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
GTEST_ASSERT_EQ(vLen, strlen(val));
|
||||
GTEST_ASSERT_EQ(memcmp(val, pVal, vLen), 0);
|
||||
}
|
||||
|
||||
tdbFree(pVal);
|
||||
}
|
||||
|
||||
{ // Iterate to query the DB data
|
||||
TBC *pDBC;
|
||||
void *pKey = NULL;
|
||||
void *pVal = NULL;
|
||||
int vLen, kLen;
|
||||
int count = 0;
|
||||
|
||||
ret = tdbTbcOpen(pDb, &pDBC, NULL);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
tdbTbcMoveToFirst(pDBC);
|
||||
|
||||
for (;;) {
|
||||
ret = tdbTbcNext(pDBC, &pKey, &kLen, &pVal, &vLen);
|
||||
if (ret < 0) break;
|
||||
|
||||
// std::cout.write((char *)pKey, kLen) /* << " " << kLen */ << " ";
|
||||
// std::cout.write((char *)pVal, vLen) /* << " " << vLen */;
|
||||
// std::cout << std::endl;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
GTEST_ASSERT_EQ(count, nData);
|
||||
|
||||
tdbTbcClose(pDBC);
|
||||
|
||||
tdbFree(pKey);
|
||||
tdbFree(pVal);
|
||||
}
|
||||
}
|
||||
|
||||
ret = tdbTbDrop(pDb);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
|
||||
// Close a database
|
||||
tdbTbClose(pDb);
|
||||
|
||||
// Close Env
|
||||
ret = tdbClose(pEnv);
|
||||
GTEST_ASSERT_EQ(ret, 0);
|
||||
}
|
|
@ -11,13 +11,20 @@
|
|||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from collections import defaultdict
|
||||
import random
|
||||
import string
|
||||
from util.sql import tdSql
|
||||
from util.dnodes import tdDnodes
|
||||
import requests
|
||||
import time
|
||||
import socket
|
||||
|
||||
import taos
|
||||
from util.log import *
|
||||
from util.sql import *
|
||||
from util.cases import *
|
||||
from util.dnodes import *
|
||||
from util.common import *
|
||||
|
||||
class TDCom:
|
||||
def init(self, conn, logSql):
|
||||
tdSql.init(conn.cursor(), logSql)
|
||||
|
@ -170,4 +177,122 @@ class TDCom:
|
|||
def close(self):
|
||||
self.cursor.close()
|
||||
|
||||
def create_database(self,tsql, dbName='test',dropFlag=1,precision="ms", **kwargs):
|
||||
if dropFlag == 1:
|
||||
tsql.execute("drop database if exists %s"%(dbName))
|
||||
'''
|
||||
vgroups replica precision strict wal fsync comp cachelast single_stable buffer pagesize pages minrows maxrows duration keep retentions
|
||||
'''
|
||||
sqlString = f'create database if not exists {dbName} precision "{precision}" vgroups 4'
|
||||
if len(kwargs) > 0:
|
||||
dbParams = ""
|
||||
for param, value in kwargs.items():
|
||||
dbParams += f'{param} {value} '
|
||||
sqlString += f'{dbParams}'
|
||||
|
||||
tsql.execute(sqlString)
|
||||
tdLog.debug("complete to create database %s"%(dbName))
|
||||
return
|
||||
|
||||
def create_stable(self,tsql, dbName,stbName,columnDict,tagDict):
|
||||
colSchema = ''
|
||||
for i in range(columnDict['int']):
|
||||
colSchema += ', c%d int'%i
|
||||
tagSchema = ''
|
||||
for i in range(tagDict['int']):
|
||||
if i > 0:
|
||||
tagSchema += ','
|
||||
tagSchema += 't%d int'%i
|
||||
|
||||
tsql.execute("create table if not exists %s.%s (ts timestamp %s) tags(%s)"%(dbName, stbName, colSchema, tagSchema))
|
||||
tdLog.debug("complete to create %s.%s" %(dbName, stbName))
|
||||
return
|
||||
|
||||
def create_ctables(self,tsql, dbName,stbName,ctbNum,tagDict):
|
||||
tsql.execute("use %s" %dbName)
|
||||
tagsValues = ''
|
||||
for i in range(tagDict['int']):
|
||||
if i > 0:
|
||||
tagsValues += ','
|
||||
tagsValues += '%d'%i
|
||||
|
||||
pre_create = "create table"
|
||||
sql = pre_create
|
||||
#tdLog.debug("doing create one stable %s and %d child table in %s ..." %(stbname, count ,dbname))
|
||||
for i in range(ctbNum):
|
||||
sql += " %s_%d using %s tags(%s)"%(stbName,i,stbName,tagsValues)
|
||||
if (i > 0) and (i%100 == 0):
|
||||
tsql.execute(sql)
|
||||
sql = pre_create
|
||||
if sql != pre_create:
|
||||
tsql.execute(sql)
|
||||
|
||||
tdLog.debug("complete to create %d child tables in %s.%s" %(ctbNum, dbName, stbName))
|
||||
return
|
||||
|
||||
def insert_data(self,tsql,dbName,stbName,ctbNum,rowsPerTbl,batchNum,startTs=0):
|
||||
tdLog.debug("start to insert data ............")
|
||||
tsql.execute("use %s" %dbName)
|
||||
pre_insert = "insert into "
|
||||
sql = pre_insert
|
||||
if startTs == 0:
|
||||
t = time.time()
|
||||
startTs = int(round(t * 1000))
|
||||
#tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows))
|
||||
for i in range(ctbNum):
|
||||
sql += " %s_%d values "%(stbName,i)
|
||||
for j in range(rowsPerTbl):
|
||||
sql += "(%d, %d, %d)"%(startTs + j, j, j)
|
||||
if (j > 0) and ((j%batchNum == 0) or (j == rowsPerTbl - 1)):
|
||||
tsql.execute(sql)
|
||||
if j < rowsPerTbl - 1:
|
||||
sql = "insert into %s_%d values " %(stbName,i)
|
||||
else:
|
||||
sql = "insert into "
|
||||
#end sql
|
||||
if sql != pre_insert:
|
||||
#print("insert sql:%s"%sql)
|
||||
tsql.execute(sql)
|
||||
tdLog.debug("insert data ............ [OK]")
|
||||
return
|
||||
|
||||
def getBuildPath(self):
|
||||
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if ("community" in selfPath):
|
||||
projPath = selfPath[:selfPath.find("community")]
|
||||
else:
|
||||
projPath = selfPath[:selfPath.find("tests")]
|
||||
|
||||
for root, dirs, files in os.walk(projPath):
|
||||
if ("taosd" in files or "taosd.exe" in files):
|
||||
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||
if ("packaging" not in rootRealPath):
|
||||
buildPath = root[:len(root) - len("/build/bin")]
|
||||
break
|
||||
return buildPath
|
||||
|
||||
def getClientCfgPath(self):
|
||||
buildPath = self.getBuildPath()
|
||||
if (buildPath == ""):
|
||||
tdLog.exit("taosd not found!")
|
||||
else:
|
||||
tdLog.info("taosd found in %s" % buildPath)
|
||||
cfgPath = buildPath + "/../sim/psim/cfg"
|
||||
tdLog.info("cfgPath: %s" % cfgPath)
|
||||
return cfgPath
|
||||
|
||||
def newcur(self,host='localhost',port=6030,user='root',password='taosdata'):
|
||||
cfgPath = self.getClientCfgPath()
|
||||
con=taos.connect(host=host, user=user, password=password, config=cfgPath, port=port)
|
||||
cur=con.cursor()
|
||||
print(cur)
|
||||
return cur
|
||||
|
||||
def newTdSql(self, host='localhost',port=6030,user='root',password='taosdata'):
|
||||
newTdSql = TDSql()
|
||||
cur = self.newcur(host=host,port=port,user=user,password=password)
|
||||
newTdSql.init(cur, False)
|
||||
return newTdSql
|
||||
|
||||
tdCom = TDCom()
|
||||
|
|
|
@ -72,13 +72,14 @@
|
|||
./test.sh -f tsim/stream/basic0.sim
|
||||
./test.sh -f tsim/stream/basic1.sim
|
||||
./test.sh -f tsim/stream/basic2.sim
|
||||
# ./test.sh -f tsim/stream/distributeInterval0.sim
|
||||
./test.sh -f tsim/stream/distributeInterval0.sim
|
||||
# ./test.sh -f tsim/stream/distributesession0.sim
|
||||
# ./test.sh -f tsim/stream/session0.sim
|
||||
# ./test.sh -f tsim/stream/session1.sim
|
||||
# ./test.sh -f tsim/stream/state0.sim
|
||||
# ./test.sh -f tsim/stream/triggerInterval0.sim
|
||||
./test.sh -f tsim/stream/triggerInterval0.sim
|
||||
# ./test.sh -f tsim/stream/triggerSession0.sim
|
||||
# ./test.sh -f tsim/stream/partitionby.sim
|
||||
./test.sh -f tsim/stream/partitionby.sim
|
||||
|
||||
|
||||
# ---- transaction
|
||||
|
|
|
@ -53,31 +53,10 @@ endi
|
|||
if $data(4)[4] != ready then
|
||||
goto step1
|
||||
endi
|
||||
#if $data(5)[4] != ready then
|
||||
# goto step1
|
||||
#endi
|
||||
|
||||
print =============== step2: create db
|
||||
sql create database d1 vgroups 1 replica 3
|
||||
|
||||
# dnode not exist
|
||||
sql_error redistribute vgroup 3 dnode 6 dnode 3 dnode 4
|
||||
# vgroup not exist
|
||||
sql_error redistribute vgroup 3 dnode 5 dnode 3 dnode 4
|
||||
# un changed
|
||||
sql_error redistribute vgroup 2 dnode 2 dnode 3 dnode 4
|
||||
# no enought vnodes
|
||||
sql_error redistribute vgroup 2 dnode 1 dnode 3 dnode 4
|
||||
# offline vnodes
|
||||
sql_error redistribute vgroup 2 dnode 5 dnode 3 dnode 4
|
||||
# Invalid replica
|
||||
sql_error redistribute vgroup 2 dnode 5
|
||||
sql_error redistribute vgroup 2 dnode 5 dnode 3
|
||||
sql_error redistribute vgroup 2 dnode 2 dnode 3
|
||||
sql_error redistribute vgroup 2 dnode 2 dnode 2
|
||||
sql_error redistribute vgroup 3 dnode 2 dnode 2
|
||||
sql_error redistribute vgroup 2 dnode 2 dnode 2 dnode 3
|
||||
|
||||
system sh/exec.sh -n dnode5 -s start
|
||||
$x = 0
|
||||
step2:
|
||||
|
|
|
@ -5,7 +5,7 @@ sleep 50
|
|||
sql connect
|
||||
|
||||
print =============== create database with retentions
|
||||
sql create database d0 retentions 15s:7d,1m:21d,15m:365d;
|
||||
sql create database d0 retentions 5s:7d,10s:21d,15s:365d;
|
||||
sql use d0
|
||||
|
||||
print =============== create super table and register rsma
|
||||
|
@ -29,6 +29,8 @@ sql insert into ct1 values(now, 10);
|
|||
sql insert into ct1 values(now+1s, 1);
|
||||
sql insert into ct1 values(now+2s, 100);
|
||||
|
||||
print =============== wait maxdelay 15+1 seconds for results
|
||||
sleep 16000
|
||||
|
||||
print =============== select * from retention level 2 from memory
|
||||
sql select * from ct1;
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
system sh/stop_dnodes.sh
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/deploy.sh -n dnode2 -i 2
|
||||
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sleep 50
|
||||
sql connect
|
||||
|
||||
sql create dnode $hostname2 port 7200
|
||||
|
||||
system sh/exec.sh -n dnode2 -s start
|
||||
|
||||
sql create database test vgroups 4;
|
||||
sql use test;
|
||||
sql create stable st(ts timestamp,a int,b int,c int) tags(ta int,tb int,tc int);
|
||||
sql create table ts1 using st tags(1,1,1);
|
||||
sql create table ts2 using st tags(2,2,2);
|
||||
sql create stream stream_t1 trigger at_once into streamtST as select _wstartts, count(*) c1, sum(a) c2 , max(b) c3 from st session(ts, 10s) ;
|
||||
|
||||
sleep 1000
|
||||
|
||||
sql insert into ts1 values(1648791211000,1,1,1) (1648791211005,1,1,1);
|
||||
sql insert into ts2 values(1648791221004,1,2,3) (1648791221008,2,2,3);
|
||||
sql insert into ts1 values(1648791211005,1,1,1);
|
||||
sql insert into ts2 values(1648791221006,5,5,5) (1648791221007,5,5,5);
|
||||
sql insert into ts2 values(1648791221008,5,5,5) (1648791221008,5,5,5)(1648791221006,5,5,5);
|
||||
sql insert into ts1 values(1648791231000,1,1,1) (1648791231002,1,1,1) (1648791231006,1,1,1);
|
||||
sql insert into ts1 values(1648791211000,6,6,6) (1648791231002,2,2,2);
|
||||
sql insert into ts1 values(1648791211002,7,7,7);
|
||||
sql insert into ts1 values(1648791211002,7,7,7) ts2 values(1648791221008,5,5,5) ;
|
||||
|
||||
$loop_count = 0
|
||||
loop1:
|
||||
sql select * from streamtST;
|
||||
|
||||
sleep 300
|
||||
$loop_count = $loop_count + 1
|
||||
if $loop_count == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# row 0
|
||||
if $data01 != 10 then
|
||||
print =====data01=$data01
|
||||
goto loop1
|
||||
endi
|
||||
|
||||
if $data02 != 34 then
|
||||
print =====data02=$data02
|
||||
goto loop1
|
||||
endi
|
||||
|
||||
if $data03 != 7 then
|
||||
print ======$data03
|
||||
return -1
|
||||
endi
|
||||
|
||||
system sh/stop_dnodes.sh
|
|
@ -1,113 +0,0 @@
|
|||
###################################################################
|
||||
# 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 random
|
||||
import string
|
||||
from util.log import *
|
||||
from util.cases import *
|
||||
from util.sql import *
|
||||
|
||||
class TDTestCase:
|
||||
def init(self, conn, logSql):
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor())
|
||||
|
||||
def get_long_name(self, length, mode="mixed"):
|
||||
"""
|
||||
generate long name
|
||||
mode could be numbers/letters/letters_mixed/mixed
|
||||
"""
|
||||
if mode == "numbers":
|
||||
population = string.digits
|
||||
elif mode == "letters":
|
||||
population = string.ascii_letters.lower()
|
||||
elif mode == "letters_mixed":
|
||||
population = string.ascii_letters.upper() + string.ascii_letters.lower()
|
||||
else:
|
||||
population = string.ascii_letters.lower() + string.digits
|
||||
return "".join(random.choices(population, k=length))
|
||||
|
||||
def __create_tb(self,dbname,stbname,tbname,comment):
|
||||
tdSql.execute(f'create database if not exists {dbname}')
|
||||
tdSql.execute(f'use {dbname}')
|
||||
tdSql.execute(
|
||||
f'create table {stbname} (ts timestamp,c0 int) tags(t0 int) ')
|
||||
tdSql.execute(
|
||||
f'create table {tbname} using {stbname} tags(1) comment "{comment}"')
|
||||
def __create_normaltb(self,dbname,tbname,comment):
|
||||
tdSql.execute(f'create database if not exists {dbname}')
|
||||
tdSql.execute(f'use {dbname}')
|
||||
tdSql.execute(
|
||||
f'create table {tbname} (ts timestamp,c0 int) comment "{comment}"')
|
||||
|
||||
def check_comment(self):
|
||||
dbname = self.get_long_name(length=10, mode="letters")
|
||||
ntbname = self.get_long_name(length=5, mode="letters")
|
||||
|
||||
# create normal table with comment
|
||||
comment = self.get_long_name(length=10, mode="letters")
|
||||
self.__create_normaltb(dbname,ntbname,comment)
|
||||
ntb_kv_list = tdSql.getResult("show tables")
|
||||
print(ntb_kv_list)
|
||||
tdSql.checkEqual(ntb_kv_list[0][8], comment)
|
||||
tdSql.error('alter table {ntbname} comment "test1"')
|
||||
tdSql.execute(f'drop database {dbname}')
|
||||
|
||||
# max length(1024)
|
||||
comment = self.get_long_name(length=1024, mode="letters")
|
||||
self.__create_normaltb(dbname,ntbname,comment)
|
||||
ntb_kv_list = tdSql.getResult("show tables")
|
||||
tdSql.checkEqual(ntb_kv_list[0][8], comment)
|
||||
tdSql.execute(f'drop database {dbname}')
|
||||
|
||||
# error overlength
|
||||
comment = self.get_long_name(length=1025, mode="letters")
|
||||
tdSql.execute(f'create database if not exists {dbname}')
|
||||
tdSql.execute(f'use {dbname}')
|
||||
tdSql.error(f"create table ntb (ts timestamp,c0 int) comment '{comment}'")
|
||||
tdSql.execute(f'drop database {dbname}')
|
||||
|
||||
# create child table with comment
|
||||
comment = self.get_long_name(length=10, mode="letters")
|
||||
stbname = self.get_long_name(length=5, mode="letters")
|
||||
tbname = self.get_long_name(length=3, mode="letters")
|
||||
self.__create_tb(dbname,stbname,tbname,comment)
|
||||
ntb_kv_list = tdSql.getResult("show tables")
|
||||
tdSql.checkEqual(ntb_kv_list[0][8], comment)
|
||||
tdSql.error(f'alter table {tbname} comment "test1"')
|
||||
tdSql.execute(f'drop database {dbname}')
|
||||
|
||||
# max length 1024
|
||||
comment = self.get_long_name(length=1024, mode="letters")
|
||||
self.__create_tb(dbname,ntbname,comment)
|
||||
ntb_kv_list = tdSql.getResult("show tables")
|
||||
tdSql.checkEqual(ntb_kv_list[0][8], comment)
|
||||
tdSql.execute(f'drop database {dbname}')
|
||||
|
||||
# error overlength
|
||||
comment = self.get_long_name(length=1025, mode="letters")
|
||||
tdSql.execute(f'create database if not exists {dbname}')
|
||||
tdSql.execute(f'use {dbname}')
|
||||
tdSql.execute(f"create table stb (ts timestamp,c0 int) tags(t0 int)")
|
||||
tdSql.error(f'create table stb_1 us stb tags(1) comment "{comment}"')
|
||||
tdSql.execute(f'drop database {dbname}')
|
||||
|
||||
def run(self):
|
||||
self.check_comment()
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -0,0 +1,134 @@
|
|||
###################################################################
|
||||
# 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 random
|
||||
import string
|
||||
|
||||
from util.log import *
|
||||
from util.cases import *
|
||||
from util.sql import *
|
||||
from util.common import *
|
||||
|
||||
class TDTestCase:
|
||||
def init(self, conn, logSql):
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor())
|
||||
# prepare data
|
||||
self.ntbname = 'ntb'
|
||||
self.stbname = 'stb'
|
||||
self.column_dict = {
|
||||
'ts':'timestamp',
|
||||
'c1':'int',
|
||||
'c2':'float',
|
||||
'c3':'double',
|
||||
'c4':'timestamp'
|
||||
}
|
||||
self.tag_dict = {
|
||||
't0':'int'
|
||||
}
|
||||
self.comment_length = [0,1024]
|
||||
self.error_comment_length = [1025]
|
||||
self.table_type_list = ['normal_table','stable','child_table']
|
||||
self.comment_flag_list = [True,False]
|
||||
|
||||
def __set_and_alter_comment(self,tb_type='',comment_flag= False):
|
||||
|
||||
column_sql = ''
|
||||
tag_sql = ''
|
||||
for k,v in self.column_dict.items():
|
||||
column_sql += f"{k} {v},"
|
||||
for k,v in self.tag_dict.items():
|
||||
tag_sql += f"{k} {v},"
|
||||
if tb_type == 'normal_table' or tb_type == '':
|
||||
if comment_flag == False:
|
||||
tdSql.execute(f'create table {self.ntbname} ({column_sql[:-1]})')
|
||||
self.check_comment_info()
|
||||
self.alter_comment(self.ntbname)
|
||||
tdSql.execute(f'drop table {self.ntbname}')
|
||||
elif comment_flag == True:
|
||||
for i in self.comment_length:
|
||||
comment_info = tdCom.getLongName(i)
|
||||
tdSql.execute(f'create table {self.ntbname} ({column_sql[:-1]}) comment "{comment_info}"')
|
||||
self.check_comment_info(comment_info)
|
||||
self.alter_comment(self.ntbname)
|
||||
tdSql.execute(f'drop table {self.ntbname}')
|
||||
for i in self.error_comment_length:
|
||||
comment_info = tdCom.getLongName(i)
|
||||
tdSql.error(f'create table {self.ntbname} ({column_sql[:-1]}) comment "{comment_info}"')
|
||||
elif tb_type == 'stable':
|
||||
for operation in ['table','stable']:
|
||||
if comment_flag == False:
|
||||
tdSql.execute(f'create {operation} {self.stbname} ({column_sql[:-1]}) tags({tag_sql[:-1]})')
|
||||
self.check_comment_info(None,'stable')
|
||||
self.alter_comment(self.stbname,'stable')
|
||||
tdSql.execute(f'drop table {self.stbname}')
|
||||
elif comment_flag == True:
|
||||
for i in self.comment_length:
|
||||
comment_info = tdCom.getLongName(i)
|
||||
tdSql.execute(f'create {operation} {self.stbname} ({column_sql[:-1]}) tags({tag_sql[:-1]}) comment "{comment_info}"')
|
||||
self.check_comment_info(comment_info,'stable')
|
||||
self.alter_comment(self.stbname,'stable')
|
||||
tdSql.execute(f'drop table {self.stbname}')
|
||||
elif tb_type == 'child_table':
|
||||
tdSql.execute(f'create table if not exists {self.stbname} ({column_sql[:-1]}) tags({tag_sql[:-1]})')
|
||||
if comment_flag == False:
|
||||
tdSql.execute(f'create table if not exists {self.stbname}_ctb using {self.stbname} tags(1)')
|
||||
self.check_comment_info()
|
||||
self.alter_comment(f'{self.stbname}_ctb')
|
||||
tdSql.execute(f'drop table {self.stbname}_ctb')
|
||||
elif comment_flag == True:
|
||||
for j in self.comment_length:
|
||||
comment_info = tdCom.getLongName(j)
|
||||
tdSql.execute(f'create table if not exists {self.stbname}_ctb using {self.stbname} tags(1) comment "{comment_info}"')
|
||||
self.check_comment_info(comment_info)
|
||||
self.alter_comment(f'{self.stbname}_ctb')
|
||||
tdSql.execute(f'drop table {self.stbname}_ctb')
|
||||
tdSql.execute(f'drop table {self.stbname}')
|
||||
def alter_comment(self,tbname,tb_type=''):
|
||||
for i in self.comment_length:
|
||||
comment_info = tdCom.getLongName(i)
|
||||
print(comment_info)
|
||||
tdSql.execute(f'alter table {tbname} comment "{comment_info}"')
|
||||
self.check_comment_info(comment_info,tb_type)
|
||||
for i in self.error_comment_length:
|
||||
comment_info = tdCom.getLongName(i)
|
||||
tdSql.error(f'alter table {tbname} comment "{comment_info}"')
|
||||
def check_comment_info(self,comment_info=None,tb_type=''):
|
||||
if tb_type == '' or tb_type == 'normal_table' or tb_type == 'child_table':
|
||||
tdSql.query('show tables')
|
||||
if comment_info == None:
|
||||
tdSql.checkEqual(tdSql.queryResult[0][8],None)
|
||||
else :
|
||||
tdSql.checkEqual(tdSql.queryResult[0][8],comment_info)
|
||||
elif tb_type == 'stable':
|
||||
tdSql.query('show stables')
|
||||
if comment_info == None:
|
||||
tdSql.checkEqual(tdSql.queryResult[0][6],None)
|
||||
else :
|
||||
tdSql.checkEqual(tdSql.queryResult[0][6],comment_info)
|
||||
def comment_check_case(self,table_type,comment_flag):
|
||||
tdSql.prepare()
|
||||
for tb in table_type:
|
||||
for flag in comment_flag:
|
||||
self.__set_and_alter_comment(tb,flag)
|
||||
tdSql.execute('drop database db')
|
||||
|
||||
def run(self):
|
||||
self.comment_check_case(self.table_type_list,self.comment_flag_list)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -4,394 +4,163 @@ from util.dnodes import *
|
|||
from util.log import *
|
||||
from util.sql import *
|
||||
from util.cases import *
|
||||
import datetime
|
||||
|
||||
|
||||
class TDTestCase:
|
||||
|
||||
updatecfgDict = {'rpcDebugFlag': '143'}
|
||||
def init(self, conn, logSql):
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
tdSql.init(conn.cursor())
|
||||
self.today_date = datetime.datetime.strptime(
|
||||
datetime.datetime.now().strftime("%Y-%m-%d"), "%Y-%m-%d")
|
||||
self.time_unit = ['b','u','a','s','m','h','d','w']
|
||||
self.error_param = ['1.5','abc','!@#','"abc"','today()']
|
||||
self.arithmetic_operators = ['+','-','*','/']
|
||||
self.relational_operator = ['<','<=','=','>=','>']
|
||||
# prepare data
|
||||
self.ntbname = 'ntb'
|
||||
self.stbname = 'stb'
|
||||
self.column_dict = {
|
||||
'ts':'timestamp',
|
||||
'c1':'int',
|
||||
'c2':'float',
|
||||
'c3':'double',
|
||||
'c4':'timestamp'
|
||||
}
|
||||
self.tag_dict = {
|
||||
't0':'int'
|
||||
}
|
||||
self.tbnum = 2
|
||||
self.tag_values = [
|
||||
f'10',
|
||||
f'100'
|
||||
]
|
||||
self.values_list = [f'now,1,1.55,100.555555,today()',
|
||||
f'now+1d,10,11.11,99.999999,now()',
|
||||
f'today(),3,3.333,333.333333,now()',
|
||||
f'today()-1d,10,11.11,99.999999,now()',
|
||||
f'today()+1d,1,1.55,100.555555,today()']
|
||||
|
||||
def set_create_normaltable_sql(self, ntbname, column_dict):
|
||||
column_sql = ''
|
||||
for k, v in column_dict.items():
|
||||
column_sql += f"{k} {v},"
|
||||
create_ntb_sql = f'create table {ntbname} ({column_sql[:-1]})'
|
||||
return create_ntb_sql
|
||||
def set_create_stable_sql(self,stbname,column_dict,tag_dict):
|
||||
column_sql = ''
|
||||
tag_sql = ''
|
||||
for k,v in column_dict.items():
|
||||
column_sql += f"{k} {v},"
|
||||
for k,v in tag_dict.items():
|
||||
tag_sql += f"{k} {v},"
|
||||
create_stb_sql = f'create table {stbname} ({column_sql[:-1]}) tags({tag_sql[:-1]})'
|
||||
return create_stb_sql
|
||||
def data_check(self,column_dict={},tbname = '',values_list = [],tb_num = 1,tb = 'tb'):
|
||||
for k,v in column_dict.items():
|
||||
num_up = 0
|
||||
num_down = 0
|
||||
num_same = 0
|
||||
if v.lower() == 'timestamp':
|
||||
tdSql.query(f'select {k} from {tbname}')
|
||||
for i in tdSql.queryResult:
|
||||
if i[0] > self.today_date:
|
||||
num_up += 1
|
||||
elif i[0] == self.today_date:
|
||||
num_same += 1
|
||||
elif i[0] < self.today_date:
|
||||
num_down += 1
|
||||
tdSql.query(f"select today() from {tbname}")
|
||||
tdSql.checkRows(len(values_list)*tb_num)
|
||||
tdSql.checkData(0, 0, str(self.today_date))
|
||||
tdSql.query(f"select * from {tbname} where {k}=today()")
|
||||
if tb == 'tb':
|
||||
tdSql.checkRows(num_same*tb_num)
|
||||
elif tb == 'stb':
|
||||
tdSql.checkRows(num_same)
|
||||
for i in [f'{tbname}',f'db.{tbname}']:
|
||||
for unit in self.time_unit:
|
||||
for symbol in ['+','-']:
|
||||
tdSql.query(f"select today() {symbol}1{unit} from {i}")
|
||||
tdSql.checkRows(len(values_list)*tb_num)
|
||||
for unit in self.error_param:
|
||||
for symbol in self.arithmetic_operators:
|
||||
tdSql.error(f'select today() {symbol}{unit} from {i}')
|
||||
for symbol in self.arithmetic_operators:
|
||||
tdSql.query(f'select now(){symbol}null from {i}')
|
||||
tdSql.checkData(0,0,None)
|
||||
for symbol in self.relational_operator:
|
||||
tdSql.query(f'select * from {i} where {k} {symbol} today()')
|
||||
if symbol == '<' :
|
||||
if tb == 'tb':
|
||||
tdSql.checkRows(num_down*tb_num)
|
||||
elif tb == 'stb':
|
||||
tdSql.checkRows(num_down)
|
||||
elif symbol == '<=':
|
||||
if tb == 'tb':
|
||||
tdSql.checkRows((num_same+num_down)*tb_num)
|
||||
elif tb == 'stb':
|
||||
tdSql.checkRows(num_same+num_down)
|
||||
elif symbol == '=':
|
||||
if tb == 'tb':
|
||||
tdSql.checkRows(num_same*tb_num)
|
||||
elif tb == 'stb':
|
||||
tdSql.checkRows(num_same)
|
||||
elif symbol == '>=':
|
||||
if tb == 'tb':
|
||||
tdSql.checkRows((num_up + num_same)*tb_num)
|
||||
elif tb == 'stb':
|
||||
tdSql.checkRows(num_up + num_same)
|
||||
elif symbol == '>':
|
||||
if tb == 'tb':
|
||||
tdSql.checkRows(num_up*tb_num)
|
||||
elif tb == 'stb':
|
||||
tdSql.checkRows(num_up)
|
||||
tdSql.query(f"select today()/0 from {tbname}")
|
||||
tdSql.checkRows(len(values_list)*tb_num)
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query(f"select {k} from {tbname} where {k}=today()")
|
||||
if tb == 'tb':
|
||||
tdSql.checkRows(num_same*tb_num)
|
||||
for i in range(num_same*tb_num):
|
||||
tdSql.checkData(i, 0, str(self.today_date))
|
||||
elif tb == 'stb':
|
||||
tdSql.checkRows(num_same)
|
||||
for i in range(num_same):
|
||||
tdSql.checkData(i, 0, str(self.today_date))
|
||||
def today_check_ntb(self):
|
||||
tdSql.prepare()
|
||||
tdSql.execute(self.set_create_normaltable_sql(self.ntbname,self.column_dict))
|
||||
for i in self.values_list:
|
||||
tdSql.execute(
|
||||
f'insert into {self.ntbname} values({i})')
|
||||
self.data_check(self.column_dict,self.ntbname,self.values_list)
|
||||
tdSql.execute('drop database db')
|
||||
def today_check_stb_tb(self):
|
||||
tdSql.prepare()
|
||||
tdSql.execute(self.set_create_stable_sql(self.stbname,self.column_dict,self.tag_dict))
|
||||
for i in range(self.tbnum):
|
||||
tdSql.execute(f'create table if not exists {self.stbname}_{i} using {self.stbname} tags({self.tag_values[i]})')
|
||||
for j in self.values_list:
|
||||
tdSql.execute(f'insert into {self.stbname}_{i} values ({j})')
|
||||
# check child table
|
||||
for i in range(self.tbnum):
|
||||
self.data_check(self.column_dict,f'{self.stbname}_{i}',self.values_list)
|
||||
# check stable
|
||||
self.data_check(self.column_dict,self.stbname,self.values_list,self.tbnum,'stb')
|
||||
tdSql.execute('drop database db')
|
||||
|
||||
def run(self): # sourcery skip: extract-duplicate-method
|
||||
# for func now() , today(), timezone()
|
||||
tdSql.prepare()
|
||||
today_date = datetime.datetime.strptime(
|
||||
datetime.datetime.now().strftime("%Y-%m-%d"), "%Y-%m-%d")
|
||||
|
||||
tdLog.printNoPrefix("==========check today() for normal table ==========")
|
||||
self.today_check_ntb()
|
||||
tdLog.printNoPrefix("==========check today() for stable and child table==========")
|
||||
self.today_check_stb_tb()
|
||||
|
||||
tdLog.printNoPrefix("==========step1:create tables==========")
|
||||
tdSql.execute(
|
||||
'''create table if not exists ntb
|
||||
(ts timestamp, c1 int, c2 float,c3 double,c4 timestamp)
|
||||
'''
|
||||
)
|
||||
tdSql.execute(
|
||||
'''create table if not exists stb
|
||||
(ts timestamp, c1 int, c2 float,c3 double,c4 timestamp) tags(t0 int)
|
||||
'''
|
||||
)
|
||||
tdSql.execute(
|
||||
'''create table if not exists stb_1 using stb tags(100)
|
||||
'''
|
||||
)
|
||||
tdLog.printNoPrefix("==========step2:insert data into ntb==========")
|
||||
tdSql.execute(
|
||||
'insert into ntb values(now,1,1.55,100.555555,today())("2020-1-1 00:00:00",10,11.11,99.999999,now())(today(),3,3.333,333.333333,now())')
|
||||
tdSql.execute(
|
||||
'insert into stb_1 values(now,1,1.55,100.555555,today())("2020-1-1 00:00:00",10,11.11,99.999999,now())(today(),3,3.333,333.333333,now())')
|
||||
tdLog.printNoPrefix("==========step2:query test of ntb ==========")
|
||||
|
||||
# test function today()
|
||||
# normal table
|
||||
tdSql.query("select today() from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.checkData(0, 0, str(today_date))
|
||||
tdSql.query("select today() from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.checkData(0, 0, str(today_date))
|
||||
tdSql.query("select today() +1w from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1w from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1d from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1d from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1h from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1h from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1m from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1m from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1s from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1s from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1a from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1a from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1u from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1u from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1b from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1b from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1w from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1w from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1d from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1d from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1h from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1h from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1m from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1m from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1s from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1s from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1a from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1a from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1u from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1u from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1b from ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1b from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select * from ntb where ts=today()")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 1, 3)
|
||||
tdSql.query("select * from ntb where ts<=today()")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 1, 10)
|
||||
# for bug
|
||||
# tdSql.query("select * from ntb where ts<today()")
|
||||
# tdSql.checkRows(1)
|
||||
tdSql.query("select * from ntb where ts>=today()")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.checkData(0, 1, 3)
|
||||
# tdSql.query("select * from ntb where ts>today()")
|
||||
# tdSql.checkRows(1)
|
||||
tdSql.query("select c4 from ntb where c4=today()")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, str(today_date))
|
||||
tdSql.query("select today() from ntb where ts<now()")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.checkData(0, 0, str(today_date))
|
||||
|
||||
tdSql.error("select today()+1.5 from ntb")
|
||||
tdSql.error("select today()-1.5 from ntb")
|
||||
tdSql.error("select today()*1.5 from ntb")
|
||||
tdSql.error("select today()/1.5 from ntb")
|
||||
tdSql.error("select today()+1.5 from db.ntb")
|
||||
tdSql.error("select today()-1.5 from db.ntb")
|
||||
tdSql.error("select today()*1.5 from db.ntb")
|
||||
tdSql.error("select today()/1.5 from db.ntb")
|
||||
tdSql.query("select today()+null from ntb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()+null from db.ntb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()-null from ntb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()-null from db.ntb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()*null from ntb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()*null from db.ntb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()/null from ntb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()/null from db.ntb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()/0 from db.ntb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.checkData(1,0,None)
|
||||
tdSql.checkData(2,0,None)
|
||||
# stable
|
||||
tdSql.query("select today() from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.checkData(0, 0, str(today_date))
|
||||
tdSql.query("select today() +1w from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1w from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1d from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1d from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1h from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1h from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1m from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1m from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1s from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1s from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1a from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1a from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1u from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1u from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1b from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1b from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1w from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1w from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1d from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1d from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1h from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1h from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1m from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1m from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1s from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1s from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1a from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1a from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1u from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1u from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1b from stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1b from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select ts from stb where ts=today()")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, str(today_date))
|
||||
tdSql.query("select ts from stb where ts<=today()")
|
||||
tdSql.checkRows(2)
|
||||
|
||||
tdSql.error("select today()+1.5 from stb")
|
||||
tdSql.error("select today()-1.5 from stb")
|
||||
tdSql.error("select today()*1.5 from stb")
|
||||
tdSql.error("select today()/1.5 from stb")
|
||||
tdSql.query("select today()+null from stb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()+null from db.stb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()-null from stb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()-null from db.stb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()*null from stb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()*null from db.stb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()/null from stb")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()/null from db.stb")
|
||||
tdSql.checkData(0,0,None)
|
||||
#
|
||||
# tdSql.query("select * from ntb where ts<today()")
|
||||
# tdSql.checkRows(1)
|
||||
# tdSql.query("select * from stb where ts>=today()")
|
||||
# tdSql.checkRows(2)
|
||||
# tdSql.query("select * from ntb where ts>today()")
|
||||
# tdSql.checkRows(1)
|
||||
tdSql.query("select c4 from stb where c4=today()")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, str(today_date))
|
||||
tdSql.query("select today() from stb where ts<now()")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today()/0 from db.stb")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.checkData(1,0,None)
|
||||
tdSql.checkData(2,0,None)
|
||||
|
||||
# table
|
||||
tdSql.query("select today() from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.checkData(0, 0, str(today_date))
|
||||
tdSql.query("select today() from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.checkData(0, 0, str(today_date))
|
||||
tdSql.query("select today() +1w from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1w from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1d from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1d from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1h from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1h from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1m from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1m from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1s from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1s from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1a from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1a from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1u from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1u from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1b from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() +1b from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1w from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1w from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1d from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1d from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1h from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1h from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1m from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1m from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1s from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1s from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1a from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1a from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1u from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1u from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1b from stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select today() -1b from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.query("select ts from stb_1 where ts=today()")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0, 0, str(today_date))
|
||||
tdSql.query("select ts from stb_1 where ts<=today()")
|
||||
tdSql.checkRows(2)
|
||||
# for bug
|
||||
tdSql.query("select * from ntb where ts<today()")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.checkData(0,0,"2020-1-1 00:00:00")
|
||||
tdSql.query("select * from stb_1 where ts>=today()")
|
||||
tdSql.checkRows(2)
|
||||
tdSql.query("select * from ntb where ts>today()")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.query("select c4 from stb_1 where c4=today()")
|
||||
tdSql.checkRows(1)
|
||||
tdSql.query("select today() from stb_1 where ts<now()")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.error("select today()+1.5 from stb_1")
|
||||
tdSql.error("select today()-1.5 from stb_1")
|
||||
tdSql.error("select today()*1.5 from stb_1")
|
||||
tdSql.error("select today()/1.5 from stb_1")
|
||||
tdSql.query("select today()+null from stb_1")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()+null from db.stb_1")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()-null from stb_1")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()-null from db.stb_1")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()*null from stb_1")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()*null from db.stb_1")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()/null from stb_1")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()/null from db.stb_1")
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.query("select today()/0 from db.stb_1")
|
||||
tdSql.checkRows(3)
|
||||
tdSql.checkData(0,0,None)
|
||||
tdSql.checkData(1,0,None)
|
||||
tdSql.checkData(2,0,None)
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
|
|
|
@ -75,7 +75,7 @@ class TDTestCase:
|
|||
testCluster = False
|
||||
valgrind = 0
|
||||
hostname = socket.gethostname()
|
||||
print(hostname)
|
||||
tdLog.debug(hostname)
|
||||
dnodes = []
|
||||
start_port = 6030
|
||||
start_port_sec = 6130
|
||||
|
@ -102,12 +102,12 @@ class TDTestCase:
|
|||
|
||||
# create cluster
|
||||
for dnode in self.TDDnodes.dnodes[1:]:
|
||||
# print(dnode.cfgDict)
|
||||
# tdLog.debug(dnode.cfgDict)
|
||||
dnode_id = dnode.cfgDict["fqdn"] + ":" +dnode.cfgDict["serverPort"]
|
||||
dnode_first_host = dnode.cfgDict["firstEp"].split(":")[0]
|
||||
dnode_first_port = dnode.cfgDict["firstEp"].split(":")[-1]
|
||||
cmd = f" taos -h {dnode_first_host} -P {dnode_first_port} -s ' create dnode \"{dnode_id} \" ' ;"
|
||||
print(cmd)
|
||||
tdLog.debug(cmd)
|
||||
os.system(cmd)
|
||||
|
||||
time.sleep(2)
|
||||
|
@ -119,26 +119,26 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='leader' :
|
||||
if tdSql.queryResult[1][2]=='follower':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("three mnodes is ready in 10s")
|
||||
tdLog.debug("three mnodes is ready in 10s")
|
||||
break
|
||||
elif tdSql.queryResult[0][2]=='follower' :
|
||||
if tdSql.queryResult[1][2]=='leader':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("three mnodes is ready in 10s")
|
||||
tdLog.debug("three mnodes is ready in 10s")
|
||||
break
|
||||
elif tdSql.queryResult[0][2]=='follower' :
|
||||
if tdSql.queryResult[1][2]=='follower':
|
||||
if tdSql.queryResult[2][2]=='leader':
|
||||
print("three mnodes is ready in 10s")
|
||||
tdLog.debug("three mnodes is ready in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print(tdSql.queryResult)
|
||||
print("three mnodes is not ready in 10s ")
|
||||
tdLog.debug(tdSql.queryResult)
|
||||
tdLog.debug("three mnodes is not ready in 10s ")
|
||||
return -1
|
||||
|
||||
tdSql.query("show mnodes;")
|
||||
|
@ -156,19 +156,19 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='offline' :
|
||||
if tdSql.queryResult[1][2]=='leader':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("stop mnodes on dnode 2 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 2 successfully in 10s")
|
||||
break
|
||||
elif tdSql.queryResult[1][2]=='follower':
|
||||
if tdSql.queryResult[2][2]=='leader':
|
||||
print("stop mnodes on dnode 2 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 2 successfully in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("stop mnodes on dnode 2 failed in 10s ")
|
||||
tdLog.debug("stop mnodes on dnode 2 failed in 10s ")
|
||||
return -1
|
||||
tdSql.error("drop mnode on dnode 1;")
|
||||
|
||||
|
@ -188,15 +188,15 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='leader' :
|
||||
if tdSql.queryResult[1][2]=='offline':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("stop mnodes on dnode 2 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 2 successfully in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("stop mnodes on dnode 2 failed in 10s ")
|
||||
tdLog.debug("stop mnodes on dnode 2 failed in 10s ")
|
||||
return -1
|
||||
tdSql.error("drop mnode on dnode 2;")
|
||||
|
||||
|
@ -218,15 +218,15 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='leader' :
|
||||
if tdSql.queryResult[2][2]=='offline':
|
||||
if tdSql.queryResult[1][2]=='follower':
|
||||
print("stop mnodes on dnode 3 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 3 successfully in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("stop mnodes on dnode 3 failed in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 3 failed in 10s")
|
||||
return -1
|
||||
tdSql.error("drop mnode on dnode 3;")
|
||||
tdSql.query("show mnodes;")
|
||||
|
@ -268,7 +268,7 @@ class TDTestCase:
|
|||
tdSql.error("drop mnode on dnode 1")
|
||||
|
||||
tdSql.query("show dnodes;")
|
||||
print(tdSql.queryResult)
|
||||
tdLog.debug(tdSql.queryResult)
|
||||
|
||||
# drop follower of mnode
|
||||
dropcount =0
|
||||
|
@ -282,7 +282,7 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(2):
|
||||
print("drop mnode %d successfully"%(i+1))
|
||||
tdLog.debug("drop mnode %d successfully"%(i+1))
|
||||
break
|
||||
count+=1
|
||||
tdLog.debug("create mnode on dnode %d"%(i+1))
|
||||
|
@ -292,7 +292,7 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3):
|
||||
print("drop mnode %d successfully"%(i+1))
|
||||
tdLog.debug("drop mnode %d successfully"%(i+1))
|
||||
break
|
||||
count+=1
|
||||
dropcount+=1
|
||||
|
@ -307,7 +307,7 @@ class TDTestCase:
|
|||
|
||||
|
||||
def run(self):
|
||||
# print(self.master_dnode.cfgDict)
|
||||
# tdLog.debug(self.master_dnode.cfgDict)
|
||||
self.buildcluster(5)
|
||||
self.five_dnode_three_mnode()
|
||||
|
||||
|
|
|
@ -99,12 +99,12 @@ class TDTestCase:
|
|||
|
||||
# create cluster
|
||||
for dnode in self.TDDnodes.dnodes[1:]:
|
||||
# print(dnode.cfgDict)
|
||||
# tdLog.debug(dnode.cfgDict)
|
||||
dnode_id = dnode.cfgDict["fqdn"] + ":" +dnode.cfgDict["serverPort"]
|
||||
dnode_first_host = dnode.cfgDict["firstEp"].split(":")[0]
|
||||
dnode_first_port = dnode.cfgDict["firstEp"].split(":")[-1]
|
||||
cmd = f" taos -h {dnode_first_host} -P {dnode_first_port} -s ' create dnode \"{dnode_id} \" ' ;"
|
||||
print(cmd)
|
||||
tdLog.debug(cmd)
|
||||
os.system(cmd)
|
||||
|
||||
time.sleep(2)
|
||||
|
@ -116,25 +116,25 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='leader' :
|
||||
if tdSql.queryResult[1][2]=='follower':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("three mnodes is ready in 10s")
|
||||
tdLog.debug("three mnodes is ready in 10s")
|
||||
break
|
||||
elif tdSql.queryResult[0][2]=='follower' :
|
||||
if tdSql.queryResult[1][2]=='leader':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("three mnodes is ready in 10s")
|
||||
tdLog.debug("three mnodes is ready in 10s")
|
||||
break
|
||||
elif tdSql.queryResult[0][2]=='follower' :
|
||||
if tdSql.queryResult[1][2]=='follower':
|
||||
if tdSql.queryResult[2][2]=='leader':
|
||||
print("three mnodes is ready in 10s")
|
||||
tdLog.debug("three mnodes is ready in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("three mnodes is not ready in 10s ")
|
||||
tdLog.debug("three mnodes is not ready in 10s ")
|
||||
return -1
|
||||
|
||||
tdSql.query("show mnodes;")
|
||||
|
@ -152,19 +152,19 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='offline' :
|
||||
if tdSql.queryResult[1][2]=='leader':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("stop mnodes on dnode 2 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 2 successfully in 10s")
|
||||
break
|
||||
elif tdSql.queryResult[1][2]=='follower':
|
||||
if tdSql.queryResult[2][2]=='leader':
|
||||
print("stop mnodes on dnode 2 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 2 successfully in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("stop mnodes on dnode 2 failed in 10s ")
|
||||
tdLog.debug("stop mnodes on dnode 2 failed in 10s ")
|
||||
return -1
|
||||
tdSql.error("drop mnode on dnode 1;")
|
||||
|
||||
|
@ -184,15 +184,15 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='leader' :
|
||||
if tdSql.queryResult[1][2]=='offline':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("stop mnodes on dnode 2 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 2 successfully in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("stop mnodes on dnode 2 failed in 10s ")
|
||||
tdLog.debug("stop mnodes on dnode 2 failed in 10s ")
|
||||
return -1
|
||||
tdSql.error("drop mnode on dnode 2;")
|
||||
|
||||
|
@ -214,15 +214,15 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='leader' :
|
||||
if tdSql.queryResult[2][2]=='offline':
|
||||
if tdSql.queryResult[1][2]=='follower':
|
||||
print("stop mnodes on dnode 3 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 3 successfully in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("stop mnodes on dnode 3 failed in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 3 failed in 10s")
|
||||
return -1
|
||||
tdSql.error("drop mnode on dnode 3;")
|
||||
tdSql.query("show mnodes;")
|
||||
|
@ -262,7 +262,7 @@ class TDTestCase:
|
|||
tdSql.error("create mnode on dnode 2")
|
||||
|
||||
tdSql.query("show dnodes;")
|
||||
print(tdSql.queryResult)
|
||||
tdLog.debug(tdSql.queryResult)
|
||||
|
||||
tdLog.debug("stop and follower of mnode")
|
||||
self.TDDnodes.stoptaosd(2)
|
||||
|
@ -303,7 +303,7 @@ class TDTestCase:
|
|||
|
||||
|
||||
def run(self):
|
||||
# print(self.master_dnode.cfgDict)
|
||||
# tdLog.debug(self.master_dnode.cfgDict)
|
||||
self.buildcluster(5)
|
||||
self.five_dnode_three_mnode(5)
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ class TDTestCase:
|
|||
for couti in range(countstart,countstop):
|
||||
tdLog.debug("drop database if exists db%d" %couti)
|
||||
tdSql.execute("drop database if exists db%d" %couti)
|
||||
print("create database if not exists db%d replica 1 duration 300" %couti)
|
||||
tdLog.debug("create database if not exists db%d replica 1 duration 300" %couti)
|
||||
tdSql.execute("create database if not exists db%d replica 1 duration 300" %couti)
|
||||
tdSql.execute("use db%d" %couti)
|
||||
tdSql.execute(
|
||||
|
@ -126,12 +126,12 @@ class TDTestCase:
|
|||
|
||||
# create cluster
|
||||
for dnode in self.TDDnodes.dnodes[1:]:
|
||||
# print(dnode.cfgDict)
|
||||
# tdLog.debug(dnode.cfgDict)
|
||||
dnode_id = dnode.cfgDict["fqdn"] + ":" +dnode.cfgDict["serverPort"]
|
||||
dnode_first_host = dnode.cfgDict["firstEp"].split(":")[0]
|
||||
dnode_first_port = dnode.cfgDict["firstEp"].split(":")[-1]
|
||||
cmd = f" taos -h {dnode_first_host} -P {dnode_first_port} -s ' create dnode \"{dnode_id} \" ' ;"
|
||||
print(cmd)
|
||||
tdLog.debug(cmd)
|
||||
os.system(cmd)
|
||||
|
||||
time.sleep(2)
|
||||
|
@ -144,22 +144,22 @@ class TDTestCase:
|
|||
statusReadyBumber=0
|
||||
tdSql.query("show dnodes;")
|
||||
if tdSql.checkRows(dnodenumber) :
|
||||
print("dnode is %d nodes"%dnodenumber)
|
||||
tdLog.debug("dnode is %d nodes"%dnodenumber)
|
||||
for i in range(dnodenumber):
|
||||
if tdSql.queryResult[i][4] !='ready' :
|
||||
status=tdSql.queryResult[i][4]
|
||||
print("dnode:%d status is %s "%(i,status))
|
||||
tdLog.debug("dnode:%d status is %s "%(i,status))
|
||||
break
|
||||
else:
|
||||
statusReadyBumber+=1
|
||||
print(statusReadyBumber)
|
||||
tdLog.debug(statusReadyBumber)
|
||||
if statusReadyBumber == dnodenumber :
|
||||
print("all of %d mnodes is ready in 10s "%dnodenumber)
|
||||
tdLog.debug("all of %d mnodes is ready in 10s "%dnodenumber)
|
||||
return True
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("%d mnodes is not ready in 10s "%dnodenumber)
|
||||
tdLog.debug("%d mnodes is not ready in 10s "%dnodenumber)
|
||||
return False
|
||||
|
||||
|
||||
|
@ -169,25 +169,25 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='leader' :
|
||||
if tdSql.queryResult[1][2]=='follower':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("three mnodes is ready in 10s")
|
||||
tdLog.debug("three mnodes is ready in 10s")
|
||||
break
|
||||
elif tdSql.queryResult[0][2]=='follower' :
|
||||
if tdSql.queryResult[1][2]=='leader':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("three mnodes is ready in 10s")
|
||||
tdLog.debug("three mnodes is ready in 10s")
|
||||
break
|
||||
elif tdSql.queryResult[0][2]=='follower' :
|
||||
if tdSql.queryResult[1][2]=='follower':
|
||||
if tdSql.queryResult[2][2]=='leader':
|
||||
print("three mnodes is ready in 10s")
|
||||
tdLog.debug("three mnodes is ready in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("three mnodes is not ready in 10s ")
|
||||
tdLog.debug("three mnodes is not ready in 10s ")
|
||||
return -1
|
||||
|
||||
tdSql.query("show mnodes;")
|
||||
|
@ -205,19 +205,19 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='offline' :
|
||||
if tdSql.queryResult[1][2]=='leader':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("stop mnodes on dnode 2 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 2 successfully in 10s")
|
||||
break
|
||||
elif tdSql.queryResult[1][2]=='follower':
|
||||
if tdSql.queryResult[2][2]=='leader':
|
||||
print("stop mnodes on dnode 2 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 2 successfully in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("stop mnodes on dnode 2 failed in 10s ")
|
||||
tdLog.debug("stop mnodes on dnode 2 failed in 10s ")
|
||||
return -1
|
||||
tdSql.error("drop mnode on dnode 1;")
|
||||
|
||||
|
@ -237,15 +237,15 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='leader' :
|
||||
if tdSql.queryResult[1][2]=='offline':
|
||||
if tdSql.queryResult[2][2]=='follower':
|
||||
print("stop mnodes on dnode 2 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 2 successfully in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("stop mnodes on dnode 2 failed in 10s ")
|
||||
tdLog.debug("stop mnodes on dnode 2 failed in 10s ")
|
||||
return -1
|
||||
tdSql.error("drop mnode on dnode 2;")
|
||||
|
||||
|
@ -267,15 +267,15 @@ class TDTestCase:
|
|||
time.sleep(1)
|
||||
tdSql.query("show mnodes;")
|
||||
if tdSql.checkRows(3) :
|
||||
print("mnode is three nodes")
|
||||
tdLog.debug("mnode is three nodes")
|
||||
if tdSql.queryResult[0][2]=='leader' :
|
||||
if tdSql.queryResult[2][2]=='offline':
|
||||
if tdSql.queryResult[1][2]=='follower':
|
||||
print("stop mnodes on dnode 3 successfully in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 3 successfully in 10s")
|
||||
break
|
||||
count+=1
|
||||
else:
|
||||
print("stop mnodes on dnode 3 failed in 10s")
|
||||
tdLog.debug("stop mnodes on dnode 3 failed in 10s")
|
||||
return -1
|
||||
tdSql.error("drop mnode on dnode 3;")
|
||||
tdSql.query("show mnodes;")
|
||||
|
@ -311,7 +311,7 @@ class TDTestCase:
|
|||
|
||||
tdSql.error("create mnode on dnode 2")
|
||||
tdSql.query("show dnodes;")
|
||||
print(tdSql.queryResult)
|
||||
tdLog.debug(tdSql.queryResult)
|
||||
tdLog.debug("stop all of mnode ")
|
||||
|
||||
stopcount =0
|
||||
|
@ -325,10 +325,10 @@ class TDTestCase:
|
|||
self.TDDnodes.starttaosd(i+1)
|
||||
|
||||
if self.checkdnodes(5):
|
||||
print("123")
|
||||
tdLog.debug("123")
|
||||
threads.join()
|
||||
else:
|
||||
print("456")
|
||||
tdLog.debug("456")
|
||||
self.stop_thread(threads)
|
||||
assert 1 == 2 ,"some dnode started failed"
|
||||
return False
|
||||
|
@ -345,7 +345,7 @@ class TDTestCase:
|
|||
|
||||
|
||||
def run(self):
|
||||
# print(self.master_dnode.cfgDict)
|
||||
# tdLog.debug(self.master_dnode.cfgDict)
|
||||
self.buildcluster(5)
|
||||
self.five_dnode_three_mnode(5)
|
||||
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
import sys
|
||||
import time
|
||||
import socket
|
||||
import os
|
||||
import threading
|
||||
|
||||
import taos
|
||||
from util.log import *
|
||||
from util.sql import *
|
||||
from util.cases import *
|
||||
from util.dnodes import *
|
||||
from util.common import *
|
||||
sys.path.append("./7-tmq")
|
||||
from tmqCommon import *
|
||||
|
||||
class TDTestCase:
|
||||
paraDict = {'dbName': 'db12',
|
||||
'dropFlag':1,
|
||||
'vgroups': 4,
|
||||
'precision': 'ms',
|
||||
'stbName': 'stb0',
|
||||
'ctbNum': 10,
|
||||
'rowsPerTbl': 10000,
|
||||
'batchNum': 10,
|
||||
'startTs': 0, # 1640966400000 ----> 2022-01-01 00:00:00.000
|
||||
'event':'',
|
||||
'columnDict': {'int':2},
|
||||
'tagDict': {'int':1}
|
||||
}
|
||||
|
||||
cdbName = 'cdb'
|
||||
# some parameter to consumer processor
|
||||
consumerId = 0
|
||||
expectrowcnt = 0
|
||||
topicList = ''
|
||||
ifcheckdata = 0
|
||||
ifManualCommit = 1
|
||||
groupId = 'group.id:cgrp1'
|
||||
autoCommit = 'enable.auto.commit:false'
|
||||
autoCommitInterval = 'auto.commit.interval.ms:1000'
|
||||
autoOffset = 'auto.offset.reset:earliest'
|
||||
|
||||
pollDelay = 20
|
||||
showMsg = 1
|
||||
showRow = 1
|
||||
|
||||
hostname = socket.gethostname()
|
||||
|
||||
def init(self, conn, logSql):
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
logSql = False
|
||||
tdSql.init(conn.cursor(), logSql)
|
||||
|
||||
def tmqCase12(self):
|
||||
tdLog.printNoPrefix("======== test case 12: ")
|
||||
tdLog.info("step 1: create database, stb, ctb and insert data")
|
||||
|
||||
tmqCom.initConsumerTable(self.cdbName)
|
||||
|
||||
tdCom.create_database(tdSql,self.paraDict["dbName"],self.paraDict["dropFlag"], self.paraDict['precision'])
|
||||
|
||||
self.paraDict["stbName"] = 'stb1'
|
||||
tdCom.create_stable(tdSql,self.paraDict["dbName"],self.paraDict["stbName"],self.paraDict["columnDict"],self.paraDict["tagDict"])
|
||||
tdCom.create_ctables(tdSql,self.paraDict["dbName"],self.paraDict["stbName"],self.paraDict["ctbNum"],self.paraDict["tagDict"])
|
||||
tdCom.insert_data(tdSql,self.paraDict["dbName"],self.paraDict["stbName"],self.paraDict["ctbNum"],self.paraDict["rowsPerTbl"],self.paraDict["batchNum"])
|
||||
|
||||
self.paraDict["stbName"] = 'stb2'
|
||||
tdCom.create_stable(tdSql,self.paraDict["dbName"],self.paraDict["stbName"],self.paraDict["columnDict"],self.paraDict["tagDict"])
|
||||
tdCom.create_ctables(tdSql,self.paraDict["dbName"],self.paraDict["stbName"],self.paraDict["ctbNum"],self.paraDict["tagDict"])
|
||||
tdCom.insert_data(tdSql,self.paraDict["dbName"],self.paraDict["stbName"],self.paraDict["ctbNum"],self.paraDict["rowsPerTbl"],self.paraDict["batchNum"])
|
||||
|
||||
tdLog.info("create topics from db")
|
||||
topicName1 = 'topic_%s'%(self.paraDict['dbName'])
|
||||
tdSql.execute("create topic %s as database %s" %(topicName1, self.paraDict['dbName']))
|
||||
|
||||
topicList = topicName1
|
||||
keyList = '%s,%s,%s,%s'%(self.groupId,self.autoCommit,self.autoCommitInterval,self.autoOffset)
|
||||
self.expectrowcnt = self.paraDict["rowsPerTbl"] * self.paraDict["ctbNum"] * 2
|
||||
tmqCom.insertConsumerInfo(self.consumerId, self.expectrowcnt,topicList,keyList,self.ifcheckdata,self.ifManualCommit)
|
||||
|
||||
tdLog.info("start consume processor")
|
||||
tmqCom.startTmqSimProcess(self.pollDelay,self.paraDict["dbName"],self.showMsg, self.showRow,self.cdbName)
|
||||
|
||||
tdLog.info("After waiting for a period of time, drop one stable")
|
||||
time.sleep(10)
|
||||
tdSql.execute("drop table %s.%s" %(self.paraDict['dbName'], self.paraDict['stbName']))
|
||||
|
||||
tdLog.info("wait result from consumer, then check it")
|
||||
expectRows = 1
|
||||
resultList = tmqCom.selectConsumeResult(expectRows)
|
||||
|
||||
totalConsumeRows = 0
|
||||
for i in range(expectRows):
|
||||
totalConsumeRows += resultList[i]
|
||||
|
||||
if not (totalConsumeRows >= self.expectrowcnt/2 and totalConsumeRows <= self.expectrowcnt):
|
||||
tdLog.info("act consume rows: %d, expect consume rows: between %d and %d"%(totalConsumeRows, self.expectrowcnt/2, self.expectrowcnt))
|
||||
tdLog.exit("tmq consume rows error!")
|
||||
|
||||
time.sleep(15)
|
||||
tdSql.query("drop topic %s"%topicName1)
|
||||
|
||||
tdLog.printNoPrefix("======== test case 12 end ...... ")
|
||||
|
||||
def run(self):
|
||||
tdSql.prepare()
|
||||
self.tmqCase12()
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
event = threading.Event()
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -196,16 +196,16 @@ class TDTestCase:
|
|||
auotCtbPrefix = 'autoCtb'
|
||||
|
||||
# create and start thread
|
||||
parameterDict = {'cfg': '', \
|
||||
'actionType': 0, \
|
||||
'dbName': 'db1', \
|
||||
'dropFlag': 1, \
|
||||
'vgroups': 4, \
|
||||
'replica': 1, \
|
||||
'stbName': 'stb1', \
|
||||
'ctbNum': 10, \
|
||||
'rowsPerTbl': 10000, \
|
||||
'batchNum': 100, \
|
||||
parameterDict = {'cfg': '',
|
||||
'actionType': 0,
|
||||
'dbName': 'db1',
|
||||
'dropFlag': 1,
|
||||
'vgroups': 4,
|
||||
'replica': 1,
|
||||
'stbName': 'stb1',
|
||||
'ctbNum': 10,
|
||||
'rowsPerTbl': 10000,
|
||||
'batchNum': 100,
|
||||
'startTs': 1640966400000} # 2022-01-01 00:00:00.000
|
||||
parameterDict['cfg'] = cfgPath
|
||||
|
||||
|
@ -349,7 +349,5 @@ class TDTestCase:
|
|||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
event = threading.Event()
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
###################################################################
|
||||
# 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 -*-
|
||||
|
||||
from collections import defaultdict
|
||||
import random
|
||||
import string
|
||||
import threading
|
||||
import requests
|
||||
import time
|
||||
# import socketfrom
|
||||
|
||||
import taos
|
||||
from util.log import *
|
||||
from util.sql import *
|
||||
from util.cases import *
|
||||
from util.dnodes import *
|
||||
from util.common import *
|
||||
|
||||
# class actionType(Enum):
|
||||
# CREATE_DATABASE = 0
|
||||
# CREATE_STABLE = 1
|
||||
# CREATE_CTABLE = 2
|
||||
# INSERT_DATA = 3
|
||||
|
||||
class TMQCom:
|
||||
def init(self, conn, logSql):
|
||||
tdSql.init(conn.cursor())
|
||||
# tdSql.init(conn.cursor(), logSql) # output sql.txt file
|
||||
|
||||
def initConsumerTable(self,cdbName='cdb'):
|
||||
tdLog.info("create consume database, and consume info table, and consume result table")
|
||||
tdSql.query("create database if not exists %s vgroups 1"%(cdbName))
|
||||
tdSql.query("drop table if exists %s.consumeinfo "%(cdbName))
|
||||
tdSql.query("drop table if exists %s.consumeresult "%(cdbName))
|
||||
|
||||
tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int, ifmanualcommit int)"%cdbName)
|
||||
tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName)
|
||||
|
||||
def initConsumerInfoTable(self,cdbName='cdb'):
|
||||
tdLog.info("drop consumeinfo table")
|
||||
tdSql.query("drop table if exists %s.consumeinfo "%(cdbName))
|
||||
tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int, ifmanualcommit int)"%cdbName)
|
||||
|
||||
def insertConsumerInfo(self,consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifmanualcommit,cdbName='cdb'):
|
||||
sql = "insert into %s.consumeinfo values "%cdbName
|
||||
sql += "(now, %d, '%s', '%s', %d, %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata, ifmanualcommit)
|
||||
tdLog.info("consume info sql: %s"%sql)
|
||||
tdSql.query(sql)
|
||||
|
||||
def selectConsumeResult(self,expectRows,cdbName='cdb'):
|
||||
resultList=[]
|
||||
while 1:
|
||||
tdSql.query("select * from %s.consumeresult"%cdbName)
|
||||
#tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3))
|
||||
if tdSql.getRows() == expectRows:
|
||||
break
|
||||
else:
|
||||
time.sleep(5)
|
||||
|
||||
for i in range(expectRows):
|
||||
tdLog.info ("consume id: %d, consume msgs: %d, consume rows: %d"%(tdSql.getData(i , 1), tdSql.getData(i , 2), tdSql.getData(i , 3)))
|
||||
resultList.append(tdSql.getData(i , 3))
|
||||
|
||||
return resultList
|
||||
|
||||
def startTmqSimProcess(self,pollDelay,dbName,showMsg=1,showRow=1,cdbName='cdb',valgrind=0):
|
||||
buildPath = tdCom.getBuildPath()
|
||||
cfgPath = tdCom.getClientCfgPath()
|
||||
if valgrind == 1:
|
||||
logFile = cfgPath + '/../log/valgrind-tmq.log'
|
||||
shellCmd = 'nohup valgrind --log-file=' + logFile
|
||||
shellCmd += '--tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v --workaround-gcc296-bugs=yes '
|
||||
|
||||
if (platform.system().lower() == 'windows'):
|
||||
shellCmd = 'mintty -h never -w hide ' + buildPath + '\\build\\bin\\tmq_sim.exe -c ' + cfgPath
|
||||
shellCmd += " -y %d -d %s -g %d -r %d -w %s "%(pollDelay, dbName, showMsg, showRow, cdbName)
|
||||
shellCmd += "> nul 2>&1 &"
|
||||
else:
|
||||
shellCmd = 'nohup ' + buildPath + '/build/bin/tmq_sim -c ' + cfgPath
|
||||
shellCmd += " -y %d -d %s -g %d -r %d -w %s "%(pollDelay, dbName, showMsg, showRow, cdbName)
|
||||
shellCmd += "> /dev/null 2>&1 &"
|
||||
tdLog.info(shellCmd)
|
||||
os.system(shellCmd)
|
||||
|
||||
def syncCreateDbStbCtbInsertData(self, tsql, paraDict):
|
||||
tdCom.create_database(tsql, paraDict["dbName"],paraDict["dropFlag"], paraDict['precision'])
|
||||
tdCom.create_stable(tsql, paraDict["dbName"],paraDict["stbName"], paraDict["columnDict"], paraDict["tagDict"])
|
||||
tdCom.create_ctables(tsql, paraDict["dbName"],paraDict["stbName"],paraDict["ctbNum"],paraDict["tagDict"])
|
||||
if "event" in paraDict and type(paraDict['event']) == type(threading.Event()):
|
||||
paraDict["event"].set()
|
||||
tdCom.insert_data(tsql,paraDict["dbName"],paraDict["stbName"],paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"])
|
||||
return
|
||||
|
||||
def threadFunction(self, **paraDict):
|
||||
# create new connector for new tdSql instance in my thread
|
||||
newTdSql = tdCom.newTdSql()
|
||||
self.syncCreateDbStbCtbInsertData(self, newTdSql, paraDict)
|
||||
return
|
||||
|
||||
def asyncCreateDbStbCtbInsertData(self, paraDict):
|
||||
pThread = threading.Thread(target=self.threadFunction, kwargs=paraDict)
|
||||
pThread.start()
|
||||
return pThread
|
||||
|
||||
def close(self):
|
||||
self.cursor.close()
|
||||
|
||||
tmqCom = TMQCom()
|
|
@ -22,7 +22,7 @@ python3 ./test.py -f 1-insert/opentsdb_json_taosc_insert.py
|
|||
python3 ./test.py -f 1-insert/alter_stable.py
|
||||
python3 ./test.py -f 1-insert/alter_table.py
|
||||
python3 ./test.py -f 1-insert/insertWithMoreVgroup.py
|
||||
# python3 ./test.py -f 1-inerst/create_table_comment.py
|
||||
python3 ./test.py -f 1-insert/table_comment.py
|
||||
python3 ./test.py -f 2-query/between.py
|
||||
python3 ./test.py -f 2-query/distinct.py
|
||||
python3 ./test.py -f 2-query/varchar.py
|
||||
|
|
|
@ -114,8 +114,10 @@ void dumpStb(SSdb *pSdb, SJson *json) {
|
|||
tjsonAddIntegerToObject(item, "tagVer", pObj->tagVer);
|
||||
tjsonAddIntegerToObject(item, "colVer", pObj->colVer);
|
||||
tjsonAddIntegerToObject(item, "nextColId", pObj->nextColId);
|
||||
tjsonAddIntegerToObject(item, "xFilesFactor", pObj->xFilesFactor * 10000);
|
||||
tjsonAddIntegerToObject(item, "delay", pObj->delay);
|
||||
tjsonAddIntegerToObject(item, "watermark1", pObj->watermark[0]);
|
||||
tjsonAddIntegerToObject(item, "watermark2", pObj->watermark[1]);
|
||||
tjsonAddIntegerToObject(item, "maxdelay1", pObj->maxdelay[0]);
|
||||
tjsonAddIntegerToObject(item, "maxdelay2", pObj->maxdelay[1]);
|
||||
tjsonAddIntegerToObject(item, "ttl", pObj->ttl);
|
||||
tjsonAddIntegerToObject(item, "numOfColumns", pObj->numOfColumns);
|
||||
tjsonAddIntegerToObject(item, "numOfTags", pObj->numOfTags);
|
||||
|
|
Loading…
Reference in New Issue