提交 9fc1e86f 编写于 作者: S Shengliang Guan

Merge remote-tracking branch 'origin/3.0' into fix/TD-19245

...@@ -375,7 +375,7 @@ public class ParameterBindingDemo { ...@@ -375,7 +375,7 @@ public class ParameterBindingDemo {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static final Random random = new Random(System.currentTimeMillis()); private static final Random random = new Random(System.currentTimeMillis());
private static final int BINARY_COLUMN_SIZE = 20; private static final int BINARY_COLUMN_SIZE = 30;
private static final String[] schemaList = { private static final String[] schemaList = {
"create table stable1(ts timestamp, f1 tinyint, f2 smallint, f3 int, f4 bigint) tags(t1 tinyint, t2 smallint, t3 int, t4 bigint)", "create table stable1(ts timestamp, f1 tinyint, f2 smallint, f3 int, f4 bigint) tags(t1 tinyint, t2 smallint, t3 int, t4 bigint)",
"create table stable2(ts timestamp, f1 float, f2 double) tags(t1 float, t2 double)", "create table stable2(ts timestamp, f1 float, f2 double) tags(t1 float, t2 double)",
......
...@@ -49,7 +49,7 @@ typedef struct { ...@@ -49,7 +49,7 @@ typedef struct {
TSKEY ts; TSKEY ts;
} SWinKey; } SWinKey;
static inline int SWinKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, int kLen2) { static inline int sWinKeyCmprImpl(const void* pKey1, const void* pKey2) {
SWinKey* pWin1 = (SWinKey*)pKey1; SWinKey* pWin1 = (SWinKey*)pKey1;
SWinKey* pWin2 = (SWinKey*)pKey2; SWinKey* pWin2 = (SWinKey*)pKey2;
...@@ -68,6 +68,10 @@ static inline int SWinKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, i ...@@ -68,6 +68,10 @@ static inline int SWinKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, i
return 0; return 0;
} }
static inline int winKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, int kLen2) {
return sWinKeyCmprImpl(pKey1, pKey2);
}
typedef struct { typedef struct {
uint64_t groupId; uint64_t groupId;
TSKEY ts; TSKEY ts;
......
...@@ -297,7 +297,7 @@ typedef enum ELogicConditionType { ...@@ -297,7 +297,7 @@ typedef enum ELogicConditionType {
#define TSDB_MAX_BUFFER_PER_VNODE 16384 // unit MB #define TSDB_MAX_BUFFER_PER_VNODE 16384 // unit MB
#define TSDB_DEFAULT_BUFFER_PER_VNODE 96 #define TSDB_DEFAULT_BUFFER_PER_VNODE 96
#define TSDB_MIN_PAGES_PER_VNODE 64 #define TSDB_MIN_PAGES_PER_VNODE 64
#define TSDB_MAX_PAGES_PER_VNODE 16384 #define TSDB_MAX_PAGES_PER_VNODE INT32_MAX
#define TSDB_DEFAULT_PAGES_PER_VNODE 256 #define TSDB_DEFAULT_PAGES_PER_VNODE 256
#define TSDB_MIN_PAGESIZE_PER_VNODE 1 // unit KB #define TSDB_MIN_PAGESIZE_PER_VNODE 1 // unit KB
#define TSDB_MAX_PAGESIZE_PER_VNODE 16384 #define TSDB_MAX_PAGESIZE_PER_VNODE 16384
...@@ -483,7 +483,7 @@ enum { ...@@ -483,7 +483,7 @@ enum {
#define SNODE_HANDLE -2 #define SNODE_HANDLE -2
#define VNODE_HANDLE -3 #define VNODE_HANDLE -3
#define BNODE_HANDLE -4 #define BNODE_HANDLE -4
#define CLIENT_HANDLE -5 #define CLIENT_HANDLE -5
#define TSDB_CONFIG_OPTION_LEN 32 #define TSDB_CONFIG_OPTION_LEN 32
#define TSDB_CONFIG_VALUE_LEN 64 #define TSDB_CONFIG_VALUE_LEN 64
......
...@@ -631,7 +631,7 @@ static int32_t mndSetDbCfgFromAlterDbReq(SDbObj *pDb, SAlterDbReq *pAlter) { ...@@ -631,7 +631,7 @@ static int32_t mndSetDbCfgFromAlterDbReq(SDbObj *pDb, SAlterDbReq *pAlter) {
terrno = TSDB_CODE_MND_DB_OPTION_UNCHANGED; terrno = TSDB_CODE_MND_DB_OPTION_UNCHANGED;
if (pAlter->buffer > 0 && pAlter->buffer != pDb->cfg.buffer) { if (pAlter->buffer > 0 && pAlter->buffer != pDb->cfg.buffer) {
#if 1 #if 0
terrno = TSDB_CODE_OPS_NOT_SUPPORT; terrno = TSDB_CODE_OPS_NOT_SUPPORT;
return terrno; return terrno;
#else #else
...@@ -641,7 +641,7 @@ static int32_t mndSetDbCfgFromAlterDbReq(SDbObj *pDb, SAlterDbReq *pAlter) { ...@@ -641,7 +641,7 @@ static int32_t mndSetDbCfgFromAlterDbReq(SDbObj *pDb, SAlterDbReq *pAlter) {
} }
if (pAlter->pages > 0 && pAlter->pages != pDb->cfg.pages) { if (pAlter->pages > 0 && pAlter->pages != pDb->cfg.pages) {
#if 1 #if 0
terrno = TSDB_CODE_OPS_NOT_SUPPORT; terrno = TSDB_CODE_OPS_NOT_SUPPORT;
return terrno; return terrno;
#else #else
...@@ -1311,7 +1311,7 @@ int32_t mndValidateDbInfo(SMnode *pMnode, SDbVgVersion *pDbs, int32_t numOfDbs, ...@@ -1311,7 +1311,7 @@ int32_t mndValidateDbInfo(SMnode *pMnode, SDbVgVersion *pDbs, int32_t numOfDbs,
continue; continue;
} else { } else {
mInfo("db:%s, vgroup version changed from %d to %d", pDbVgVersion->dbFName, pDbVgVersion->vgVersion, mInfo("db:%s, vgroup version changed from %d to %d", pDbVgVersion->dbFName, pDbVgVersion->vgVersion,
pDb->vgVersion); pDb->vgVersion);
} }
usedbRsp.pVgroupInfos = taosArrayInit(pDb->cfg.numOfVgroups, sizeof(SVgroupInfo)); usedbRsp.pVgroupInfos = taosArrayInit(pDb->cfg.numOfVgroups, sizeof(SVgroupInfo));
......
...@@ -30,6 +30,7 @@ TEST_F(MndTestDb, 01_ShowDb) { ...@@ -30,6 +30,7 @@ TEST_F(MndTestDb, 01_ShowDb) {
EXPECT_EQ(test.GetShowRows(), 2); EXPECT_EQ(test.GetShowRows(), 2);
} }
#if 0
TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) { TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) {
{ {
SCreateDbReq createReq = {0}; SCreateDbReq createReq = {0};
...@@ -125,6 +126,7 @@ TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) { ...@@ -125,6 +126,7 @@ TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) {
test.SendShowReq(TSDB_MGMT_TABLE_DB, "ins_databases", ""); test.SendShowReq(TSDB_MGMT_TABLE_DB, "ins_databases", "");
EXPECT_EQ(test.GetShowRows(), 2); EXPECT_EQ(test.GetShowRows(), 2);
} }
#endif
TEST_F(MndTestDb, 03_Create_Use_Restart_Use_Db) { TEST_F(MndTestDb, 03_Create_Use_Restart_Use_Db) {
{ {
......
...@@ -72,7 +72,7 @@ struct SVBufPool { ...@@ -72,7 +72,7 @@ struct SVBufPool {
SVBufPoolNode node; SVBufPoolNode node;
}; };
int32_t vnodeOpenBufPool(SVnode* pVnode, int64_t size); int32_t vnodeOpenBufPool(SVnode* pVnode);
int32_t vnodeCloseBufPool(SVnode* pVnode); int32_t vnodeCloseBufPool(SVnode* pVnode);
void vnodeBufPoolReset(SVBufPool* pPool); void vnodeBufPoolReset(SVBufPool* pPool);
......
...@@ -111,6 +111,7 @@ SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, boo ...@@ -111,6 +111,7 @@ SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, boo
STSchema* metaGetTbTSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver); STSchema* metaGetTbTSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver);
int32_t metaGetTbTSchemaEx(SMeta* pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sver, STSchema** ppTSchema); int32_t metaGetTbTSchemaEx(SMeta* pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sver, STSchema** ppTSchema);
int metaGetTableEntryByName(SMetaReader* pReader, const char* name); int metaGetTableEntryByName(SMetaReader* pReader, const char* name);
int metaAlterCache(SMeta* pMeta, int32_t nPage);
tb_uid_t metaGetTableEntryUidByName(SMeta* pMeta, const char* name); tb_uid_t metaGetTableEntryUidByName(SMeta* pMeta, const char* name);
int64_t metaGetTbNum(SMeta* pMeta); int64_t metaGetTbNum(SMeta* pMeta);
......
...@@ -197,6 +197,18 @@ int metaClose(SMeta *pMeta) { ...@@ -197,6 +197,18 @@ int metaClose(SMeta *pMeta) {
return 0; return 0;
} }
int metaAlterCache(SMeta *pMeta, int32_t nPage) {
metaWLock(pMeta);
if (tdbAlter(pMeta->pEnv, nPage) < 0) {
metaULock(pMeta);
return -1;
}
metaULock(pMeta);
return 0;
}
int32_t metaRLock(SMeta *pMeta) { int32_t metaRLock(SMeta *pMeta) {
int32_t ret = 0; int32_t ret = 0;
......
...@@ -235,8 +235,13 @@ static int32_t binarySearchForStartRowIndex(uint64_t* uidList, int32_t num, uint ...@@ -235,8 +235,13 @@ static int32_t binarySearchForStartRowIndex(uint64_t* uidList, int32_t num, uint
} }
} }
static bool queryChildTable(uint64_t suid) {
return suid != 0;
}
int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t iStt, int8_t backward, uint64_t suid, int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t iStt, int8_t backward, uint64_t suid,
uint64_t uid, STimeWindow *pTimeWindow, SVersionRange *pRange, SSttBlockLoadInfo* pBlockLoadInfo) { uint64_t uid, STimeWindow *pTimeWindow, SVersionRange *pRange, SSttBlockLoadInfo* pBlockLoadInfo,
const char* idStr) {
int32_t code = 0; int32_t code = 0;
*pIter = taosMemoryCalloc(1, sizeof(SLDataIter)); *pIter = taosMemoryCalloc(1, sizeof(SLDataIter));
if (*pIter == NULL) { if (*pIter == NULL) {
...@@ -252,15 +257,22 @@ int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t ...@@ -252,15 +257,22 @@ int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t
(*pIter)->timeWindow = *pTimeWindow; (*pIter)->timeWindow = *pTimeWindow;
(*pIter)->pBlockLoadInfo = pBlockLoadInfo; (*pIter)->pBlockLoadInfo = pBlockLoadInfo;
if (taosArrayGetSize(pBlockLoadInfo->aSttBlk) == 0) {
size_t size = taosArrayGetSize(pBlockLoadInfo->aSttBlk);
if (size == 0) {
int64_t st = taosGetTimestampUs();
code = tsdbReadSttBlk(pReader, iStt, pBlockLoadInfo->aSttBlk); code = tsdbReadSttBlk(pReader, iStt, pBlockLoadInfo->aSttBlk);
if (code) { if (code) {
goto _exit; goto _exit;
} else { }
size_t size = taosArrayGetSize(pBlockLoadInfo->aSttBlk);
SArray* pTmp = taosArrayInit(size, sizeof(SSttBlk)); // only apply to the child tables, ordinary tables will not incur this filter procedure.
for(int32_t i = 0; i < size; ++i) { if (queryChildTable(suid)) {
SSttBlk* p = taosArrayGet(pBlockLoadInfo->aSttBlk, i); size = taosArrayGetSize(pBlockLoadInfo->aSttBlk);
SArray *pTmp = taosArrayInit(size, sizeof(SSttBlk));
for (int32_t i = 0; i < size; ++i) {
SSttBlk *p = taosArrayGet(pBlockLoadInfo->aSttBlk, i);
if (p->suid == suid) { if (p->suid == suid) {
taosArrayPush(pTmp, p); taosArrayPush(pTmp, p);
} }
...@@ -269,9 +281,12 @@ int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t ...@@ -269,9 +281,12 @@ int32_t tLDataIterOpen(struct SLDataIter **pIter, SDataFReader *pReader, int32_t
taosArrayDestroy(pBlockLoadInfo->aSttBlk); taosArrayDestroy(pBlockLoadInfo->aSttBlk);
pBlockLoadInfo->aSttBlk = pTmp; pBlockLoadInfo->aSttBlk = pTmp;
} }
double el = (taosGetTimestampUs() - st)/1000.0;
tsdbDebug("load the last file info completed, elapsed time:%.2fms, %s", el, idStr);
} }
size_t size = taosArrayGetSize(pBlockLoadInfo->aSttBlk); size = taosArrayGetSize(pBlockLoadInfo->aSttBlk);
// find the start block // find the start block
(*pIter)->iSttBlk = binarySearchForStartBlock(pBlockLoadInfo->aSttBlk->pData, size, uid, backward); (*pIter)->iSttBlk = binarySearchForStartBlock(pBlockLoadInfo->aSttBlk->pData, size, uid, backward);
...@@ -493,7 +508,7 @@ int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFRead ...@@ -493,7 +508,7 @@ int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFRead
for (int32_t i = 0; i < pFReader->pSet->nSttF; ++i) { // open all last file for (int32_t i = 0; i < pFReader->pSet->nSttF; ++i) { // open all last file
struct SLDataIter* pIter = NULL; struct SLDataIter* pIter = NULL;
code = tLDataIterOpen(&pIter, pFReader, i, pMTree->backward, suid, uid, pTimeWindow, pVerRange, &pMTree->pLoadInfo[i]); code = tLDataIterOpen(&pIter, pFReader, i, pMTree->backward, suid, uid, pTimeWindow, pVerRange, &pMTree->pLoadInfo[i], pMTree->idStr);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
goto _end; goto _end;
} }
......
...@@ -16,20 +16,53 @@ ...@@ -16,20 +16,53 @@
#include "vnd.h" #include "vnd.h"
/* ------------------------ STRUCTURES ------------------------ */ /* ------------------------ STRUCTURES ------------------------ */
#define VNODE_BUFPOOL_SEGMENTS 3
static int vnodeBufPoolCreate(SVnode *pVnode, int64_t size, SVBufPool **ppPool); static int vnodeBufPoolCreate(SVnode *pVnode, int64_t size, SVBufPool **ppPool) {
static int vnodeBufPoolDestroy(SVBufPool *pPool); SVBufPool *pPool;
pPool = taosMemoryMalloc(sizeof(SVBufPool) + size);
if (pPool == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return -1;
}
if (taosThreadSpinInit(&pPool->lock, 0) != 0) {
taosMemoryFree(pPool);
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
pPool->next = NULL;
pPool->pVnode = pVnode;
pPool->nRef = 0;
pPool->size = 0;
pPool->ptr = pPool->node.data;
pPool->pTail = &pPool->node;
pPool->node.prev = NULL;
pPool->node.pnext = &pPool->pTail;
pPool->node.size = size;
int vnodeOpenBufPool(SVnode *pVnode, int64_t size) { *ppPool = pPool;
return 0;
}
static int vnodeBufPoolDestroy(SVBufPool *pPool) {
vnodeBufPoolReset(pPool);
taosThreadSpinDestroy(&pPool->lock);
taosMemoryFree(pPool);
return 0;
}
int vnodeOpenBufPool(SVnode *pVnode) {
SVBufPool *pPool = NULL; SVBufPool *pPool = NULL;
int ret; int64_t size = pVnode->config.szBuf / VNODE_BUFPOOL_SEGMENTS;
ASSERT(pVnode->pPool == NULL); ASSERT(pVnode->pPool == NULL);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
// create pool // create pool
ret = vnodeBufPoolCreate(pVnode, size, &pPool); if (vnodeBufPoolCreate(pVnode, size, &pPool)) {
if (ret < 0) {
vError("vgId:%d, failed to open vnode buffer pool since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d, failed to open vnode buffer pool since %s", TD_VID(pVnode), tstrerror(terrno));
vnodeCloseBufPool(pVnode); vnodeCloseBufPool(pVnode);
return -1; return -1;
...@@ -41,7 +74,6 @@ int vnodeOpenBufPool(SVnode *pVnode, int64_t size) { ...@@ -41,7 +74,6 @@ int vnodeOpenBufPool(SVnode *pVnode, int64_t size) {
} }
vDebug("vgId:%d, vnode buffer pool is opened, size:%" PRId64, TD_VID(pVnode), size); vDebug("vgId:%d, vnode buffer pool is opened, size:%" PRId64, TD_VID(pVnode), size);
return 0; return 0;
} }
...@@ -63,9 +95,7 @@ int vnodeCloseBufPool(SVnode *pVnode) { ...@@ -63,9 +95,7 @@ int vnodeCloseBufPool(SVnode *pVnode) {
} }
void vnodeBufPoolReset(SVBufPool *pPool) { void vnodeBufPoolReset(SVBufPool *pPool) {
SVBufPoolNode *pNode; for (SVBufPoolNode *pNode = pPool->pTail; pNode->prev; pNode = pPool->pTail) {
for (pNode = pPool->pTail; pNode->prev; pNode = pPool->pTail) {
ASSERT(pNode->pnext == &pPool->pTail); ASSERT(pNode->pnext == &pPool->pTail);
pNode->prev->pnext = &pPool->pTail; pNode->prev->pnext = &pPool->pTail;
pPool->pTail = pNode->prev; pPool->pTail = pNode->prev;
...@@ -81,7 +111,7 @@ void vnodeBufPoolReset(SVBufPool *pPool) { ...@@ -81,7 +111,7 @@ void vnodeBufPoolReset(SVBufPool *pPool) {
void *vnodeBufPoolMalloc(SVBufPool *pPool, int size) { void *vnodeBufPoolMalloc(SVBufPool *pPool, int size) {
SVBufPoolNode *pNode; SVBufPoolNode *pNode;
void *p; void *p = NULL;
taosThreadSpinLock(&pPool->lock); taosThreadSpinLock(&pPool->lock);
if (pPool->node.size >= pPool->ptr - pPool->node.data + size) { if (pPool->node.size >= pPool->ptr - pPool->node.data + size) {
// allocate from the anchor node // allocate from the anchor node
...@@ -124,43 +154,6 @@ void vnodeBufPoolFree(SVBufPool *pPool, void *p) { ...@@ -124,43 +154,6 @@ void vnodeBufPoolFree(SVBufPool *pPool, void *p) {
} }
} }
// STATIC METHODS -------------------
static int vnodeBufPoolCreate(SVnode *pVnode, int64_t size, SVBufPool **ppPool) {
SVBufPool *pPool;
pPool = taosMemoryMalloc(sizeof(SVBufPool) + size);
if (pPool == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return -1;
}
if (taosThreadSpinInit(&pPool->lock, 0) != 0) {
taosMemoryFree(pPool);
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
pPool->next = NULL;
pPool->pVnode = pVnode;
pPool->nRef = 0;
pPool->size = 0;
pPool->ptr = pPool->node.data;
pPool->pTail = &pPool->node;
pPool->node.prev = NULL;
pPool->node.pnext = &pPool->pTail;
pPool->node.size = size;
*ppPool = pPool;
return 0;
}
static int vnodeBufPoolDestroy(SVBufPool *pPool) {
vnodeBufPoolReset(pPool);
taosThreadSpinDestroy(&pPool->lock);
taosMemoryFree(pPool);
return 0;
}
void vnodeBufPoolRef(SVBufPool *pPool) { void vnodeBufPoolRef(SVBufPool *pPool) {
int32_t nRef = atomic_fetch_add_32(&pPool->nRef, 1); int32_t nRef = atomic_fetch_add_32(&pPool->nRef, 1);
ASSERT(nRef > 0); ASSERT(nRef > 0);
...@@ -175,6 +168,19 @@ void vnodeBufPoolUnRef(SVBufPool *pPool) { ...@@ -175,6 +168,19 @@ void vnodeBufPoolUnRef(SVBufPool *pPool) {
taosThreadMutexLock(&pVnode->mutex); taosThreadMutexLock(&pVnode->mutex);
int64_t size = pVnode->config.szBuf / VNODE_BUFPOOL_SEGMENTS;
if (pPool->node.size != size) {
SVBufPool *pPoolT = NULL;
if (vnodeBufPoolCreate(pVnode, size, &pPoolT) < 0) {
vWarn("vgId:%d try to change buf pools size from %" PRId64 " to %" PRId64 " since %s", TD_VID(pVnode),
pPool->node.size, size, tstrerror(errno));
} else {
vnodeBufPoolDestroy(pPool);
pPool = pPoolT;
vDebug("vgId:%d change buf pools size from %" PRId64 " to %" PRId64, TD_VID(pVnode), pPool->node.size, size);
}
}
pPool->next = pVnode->pPool; pPool->next = pVnode->pPool;
pVnode->pPool = pPool; pVnode->pPool = pPool;
taosThreadCondSignal(&pVnode->poolNotEmpty); taosThreadCondSignal(&pVnode->poolNotEmpty);
......
...@@ -73,7 +73,7 @@ int vnodeBegin(SVnode *pVnode) { ...@@ -73,7 +73,7 @@ int vnodeBegin(SVnode *pVnode) {
int vnodeShouldCommit(SVnode *pVnode) { int vnodeShouldCommit(SVnode *pVnode) {
if (pVnode->inUse) { if (pVnode->inUse) {
return pVnode->inUse->size > pVnode->config.szBuf / 3; return pVnode->inUse->size > pVnode->inUse->node.size;
} }
return false; return false;
} }
...@@ -236,7 +236,7 @@ int vnodeCommit(SVnode *pVnode) { ...@@ -236,7 +236,7 @@ int vnodeCommit(SVnode *pVnode) {
// preCommit // preCommit
// smaSyncPreCommit(pVnode->pSma); // smaSyncPreCommit(pVnode->pSma);
if(smaAsyncPreCommit(pVnode->pSma) < 0){ if (smaAsyncPreCommit(pVnode->pSma) < 0) {
ASSERT(0); ASSERT(0);
return -1; return -1;
} }
......
...@@ -96,7 +96,7 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) { ...@@ -96,7 +96,7 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
taosThreadCondInit(&pVnode->poolNotEmpty, NULL); taosThreadCondInit(&pVnode->poolNotEmpty, NULL);
// open buffer pool // open buffer pool
if (vnodeOpenBufPool(pVnode, pVnode->config.isHeap ? 0 : pVnode->config.szBuf / 3) < 0) { if (vnodeOpenBufPool(pVnode) < 0) {
vError("vgId:%d, failed to open vnode buffer pool since %s", TD_VID(pVnode), tstrerror(terrno)); vError("vgId:%d, failed to open vnode buffer pool since %s", TD_VID(pVnode), tstrerror(terrno));
goto _err; goto _err;
} }
......
...@@ -1040,6 +1040,23 @@ static int32_t vnodeProcessAlterConfigReq(SVnode *pVnode, int64_t version, void ...@@ -1040,6 +1040,23 @@ static int32_t vnodeProcessAlterConfigReq(SVnode *pVnode, int64_t version, void
tsdbCacheSetCapacity(pVnode, (size_t)pVnode->config.cacheLastSize * 1024 * 1024); tsdbCacheSetCapacity(pVnode, (size_t)pVnode->config.cacheLastSize * 1024 * 1024);
} }
if (pVnode->config.szBuf != alterReq.buffer * 1024LL * 1024LL) {
vInfo("vgId:%d vnode buffer is changed from %" PRId64 " to %" PRId64, TD_VID(pVnode), pVnode->config.szBuf,
alterReq.buffer * 1024LL * 1024LL);
pVnode->config.szBuf = alterReq.buffer * 1024LL * 1024LL;
}
if (pVnode->config.szCache != alterReq.pages) {
if (metaAlterCache(pVnode->pMeta, alterReq.pages) < 0) {
vError("vgId:%d failed to change vnode pages from %d to %d failed since %s", TD_VID(pVnode),
pVnode->config.szCache, alterReq.pages, tstrerror(errno));
return errno;
} else {
vInfo("vgId:%d vnode pages is changed from %d to %d", TD_VID(pVnode), pVnode->config.szCache, alterReq.pages);
pVnode->config.szCache = alterReq.pages;
}
}
if (pVnode->config.cacheLast != alterReq.cacheLast) { if (pVnode->config.cacheLast != alterReq.cacheLast) {
pVnode->config.cacheLast = alterReq.cacheLast; pVnode->config.cacheLast = alterReq.cacheLast;
} }
......
...@@ -606,8 +606,6 @@ typedef struct SStreamIntervalOperatorInfo { ...@@ -606,8 +606,6 @@ typedef struct SStreamIntervalOperatorInfo {
SArray* pDelWins; // SWinRes SArray* pDelWins; // SWinRes
int32_t delIndex; int32_t delIndex;
SSDataBlock* pDelRes; SSDataBlock* pDelRes;
SSDataBlock* pUpdateRes;
bool returnUpdate;
SPhysiNode* pPhyNode; // create new child SPhysiNode* pPhyNode; // create new child
SHashObj* pPullDataMap; SHashObj* pPullDataMap;
SArray* pPullWins; // SPullWindowInfo SArray* pPullWins; // SPullWindowInfo
......
...@@ -1331,8 +1331,8 @@ void appendOneRow(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* ...@@ -1331,8 +1331,8 @@ void appendOneRow(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t*
colDataAppend(pEndTsCol, pBlock->info.rows, (const char*)pEndTs, false); colDataAppend(pEndTsCol, pBlock->info.rows, (const char*)pEndTs, false);
colDataAppend(pUidCol, pBlock->info.rows, (const char*)pUid, false); colDataAppend(pUidCol, pBlock->info.rows, (const char*)pUid, false);
colDataAppend(pGpCol, pBlock->info.rows, (const char*)pGp, false); colDataAppend(pGpCol, pBlock->info.rows, (const char*)pGp, false);
colDataAppendNULL(pCalStartCol, pBlock->info.rows); colDataAppend(pCalStartCol, pBlock->info.rows, (const char*)pStartTs, false);
colDataAppendNULL(pCalEndCol, pBlock->info.rows); colDataAppend(pCalEndCol, pBlock->info.rows, (const char*)pEndTs, false);
pBlock->info.rows++; pBlock->info.rows++;
} }
...@@ -1376,7 +1376,7 @@ static void checkUpdateData(SStreamScanInfo* pInfo, bool invertible, SSDataBlock ...@@ -1376,7 +1376,7 @@ static void checkUpdateData(SStreamScanInfo* pInfo, bool invertible, SSDataBlock
} }
} }
static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock) { static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock, bool filter) {
SDataBlockInfo* pBlockInfo = &pInfo->pRes->info; SDataBlockInfo* pBlockInfo = &pInfo->pRes->info;
SOperatorInfo* pOperator = pInfo->pStreamScanOp; SOperatorInfo* pOperator = pInfo->pStreamScanOp;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
...@@ -1430,7 +1430,9 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock ...@@ -1430,7 +1430,9 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock
} }
} }
doFilter(pInfo->pCondition, pInfo->pRes, NULL); if (filter) {
doFilter(pInfo->pCondition, pInfo->pRes, NULL);
}
blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex); blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex);
blockDataFreeRes((SSDataBlock*)pBlock); blockDataFreeRes((SSDataBlock*)pBlock);
return 0; return 0;
...@@ -1466,7 +1468,7 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) { ...@@ -1466,7 +1468,7 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
continue; continue;
} }
setBlockIntoRes(pInfo, &block); setBlockIntoRes(pInfo, &block, true);
if (pBlockInfo->rows > 0) { if (pBlockInfo->rows > 0) {
return pInfo->pRes; return pInfo->pRes;
...@@ -1507,7 +1509,7 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) { ...@@ -1507,7 +1509,7 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
tqNextBlock(pInfo->tqReader, &ret); tqNextBlock(pInfo->tqReader, &ret);
if (ret.fetchType == FETCH_TYPE__DATA) { if (ret.fetchType == FETCH_TYPE__DATA) {
blockDataCleanup(pInfo->pRes); blockDataCleanup(pInfo->pRes);
if (setBlockIntoRes(pInfo, &ret.data) < 0) { if (setBlockIntoRes(pInfo, &ret.data, true) < 0) {
ASSERT(0); ASSERT(0);
} }
if (pInfo->pRes->info.rows > 0) { if (pInfo->pRes->info.rows > 0) {
...@@ -1771,6 +1773,7 @@ FETCH_NEXT_BLOCK: ...@@ -1771,6 +1773,7 @@ FETCH_NEXT_BLOCK:
// printDataBlock(pSDB, "stream scan update"); // printDataBlock(pSDB, "stream scan update");
return pSDB; return pSDB;
} }
blockDataCleanup(pInfo->pUpdateDataRes);
pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE; pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE;
} break; } break;
default: default:
...@@ -1821,7 +1824,7 @@ FETCH_NEXT_BLOCK: ...@@ -1821,7 +1824,7 @@ FETCH_NEXT_BLOCK:
continue; continue;
} }
setBlockIntoRes(pInfo, &block); setBlockIntoRes(pInfo, &block, false);
if (updateInfoIgnore(pInfo->pUpdateInfo, &pInfo->pRes->info.window, pInfo->pRes->info.groupId, if (updateInfoIgnore(pInfo->pUpdateInfo, &pInfo->pRes->info.window, pInfo->pRes->info.groupId,
pInfo->pRes->info.version)) { pInfo->pRes->info.version)) {
...@@ -1830,11 +1833,30 @@ FETCH_NEXT_BLOCK: ...@@ -1830,11 +1833,30 @@ FETCH_NEXT_BLOCK:
continue; continue;
} }
if (pBlockInfo->rows > 0) { if (pInfo->pUpdateInfo) {
checkUpdateData(pInfo, true, pInfo->pRes, true);
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlockInfo->window.ekey);
if (pInfo->pUpdateDataRes->info.rows > 0) {
pInfo->updateResIndex = 0;
if (pInfo->pUpdateDataRes->info.type == STREAM_CLEAR) {
pInfo->scanMode = STREAM_SCAN_FROM_UPDATERES;
} else if (pInfo->pUpdateDataRes->info.type == STREAM_INVERT) {
pInfo->scanMode = STREAM_SCAN_FROM_RES;
return pInfo->pUpdateDataRes;
} else if (pInfo->pUpdateDataRes->info.type == STREAM_DELETE_DATA) {
pInfo->scanMode = STREAM_SCAN_FROM_DELETE_DATA;
}
}
}
doFilter(pInfo->pCondition, pInfo->pRes, NULL);
blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex);
if (pBlockInfo->rows > 0 || pInfo->pUpdateDataRes->info.rows > 0) {
break; break;
} }
} }
if (pBlockInfo->rows > 0) { if (pBlockInfo->rows > 0 || pInfo->pUpdateDataRes->info.rows > 0) {
break; break;
} else { } else {
pInfo->tqReader->pMsg = NULL; pInfo->tqReader->pMsg = NULL;
...@@ -1848,32 +1870,16 @@ FETCH_NEXT_BLOCK: ...@@ -1848,32 +1870,16 @@ FETCH_NEXT_BLOCK:
pOperator->resultInfo.totalRows += pBlockInfo->rows; pOperator->resultInfo.totalRows += pBlockInfo->rows;
// printDataBlock(pInfo->pRes, "stream scan"); // printDataBlock(pInfo->pRes, "stream scan");
if (pBlockInfo->rows == 0) {
updateInfoDestoryColseWinSBF(pInfo->pUpdateInfo);
/*pOperator->status = OP_EXEC_DONE;*/
} else if (pInfo->pUpdateInfo) {
checkUpdateData(pInfo, true, pInfo->pRes, true);
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlockInfo->window.ekey);
if (pInfo->pUpdateDataRes->info.rows > 0) {
pInfo->updateResIndex = 0;
if (pInfo->pUpdateDataRes->info.type == STREAM_CLEAR) {
pInfo->scanMode = STREAM_SCAN_FROM_UPDATERES;
} else if (pInfo->pUpdateDataRes->info.type == STREAM_INVERT) {
pInfo->scanMode = STREAM_SCAN_FROM_RES;
return pInfo->pUpdateDataRes;
} else if (pInfo->pUpdateDataRes->info.type == STREAM_DELETE_DATA) {
pInfo->scanMode = STREAM_SCAN_FROM_DELETE_DATA;
}
}
}
qDebug("scan rows: %d", pBlockInfo->rows); qDebug("scan rows: %d", pBlockInfo->rows);
if (pBlockInfo->rows > 0) { if (pBlockInfo->rows > 0) {
return pInfo->pRes; return pInfo->pRes;
} else {
goto NEXT_SUBMIT_BLK;
} }
/*return (pBlockInfo->rows == 0) ? NULL : pInfo->pRes;*/
if (pInfo->pUpdateDataRes->info.rows > 0) {
goto FETCH_NEXT_BLOCK;
}
goto NEXT_SUBMIT_BLK;
} else { } else {
ASSERT(0); ASSERT(0);
return NULL; return NULL;
......
...@@ -414,14 +414,17 @@ static bool setTimeWindowInterpolationEndTs(SIntervalAggOperatorInfo* pInfo, SEx ...@@ -414,14 +414,17 @@ static bool setTimeWindowInterpolationEndTs(SIntervalAggOperatorInfo* pInfo, SEx
return true; return true;
} }
bool inSlidingWindow(SInterval* pInterval, STimeWindow* pWin, SDataBlockInfo* pBlockInfo) { bool inCalSlidingWindow(SInterval* pInterval, STimeWindow* pWin, TSKEY calStart, TSKEY calEnd) {
if (pInterval->interval != pInterval->sliding && if (pInterval->interval != pInterval->sliding && (pWin->ekey < calStart || pWin->skey > calEnd)) {
(pWin->ekey < pBlockInfo->calWin.skey || pWin->skey > pBlockInfo->calWin.ekey)) {
return false; return false;
} }
return true; return true;
} }
bool inSlidingWindow(SInterval* pInterval, STimeWindow* pWin, SDataBlockInfo* pBlockInfo) {
return inCalSlidingWindow(pInterval, pWin, pBlockInfo->calWin.skey, pBlockInfo->calWin.ekey);
}
static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo, static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext, SDataBlockInfo* pDataBlockInfo,
TSKEY* primaryKeys, int32_t prevPosition, int32_t order) { TSKEY* primaryKeys, int32_t prevPosition, int32_t order) {
bool ascQuery = (order == TSDB_ORDER_ASC); bool ascQuery = (order == TSDB_ORDER_ASC);
...@@ -912,6 +915,8 @@ int32_t compareWinRes(void* pKey, void* data, int32_t index) { ...@@ -912,6 +915,8 @@ int32_t compareWinRes(void* pKey, void* data, int32_t index) {
} }
static void removeDeleteResults(SHashObj* pUpdatedMap, SArray* pDelWins) { static void removeDeleteResults(SHashObj* pUpdatedMap, SArray* pDelWins) {
taosArraySort(pDelWins, sWinKeyCmprImpl);
taosArrayRemoveDuplicate(pDelWins, sWinKeyCmprImpl, NULL);
int32_t delSize = taosArrayGetSize(pDelWins); int32_t delSize = taosArrayGetSize(pDelWins);
if (taosHashGetSize(pUpdatedMap) == 0 || delSize == 0) { if (taosHashGetSize(pUpdatedMap) == 0 || delSize == 0) {
return; return;
...@@ -1387,7 +1392,7 @@ static bool doClearWindow(SAggSupporter* pAggSup, SExprSupp* pSup, char* pData, ...@@ -1387,7 +1392,7 @@ static bool doClearWindow(SAggSupporter* pAggSup, SExprSupp* pSup, char* pData,
return true; return true;
} }
static bool doDeleteWindow(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId, int32_t numOfOutput) { static bool doDeleteWindow(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId) {
SStreamIntervalOperatorInfo* pInfo = pOperator->info; SStreamIntervalOperatorInfo* pInfo = pOperator->info;
SWinKey key = {.ts = ts, .groupId = groupId}; SWinKey key = {.ts = ts, .groupId = groupId};
tSimpleHashRemove(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey)); tSimpleHashRemove(pInfo->aggSup.pResultRowHashTable, &key, sizeof(SWinKey));
...@@ -1395,21 +1400,37 @@ static bool doDeleteWindow(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId, ...@@ -1395,21 +1400,37 @@ static bool doDeleteWindow(SOperatorInfo* pOperator, TSKEY ts, uint64_t groupId,
return true; return true;
} }
static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, int32_t numOfOutput, SSDataBlock* pBlock, static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDataBlock* pBlock, SArray* pUpWins,
SArray* pUpWins, SHashObj* pUpdatedMap) { SHashObj* pUpdatedMap) {
SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX); SStreamIntervalOperatorInfo* pInfo = pOperator->info;
TSKEY* startTsCols = (TSKEY*)pStartTsCol->pData; SColumnInfoData* pStartTsCol = taosArrayGet(pBlock->pDataBlock, START_TS_COLUMN_INDEX);
SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX); TSKEY* startTsCols = (TSKEY*)pStartTsCol->pData;
TSKEY* endTsCols = (TSKEY*)pEndTsCol->pData; SColumnInfoData* pEndTsCol = taosArrayGet(pBlock->pDataBlock, END_TS_COLUMN_INDEX);
SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX); TSKEY* endTsCols = (TSKEY*)pEndTsCol->pData;
uint64_t* pGpDatas = (uint64_t*)pGpCol->pData; SColumnInfoData* pCalStTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_START_TS_COLUMN_INDEX);
TSKEY* calStTsCols = (TSKEY*)pCalStTsCol->pData;
SColumnInfoData* pCalEnTsCol = taosArrayGet(pBlock->pDataBlock, CALCULATE_END_TS_COLUMN_INDEX);
TSKEY* calEnTsCols = (TSKEY*)pCalEnTsCol->pData;
SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, GROUPID_COLUMN_INDEX);
uint64_t* pGpDatas = (uint64_t*)pGpCol->pData;
for (int32_t i = 0; i < pBlock->info.rows; i++) { for (int32_t i = 0; i < pBlock->info.rows; i++) {
SResultRowInfo dumyInfo; SResultRowInfo dumyInfo;
dumyInfo.cur.pageId = -1; dumyInfo.cur.pageId = -1;
STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, startTsCols[i], pInterval, TSDB_ORDER_ASC); STimeWindow win = {0};
if (IS_FINAL_OP(pInfo)) {
win.skey = startTsCols[i];
win.ekey = endTsCols[i];
} else {
win = getActiveTimeWindow(NULL, &dumyInfo, startTsCols[i], pInterval, TSDB_ORDER_ASC);
}
do { do {
if (!inCalSlidingWindow(pInterval, &win, calStTsCols[i], calEnTsCols[i])) {
getNextTimeWindow(pInterval, pInterval->precision, TSDB_ORDER_ASC, &win);
continue;
}
uint64_t winGpId = pGpDatas[i]; uint64_t winGpId = pGpDatas[i];
bool res = doDeleteWindow(pOperator, win.skey, winGpId, numOfOutput); bool res = doDeleteWindow(pOperator, win.skey, winGpId);
SWinKey winRes = {.ts = win.skey, .groupId = winGpId}; SWinKey winRes = {.ts = win.skey, .groupId = winGpId};
if (pUpWins && res) { if (pUpWins && res) {
taosArrayPush(pUpWins, &winRes); taosArrayPush(pUpWins, &winRes);
...@@ -1511,16 +1532,43 @@ static int32_t getAllIntervalWindow(SSHashObj* pHashMap, SHashObj* resWins) { ...@@ -1511,16 +1532,43 @@ static int32_t getAllIntervalWindow(SSHashObj* pHashMap, SHashObj* resWins) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t compareWinKey(void* pKey, void* data, int32_t index) {
SArray* res = (SArray*)data;
SWinKey* pos = taosArrayGet(res, index);
SWinKey* pData = (SWinKey*)pKey;
if (pData->ts == pos->ts) {
if (pData->groupId > pos->groupId) {
return 1;
} else if (pData->groupId < pos->groupId) {
return -1;
}
return 0;
} else if (pData->ts > pos->ts) {
return 1;
}
return -1;
}
static int32_t closeStreamIntervalWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SInterval* pInterval, static int32_t closeStreamIntervalWindow(SSHashObj* pHashMap, STimeWindowAggSupp* pTwSup, SInterval* pInterval,
SHashObj* pPullDataMap, SHashObj* closeWins, SOperatorInfo* pOperator) { SHashObj* pPullDataMap, SHashObj* closeWins, SArray* pDelWins,
SOperatorInfo* pOperator) {
qDebug("===stream===close interval window"); qDebug("===stream===close interval window");
void* pIte = NULL; void* pIte = NULL;
size_t keyLen = 0; size_t keyLen = 0;
int32_t iter = 0; int32_t iter = 0;
SStreamIntervalOperatorInfo* pInfo = pOperator->info; SStreamIntervalOperatorInfo* pInfo = pOperator->info;
int32_t delSize = taosArrayGetSize(pDelWins);
while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) { while ((pIte = tSimpleHashIterate(pHashMap, pIte, &iter)) != NULL) {
void* key = tSimpleHashGetKey(pIte, &keyLen); void* key = tSimpleHashGetKey(pIte, &keyLen);
SWinKey* pWinKey = (SWinKey*)key; SWinKey* pWinKey = (SWinKey*)key;
if (delSize > 0) {
int32_t index = binarySearchCom(pDelWins, delSize, pWinKey, TSDB_ORDER_DESC, compareWinKey);
if (index >= 0 && 0 == compareWinKey(pWinKey, pDelWins, index)) {
taosArrayRemove(pDelWins, index);
delSize = taosArrayGetSize(pDelWins);
}
}
void* chIds = taosHashGet(pPullDataMap, pWinKey, sizeof(SWinKey)); void* chIds = taosHashGet(pPullDataMap, pWinKey, sizeof(SWinKey));
STimeWindow win = { STimeWindow win = {
.skey = pWinKey->ts, .skey = pWinKey->ts,
...@@ -1624,7 +1672,7 @@ static void closeChildIntervalWindow(SOperatorInfo* pOperator, SArray* pChildren ...@@ -1624,7 +1672,7 @@ static void closeChildIntervalWindow(SOperatorInfo* pOperator, SArray* pChildren
ASSERT(pChInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE); ASSERT(pChInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE);
pChInfo->twAggSup.maxTs = TMAX(pChInfo->twAggSup.maxTs, maxTs); pChInfo->twAggSup.maxTs = TMAX(pChInfo->twAggSup.maxTs, maxTs);
closeStreamIntervalWindow(pChInfo->aggSup.pResultRowHashTable, &pChInfo->twAggSup, &pChInfo->interval, NULL, NULL, closeStreamIntervalWindow(pChInfo->aggSup.pResultRowHashTable, &pChInfo->twAggSup, &pChInfo->interval, NULL, NULL,
pOperator); NULL, pOperator);
} }
} }
...@@ -1694,7 +1742,6 @@ void destroyStreamFinalIntervalOperatorInfo(void* param) { ...@@ -1694,7 +1742,6 @@ void destroyStreamFinalIntervalOperatorInfo(void* param) {
taosHashCleanup(pInfo->pPullDataMap); taosHashCleanup(pInfo->pPullDataMap);
taosArrayDestroy(pInfo->pPullWins); taosArrayDestroy(pInfo->pPullWins);
blockDataDestroy(pInfo->pPullDataRes); blockDataDestroy(pInfo->pPullDataRes);
blockDataDestroy(pInfo->pUpdateRes);
taosArrayDestroy(pInfo->pDelWins); taosArrayDestroy(pInfo->pDelWins);
blockDataDestroy(pInfo->pDelRes); blockDataDestroy(pInfo->pDelRes);
taosMemoryFreeClear(pInfo->pState); taosMemoryFreeClear(pInfo->pState);
...@@ -2862,11 +2909,7 @@ static void rebuildIntervalWindow(SOperatorInfo* pOperator, SExprSupp* pSup, SAr ...@@ -2862,11 +2909,7 @@ static void rebuildIntervalWindow(SOperatorInfo* pOperator, SExprSupp* pSup, SAr
isCloseWindow(&parentWin, &pInfo->twAggSup)) { isCloseWindow(&parentWin, &pInfo->twAggSup)) {
continue; continue;
} }
int32_t code = setOutputBuf(pInfo->pState, &parentWin, &pCurResult, pWinRes->groupId, pSup->pCtx, numOfOutput,
pSup->rowEntryInfoOffset, &pInfo->aggSup);
if (code != TSDB_CODE_SUCCESS || pCurResult == NULL) {
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
int32_t numOfChildren = taosArrayGetSize(pInfo->pChildren); int32_t numOfChildren = taosArrayGetSize(pInfo->pChildren);
int32_t num = 0; int32_t num = 0;
for (int32_t j = 0; j < numOfChildren; j++) { for (int32_t j = 0; j < numOfChildren; j++) {
...@@ -2876,6 +2919,13 @@ static void rebuildIntervalWindow(SOperatorInfo* pOperator, SExprSupp* pSup, SAr ...@@ -2876,6 +2919,13 @@ static void rebuildIntervalWindow(SOperatorInfo* pOperator, SExprSupp* pSup, SAr
if (!hasIntervalWindow(pChInfo->pState, pWinRes)) { if (!hasIntervalWindow(pChInfo->pState, pWinRes)) {
continue; continue;
} }
if (num == 0) {
int32_t code = setOutputBuf(pInfo->pState, &parentWin, &pCurResult, pWinRes->groupId, pSup->pCtx, numOfOutput,
pSup->rowEntryInfoOffset, &pInfo->aggSup);
if (code != TSDB_CODE_SUCCESS || pCurResult == NULL) {
T_LONG_JMP(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
}
num++; num++;
SResultRow* pChResult = NULL; SResultRow* pChResult = NULL;
setOutputBuf(pChInfo->pState, &parentWin, &pChResult, pWinRes->groupId, pChildSup->pCtx, pChildSup->numOfExprs, setOutputBuf(pChInfo->pState, &parentWin, &pChResult, pWinRes->groupId, pChildSup->pCtx, pChildSup->numOfExprs,
...@@ -3214,25 +3264,19 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { ...@@ -3214,25 +3264,19 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
return NULL; return NULL;
} else { } else {
if (!IS_FINAL_OP(pInfo)) { if (!IS_FINAL_OP(pInfo)) {
doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes);
if (pInfo->pDelRes->info.rows != 0) {
// process the rest of the data
printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi");
return pInfo->pDelRes;
}
doBuildResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo); doBuildResult(pOperator, pInfo->pState, pInfo->binfo.pRes, &pInfo->groupResInfo);
if (pInfo->binfo.pRes->info.rows != 0) { if (pInfo->binfo.pRes->info.rows != 0) {
printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi");
return pInfo->binfo.pRes; return pInfo->binfo.pRes;
} }
} }
if (pInfo->pUpdateRes->info.rows != 0 && pInfo->returnUpdate) {
pInfo->returnUpdate = false;
ASSERT(!IS_FINAL_OP(pInfo));
printDataBlock(pInfo->pUpdateRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi");
// process the rest of the data
return pInfo->pUpdateRes;
}
doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes);
if (pInfo->pDelRes->info.rows != 0) {
// process the rest of the data
printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi");
return pInfo->pDelRes;
}
} }
SArray* pUpdated = taosArrayInit(4, POINTER_BYTES); SArray* pUpdated = taosArrayInit(4, POINTER_BYTES);
...@@ -3241,8 +3285,6 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { ...@@ -3241,8 +3285,6 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
while (1) { while (1) {
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
if (pBlock == NULL) { if (pBlock == NULL) {
clearSpecialDataBlock(pInfo->pUpdateRes);
removeDeleteResults(pUpdatedMap, pInfo->pDelWins);
pOperator->status = OP_RES_TO_RETURN; pOperator->status = OP_RES_TO_RETURN;
qDebug("%s return data", IS_FINAL_OP(pInfo) ? "interval final" : "interval semi"); qDebug("%s return data", IS_FINAL_OP(pInfo) ? "interval final" : "interval semi");
break; break;
...@@ -3252,34 +3294,16 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { ...@@ -3252,34 +3294,16 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
ASSERT(pBlock->info.type != STREAM_INVERT); ASSERT(pBlock->info.type != STREAM_INVERT);
if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PULL_DATA) { if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PULL_DATA) {
pInfo->binfo.pRes->info.type = pBlock->info.type; pInfo->binfo.pRes->info.type = pBlock->info.type;
} else if (pBlock->info.type == STREAM_CLEAR) { } else if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
SArray* pUpWins = taosArrayInit(8, sizeof(SWinKey)); pBlock->info.type == STREAM_CLEAR) {
doDeleteWindows(pOperator, &pInfo->interval, pOperator->exprSupp.numOfExprs, pBlock, pUpWins, NULL);
if (IS_FINAL_OP(pInfo)) {
int32_t childIndex = getChildIndex(pBlock);
SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex);
SStreamIntervalOperatorInfo* pChildInfo = pChildOp->info;
SExprSupp* pChildSup = &pChildOp->exprSupp;
doDeleteWindows(pChildOp, &pChildInfo->interval, pChildOp->exprSupp.numOfExprs, pBlock, NULL, NULL);
rebuildIntervalWindow(pOperator, pSup, pUpWins, pUpdatedMap);
taosArrayDestroy(pUpWins);
continue;
}
removeResults(pUpWins, pUpdatedMap);
copyDataBlock(pInfo->pUpdateRes, pBlock);
pInfo->returnUpdate = true;
taosArrayDestroy(pUpWins);
break;
} else if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT) {
SArray* delWins = taosArrayInit(8, sizeof(SWinKey)); SArray* delWins = taosArrayInit(8, sizeof(SWinKey));
doDeleteWindows(pOperator, &pInfo->interval, pOperator->exprSupp.numOfExprs, pBlock, delWins, pUpdatedMap); doDeleteWindows(pOperator, &pInfo->interval, pBlock, delWins, pUpdatedMap);
if (IS_FINAL_OP(pInfo)) { if (IS_FINAL_OP(pInfo)) {
int32_t childIndex = getChildIndex(pBlock); int32_t childIndex = getChildIndex(pBlock);
SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex); SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, childIndex);
SStreamIntervalOperatorInfo* pChildInfo = pChildOp->info; SStreamIntervalOperatorInfo* pChildInfo = pChildOp->info;
SExprSupp* pChildSup = &pChildOp->exprSupp; SExprSupp* pChildSup = &pChildOp->exprSupp;
doDeleteWindows(pChildOp, &pChildInfo->interval, pChildOp->exprSupp.numOfExprs, pBlock, NULL, NULL); doDeleteWindows(pChildOp, &pChildInfo->interval, pBlock, NULL, NULL);
rebuildIntervalWindow(pOperator, pSup, delWins, pUpdatedMap); rebuildIntervalWindow(pOperator, pSup, delWins, pUpdatedMap);
addRetriveWindow(delWins, pInfo); addRetriveWindow(delWins, pInfo);
taosArrayAddAll(pInfo->pDelWins, delWins); taosArrayAddAll(pInfo->pDelWins, delWins);
...@@ -3294,7 +3318,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { ...@@ -3294,7 +3318,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pUpdatedMap); getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pUpdatedMap);
continue; continue;
} else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_OP(pInfo)) { } else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_OP(pInfo)) {
doDeleteWindows(pOperator, &pInfo->interval, pOperator->exprSupp.numOfExprs, pBlock, NULL, pUpdatedMap); doDeleteWindows(pOperator, &pInfo->interval, pBlock, NULL, pUpdatedMap);
if (taosArrayGetSize(pUpdated) > 0) { if (taosArrayGetSize(pUpdated) > 0) {
break; break;
} }
...@@ -3334,11 +3358,12 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { ...@@ -3334,11 +3358,12 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
minTs = TMIN(minTs, pBlock->info.window.skey); minTs = TMIN(minTs, pBlock->info.window.skey);
} }
removeDeleteResults(pUpdatedMap, pInfo->pDelWins);
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs); pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs);
pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, minTs); pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, minTs);
if (IS_FINAL_OP(pInfo)) { if (IS_FINAL_OP(pInfo)) {
closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval,
pInfo->pPullDataMap, pUpdatedMap, pOperator); pInfo->pPullDataMap, pUpdatedMap, pInfo->pDelWins, pOperator);
closeChildIntervalWindow(pOperator, pInfo->pChildren, pInfo->twAggSup.maxTs); closeChildIntervalWindow(pOperator, pInfo->pChildren, pInfo->twAggSup.maxTs);
} }
pInfo->binfo.pRes->info.watermark = pInfo->twAggSup.maxTs; pInfo->binfo.pRes->info.watermark = pInfo->twAggSup.maxTs;
...@@ -3374,13 +3399,6 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) { ...@@ -3374,13 +3399,6 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
return pInfo->binfo.pRes; return pInfo->binfo.pRes;
} }
if (pInfo->pUpdateRes->info.rows != 0 && pInfo->returnUpdate) {
pInfo->returnUpdate = false;
ASSERT(!IS_FINAL_OP(pInfo));
printDataBlock(pInfo->pUpdateRes, IS_FINAL_OP(pInfo) ? "interval final" : "interval semi");
// process the rest of the data
return pInfo->pUpdateRes;
}
return NULL; return NULL;
} }
...@@ -3455,9 +3473,6 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, ...@@ -3455,9 +3473,6 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream,
goto _error; goto _error;
} }
} }
pInfo->pUpdateRes = createSpecialDataBlock(STREAM_CLEAR);
blockDataEnsureCapacity(pInfo->pUpdateRes, 128);
pInfo->returnUpdate = false;
pInfo->pPhyNode = (SPhysiNode*)nodesCloneNode((SNode*)pPhyNode); pInfo->pPhyNode = (SPhysiNode*)nodesCloneNode((SNode*)pPhyNode);
...@@ -4276,23 +4291,6 @@ static void removeSessionResults(SHashObj* pHashMap, SArray* pWins) { ...@@ -4276,23 +4291,6 @@ static void removeSessionResults(SHashObj* pHashMap, SArray* pWins) {
} }
} }
int32_t compareWinKey(void* pKey, void* data, int32_t index) {
SArray* res = (SArray*)data;
SResKeyPos* pos = taosArrayGetP(res, index);
SWinKey* pData = (SWinKey*)pKey;
if (pData->ts == *(int64_t*)pos->key) {
if (pData->groupId > pos->groupId) {
return 1;
} else if (pData->groupId < pos->groupId) {
return -1;
}
return 0;
} else if (pData->ts > *(int64_t*)pos->key) {
return 1;
}
return -1;
}
static void removeSessionDeleteResults(SArray* update, SHashObj* pStDeleted) { static void removeSessionDeleteResults(SArray* update, SHashObj* pStDeleted) {
int32_t size = taosHashGetSize(pStDeleted); int32_t size = taosHashGetSize(pStDeleted);
if (size == 0) { if (size == 0) {
...@@ -5668,13 +5666,9 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { ...@@ -5668,13 +5666,9 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
} }
printDataBlock(pBlock, "single interval recv"); printDataBlock(pBlock, "single interval recv");
if (pBlock->info.type == STREAM_CLEAR) { if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT ||
doDeleteWindows(pOperator, &pInfo->interval, pOperator->exprSupp.numOfExprs, pBlock, NULL, NULL); pBlock->info.type == STREAM_CLEAR) {
qDebug("%s clear existed time window results for updates checked", GET_TASKID(pTaskInfo)); doDeleteWindows(pOperator, &pInfo->interval, pBlock, pInfo->pDelWins, pUpdatedMap);
continue;
} else if (pBlock->info.type == STREAM_DELETE_DATA || pBlock->info.type == STREAM_DELETE_RESULT) {
doDeleteWindows(pOperator, &pInfo->interval, pOperator->exprSupp.numOfExprs, pBlock, pInfo->pDelWins,
pUpdatedMap);
continue; continue;
} else if (pBlock->info.type == STREAM_GET_ALL) { } else if (pBlock->info.type == STREAM_GET_ALL) {
getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pUpdatedMap); getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pUpdatedMap);
...@@ -5706,8 +5700,9 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { ...@@ -5706,8 +5700,9 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs); pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs);
pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, minTs); pInfo->twAggSup.minTs = TMIN(pInfo->twAggSup.minTs, minTs);
pOperator->status = OP_RES_TO_RETURN; pOperator->status = OP_RES_TO_RETURN;
removeDeleteResults(pUpdatedMap, pInfo->pDelWins);
closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, NULL, pUpdatedMap, closeStreamIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, NULL, pUpdatedMap,
pOperator); pInfo->pDelWins, pOperator);
void* pIte = NULL; void* pIte = NULL;
while ((pIte = taosHashIterate(pUpdatedMap, pIte)) != NULL) { while ((pIte = taosHashIterate(pUpdatedMap, pIte)) != NULL) {
...@@ -5717,7 +5712,6 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { ...@@ -5717,7 +5712,6 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated); initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
removeDeleteResults(pUpdatedMap, pInfo->pDelWins);
taosHashCleanup(pUpdatedMap); taosHashCleanup(pUpdatedMap);
doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes); doBuildDeleteResult(pInfo->pDelWins, &pInfo->delIndex, pInfo->pDelRes);
...@@ -5803,8 +5797,6 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhys ...@@ -5803,8 +5797,6 @@ SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SPhys
*(pInfo->pState) = *(pTaskInfo->streamInfo.pState); *(pInfo->pState) = *(pTaskInfo->streamInfo.pState);
streamStateSetNumber(pInfo->pState, -1); streamStateSetNumber(pInfo->pState, -1);
pInfo->pUpdateRes = NULL;
pInfo->returnUpdate = false;
pInfo->pPhyNode = NULL; // create new child pInfo->pPhyNode = NULL; // create new child
pInfo->pPullDataMap = NULL; pInfo->pPullDataMap = NULL;
pInfo->pPullWins = NULL; // SPullWindowInfo pInfo->pPullWins = NULL; // SPullWindowInfo
......
...@@ -959,8 +959,8 @@ int32_t udfdInitResidentFuncs() { ...@@ -959,8 +959,8 @@ int32_t udfdInitResidentFuncs() {
char* pSave = tsUdfdResFuncs; char* pSave = tsUdfdResFuncs;
char* token; char* token;
while ((token = strtok_r(pSave, ",", &pSave)) != NULL) { while ((token = strtok_r(pSave, ",", &pSave)) != NULL) {
char func[TSDB_FUNC_NAME_LEN] = {0}; char func[TSDB_FUNC_NAME_LEN+1] = {0};
strncpy(func, token, sizeof(func)); strncpy(func, token, TSDB_FUNC_NAME_LEN);
taosArrayPush(global.residentFuncs, func); taosArrayPush(global.residentFuncs, func);
} }
......
...@@ -217,13 +217,13 @@ alter_db_options(A) ::= alter_db_options(B) alter_db_option(C). ...@@ -217,13 +217,13 @@ alter_db_options(A) ::= alter_db_options(B) alter_db_option(C).
%type alter_db_option { SAlterOption } %type alter_db_option { SAlterOption }
%destructor alter_db_option { } %destructor alter_db_option { }
//alter_db_option(A) ::= BUFFER NK_INTEGER(B). { A.type = DB_OPTION_BUFFER; A.val = B; } alter_db_option(A) ::= BUFFER NK_INTEGER(B). { A.type = DB_OPTION_BUFFER; A.val = B; }
alter_db_option(A) ::= CACHEMODEL NK_STRING(B). { A.type = DB_OPTION_CACHEMODEL; A.val = B; } alter_db_option(A) ::= CACHEMODEL NK_STRING(B). { A.type = DB_OPTION_CACHEMODEL; A.val = B; }
alter_db_option(A) ::= CACHESIZE NK_INTEGER(B). { A.type = DB_OPTION_CACHESIZE; A.val = B; } alter_db_option(A) ::= CACHESIZE NK_INTEGER(B). { A.type = DB_OPTION_CACHESIZE; A.val = B; }
alter_db_option(A) ::= WAL_FSYNC_PERIOD NK_INTEGER(B). { A.type = DB_OPTION_FSYNC; A.val = B; } alter_db_option(A) ::= WAL_FSYNC_PERIOD NK_INTEGER(B). { A.type = DB_OPTION_FSYNC; A.val = B; }
alter_db_option(A) ::= KEEP integer_list(B). { A.type = DB_OPTION_KEEP; A.pList = B; } alter_db_option(A) ::= KEEP integer_list(B). { A.type = DB_OPTION_KEEP; A.pList = B; }
alter_db_option(A) ::= KEEP variable_list(B). { A.type = DB_OPTION_KEEP; A.pList = B; } alter_db_option(A) ::= KEEP variable_list(B). { A.type = DB_OPTION_KEEP; A.pList = B; }
//alter_db_option(A) ::= PAGES NK_INTEGER(B). { A.type = DB_OPTION_PAGES; A.val = B; } alter_db_option(A) ::= PAGES NK_INTEGER(B). { A.type = DB_OPTION_PAGES; A.val = B; }
//alter_db_option(A) ::= REPLICA NK_INTEGER(B). { A.type = DB_OPTION_REPLICA; A.val = B; } //alter_db_option(A) ::= REPLICA NK_INTEGER(B). { A.type = DB_OPTION_REPLICA; A.val = B; }
//alter_db_option(A) ::= STRICT NK_STRING(B). { A.type = DB_OPTION_STRICT; A.val = B; } //alter_db_option(A) ::= STRICT NK_STRING(B). { A.type = DB_OPTION_STRICT; A.val = B; }
alter_db_option(A) ::= WAL_LEVEL NK_INTEGER(B). { A.type = DB_OPTION_WAL; A.val = B; } alter_db_option(A) ::= WAL_LEVEL NK_INTEGER(B). { A.type = DB_OPTION_WAL; A.val = B; }
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
...@@ -79,12 +79,12 @@ TEST_F(ParserInitialATest, alterDnode) { ...@@ -79,12 +79,12 @@ TEST_F(ParserInitialATest, alterDnode) {
* alter_database_option ... * alter_database_option ...
* *
* alter_database_option: { * alter_database_option: {
* BUFFER int_value -- todo: range [3, 16384], default 96, unit MB * BUFFER int_value -- range [3, 16384], default 96, unit MB
* | CACHEMODEL {'none' | 'last_row' | 'last_value' | 'both'} -- default 'none' * | CACHEMODEL {'none' | 'last_row' | 'last_value' | 'both'} -- default 'none'
* | CACHESIZE int_value -- range [1, 65536], default 1, unit MB * | CACHESIZE int_value -- range [1, 65536], default 1, unit MB
* | WAL_FSYNC_PERIOD int_value -- rang [0, 180000], default 3000, unit ms * | WAL_FSYNC_PERIOD int_value -- rang [0, 180000], default 3000, unit ms
* | KEEP {int_value | duration_value} -- rang [1, 365000], default 3650, unit day * | KEEP {int_value | duration_value} -- rang [1, 365000], default 3650, unit day
* | PAGES int_value -- todo: rang [64, +oo), default 256, unit page * | PAGES int_value -- rang [64, INT32_MAX], default 256, unit page
* | REPLICA int_value -- todo: enum 1, 3, default 1, unit replica * | REPLICA int_value -- todo: enum 1, 3, default 1, unit replica
* | STRICT {'off' | 'on'} -- todo: default 'off' * | STRICT {'off' | 'on'} -- todo: default 'off'
* | WAL_LEVEL int_value -- enum 1, 2, default 1 * | WAL_LEVEL int_value -- enum 1, 2, default 1
...@@ -162,7 +162,19 @@ TEST_F(ParserInitialATest, alterDatabase) { ...@@ -162,7 +162,19 @@ TEST_F(ParserInitialATest, alterDatabase) {
setAlterDbWal(1); setAlterDbWal(1);
setAlterDbCacheModel(TSDB_CACHE_MODEL_LAST_ROW); setAlterDbCacheModel(TSDB_CACHE_MODEL_LAST_ROW);
setAlterDbSstTrigger(16); setAlterDbSstTrigger(16);
run("ALTER DATABASE test CACHEMODEL 'last_row' CACHESIZE 32 WAL_FSYNC_PERIOD 200 KEEP 10 WAL_LEVEL 1 STT_TRIGGER 16"); setAlterDbBuffer(16);
setAlterDbPages(128);
run("ALTER DATABASE test BUFFER 16 CACHEMODEL 'last_row' CACHESIZE 32 WAL_FSYNC_PERIOD 200 KEEP 10 PAGES 128 "
"WAL_LEVEL 1 STT_TRIGGER 16");
clearAlterDbReq();
initAlterDb("test");
setAlterDbBuffer(3);
run("ALTER DATABASE test BUFFER 3");
setAlterDbBuffer(64);
run("ALTER DATABASE test BUFFER 64");
setAlterDbBuffer(16384);
run("ALTER DATABASE test BUFFER 16384");
clearAlterDbReq(); clearAlterDbReq();
initAlterDb("test"); initAlterDb("test");
...@@ -213,6 +225,15 @@ TEST_F(ParserInitialATest, alterDatabase) { ...@@ -213,6 +225,15 @@ TEST_F(ParserInitialATest, alterDatabase) {
run("ALTER DATABASE test KEEP 14400m,2400h,1500d"); run("ALTER DATABASE test KEEP 14400m,2400h,1500d");
clearAlterDbReq(); clearAlterDbReq();
initAlterDb("test");
setAlterDbPages(64);
run("ALTER DATABASE test PAGES 64");
setAlterDbPages(1024);
run("ALTER DATABASE test PAGES 1024");
setAlterDbPages(16384);
run("ALTER DATABASE test PAGES 16384");
clearAlterDbReq();
initAlterDb("test"); initAlterDb("test");
setAlterDbWal(1); setAlterDbWal(1);
run("ALTER DATABASE test WAL_LEVEL 1"); run("ALTER DATABASE test WAL_LEVEL 1");
...@@ -224,6 +245,8 @@ TEST_F(ParserInitialATest, alterDatabase) { ...@@ -224,6 +245,8 @@ TEST_F(ParserInitialATest, alterDatabase) {
TEST_F(ParserInitialATest, alterDatabaseSemanticCheck) { TEST_F(ParserInitialATest, alterDatabaseSemanticCheck) {
useDb("root", "test"); useDb("root", "test");
run("ALTER DATABASE test BUFFER 2", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test BUFFER 16385", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test CACHEMODEL 'other'", TSDB_CODE_PAR_INVALID_DB_OPTION); run("ALTER DATABASE test CACHEMODEL 'other'", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test CACHESIZE 0", TSDB_CODE_PAR_INVALID_DB_OPTION); run("ALTER DATABASE test CACHESIZE 0", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test CACHESIZE 65537", TSDB_CODE_PAR_INVALID_DB_OPTION); run("ALTER DATABASE test CACHESIZE 65537", TSDB_CODE_PAR_INVALID_DB_OPTION);
...@@ -234,6 +257,7 @@ TEST_F(ParserInitialATest, alterDatabaseSemanticCheck) { ...@@ -234,6 +257,7 @@ TEST_F(ParserInitialATest, alterDatabaseSemanticCheck) {
run("ALTER DATABASE test KEEP 365001", TSDB_CODE_PAR_INVALID_DB_OPTION); run("ALTER DATABASE test KEEP 365001", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test KEEP 1000000000s", TSDB_CODE_PAR_INVALID_DB_OPTION); run("ALTER DATABASE test KEEP 1000000000s", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test KEEP 1w", TSDB_CODE_PAR_INVALID_DB_OPTION); run("ALTER DATABASE test KEEP 1w", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test PAGES 63", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test WAL_LEVEL 0", TSDB_CODE_PAR_INVALID_DB_OPTION); run("ALTER DATABASE test WAL_LEVEL 0", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test WAL_LEVEL 3", TSDB_CODE_PAR_INVALID_DB_OPTION); run("ALTER DATABASE test WAL_LEVEL 3", TSDB_CODE_PAR_INVALID_DB_OPTION);
run("ALTER DATABASE test STT_TRIGGER 0", TSDB_CODE_PAR_INVALID_DB_OPTION); run("ALTER DATABASE test STT_TRIGGER 0", TSDB_CODE_PAR_INVALID_DB_OPTION);
......
...@@ -24,7 +24,7 @@ typedef struct SStateKey { ...@@ -24,7 +24,7 @@ typedef struct SStateKey {
int64_t opNum; int64_t opNum;
} SStateKey; } SStateKey;
static inline int SStateKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, int kLen2) { static inline int stateKeyCmpr(const void* pKey1, int kLen1, const void* pKey2, int kLen2) {
SStateKey* pWin1 = (SStateKey*)pKey1; SStateKey* pWin1 = (SStateKey*)pKey1;
SStateKey* pWin2 = (SStateKey*)pKey2; SStateKey* pWin2 = (SStateKey*)pKey2;
...@@ -67,12 +67,12 @@ SStreamState* streamStateOpen(char* path, SStreamTask* pTask, bool specPath) { ...@@ -67,12 +67,12 @@ SStreamState* streamStateOpen(char* path, SStreamTask* pTask, bool specPath) {
} }
// open state storage backend // open state storage backend
if (tdbTbOpen("state.db", sizeof(SStateKey), -1, SStateKeyCmpr, pState->db, &pState->pStateDb) < 0) { if (tdbTbOpen("state.db", sizeof(SStateKey), -1, stateKeyCmpr, pState->db, &pState->pStateDb) < 0) {
goto _err; goto _err;
} }
// todo refactor // todo refactor
if (tdbTbOpen("func.state.db", sizeof(SWinKey), -1, SWinKeyCmpr, pState->db, &pState->pFillStateDb) < 0) { if (tdbTbOpen("func.state.db", sizeof(SWinKey), -1, winKeyCmpr, pState->db, &pState->pFillStateDb) < 0) {
goto _err; goto _err;
} }
......
...@@ -36,6 +36,7 @@ int32_t tdbClose(TDB *pDb); ...@@ -36,6 +36,7 @@ int32_t tdbClose(TDB *pDb);
int32_t tdbBegin(TDB *pDb, TXN *pTxn); int32_t tdbBegin(TDB *pDb, TXN *pTxn);
int32_t tdbCommit(TDB *pDb, TXN *pTxn); int32_t tdbCommit(TDB *pDb, TXN *pTxn);
int32_t tdbAbort(TDB *pDb, TXN *pTxn); int32_t tdbAbort(TDB *pDb, TXN *pTxn);
int32_t tdbAlter(TDB *pDb, int pages);
// TTB // TTB
int32_t tdbTbOpen(const char *tbname, int keyLen, int valLen, tdb_cmpr_fn_t keyCmprFn, TDB *pEnv, TTB **ppTb); int32_t tdbTbOpen(const char *tbname, int keyLen, int valLen, tdb_cmpr_fn_t keyCmprFn, TDB *pEnv, TTB **ppTb);
......
...@@ -97,6 +97,8 @@ int tdbClose(TDB *pDb) { ...@@ -97,6 +97,8 @@ int tdbClose(TDB *pDb) {
return 0; return 0;
} }
int32_t tdbAlter(TDB *pDb, int pages) { return tdbPCacheAlter(pDb->pCache, pages); }
int32_t tdbBegin(TDB *pDb, TXN *pTxn) { int32_t tdbBegin(TDB *pDb, TXN *pTxn) {
SPager *pPager; SPager *pPager;
int ret; int ret;
......
...@@ -61,7 +61,11 @@ int tdbPCacheOpen(int pageSize, int cacheSize, SPCache **ppCache) { ...@@ -61,7 +61,11 @@ int tdbPCacheOpen(int pageSize, int cacheSize, SPCache **ppCache) {
pCache->szPage = pageSize; pCache->szPage = pageSize;
pCache->nPages = cacheSize; pCache->nPages = cacheSize;
pCache->aPage = (SPage **)&pCache[1]; pCache->aPage = (SPage **)tdbOsCalloc(cacheSize, sizeof(SPage *));
if (pCache->aPage == NULL) {
tdbOsFree(pCache);
return -1;
}
if (tdbPCacheOpenImpl(pCache) < 0) { if (tdbPCacheOpenImpl(pCache) < 0) {
tdbOsFree(pCache); tdbOsFree(pCache);
...@@ -75,11 +79,93 @@ int tdbPCacheOpen(int pageSize, int cacheSize, SPCache **ppCache) { ...@@ -75,11 +79,93 @@ int tdbPCacheOpen(int pageSize, int cacheSize, SPCache **ppCache) {
int tdbPCacheClose(SPCache *pCache) { int tdbPCacheClose(SPCache *pCache) {
if (pCache) { if (pCache) {
tdbPCacheCloseImpl(pCache); tdbPCacheCloseImpl(pCache);
tdbOsFree(pCache->aPage);
tdbOsFree(pCache); tdbOsFree(pCache);
} }
return 0; return 0;
} }
// TODO:
// if (pPage->id >= pCache->nPages) {
// free(pPage);
// pCache->aPage[pPage->id] = NULL;
// } else {
// add to free list
// }
static int tdbPCacheAlterImpl(SPCache *pCache, int32_t nPage) {
if (pCache->nPages == nPage) {
return 0;
} else if (pCache->nPages < nPage) {
SPage **aPage = tdbOsCalloc(nPage, sizeof(SPage *));
if (aPage == NULL) {
return -1;
}
for (int32_t iPage = pCache->nPages; iPage < nPage; iPage++) {
if (tdbPageCreate(pCache->szPage, &aPage[iPage], tdbDefaultMalloc, NULL) < 0) {
// TODO: handle error
return -1;
}
// pPage->pgid = 0;
aPage[iPage]->isAnchor = 0;
aPage[iPage]->isLocal = 1;
aPage[iPage]->nRef = 0;
aPage[iPage]->pHashNext = NULL;
aPage[iPage]->pLruNext = NULL;
aPage[iPage]->pLruPrev = NULL;
aPage[iPage]->pDirtyNext = NULL;
// add to local list
aPage[iPage]->id = iPage;
}
// add page to free list
for (int32_t iPage = pCache->nPages; iPage < nPage; iPage++) {
aPage[iPage]->pFreeNext = pCache->pFree;
pCache->pFree = aPage[iPage];
pCache->nFree++;
}
for (int32_t iPage = 0; iPage < pCache->nPage; iPage++) {
aPage[iPage] = pCache->aPage[iPage];
}
tdbOsFree(pCache->aPage);
pCache->aPage = aPage;
} else {
for (SPage **ppPage = &pCache->pFree; *ppPage;) {
int32_t iPage = (*ppPage)->id;
if (iPage >= nPage) {
SPage *pPage = *ppPage;
*ppPage = pPage->pFreeNext;
pCache->aPage[pPage->id] = NULL;
tdbPageDestroy(pPage, tdbDefaultFree, NULL);
pCache->nFree--;
} else {
ppPage = &(*ppPage)->pFreeNext;
}
}
}
pCache->nPages = nPage;
return 0;
}
int tdbPCacheAlter(SPCache *pCache, int32_t nPage) {
int ret = 0;
tdbPCacheLock(pCache);
ret = tdbPCacheAlterImpl(pCache, nPage);
tdbPCacheUnlock(pCache);
return ret;
}
SPage *tdbPCacheFetch(SPCache *pCache, const SPgid *pPgid, TXN *pTxn) { SPage *tdbPCacheFetch(SPCache *pCache, const SPgid *pPgid, TXN *pTxn) {
SPage *pPage; SPage *pPage;
i32 nRef; i32 nRef;
...@@ -310,8 +396,7 @@ static int tdbPCacheOpenImpl(SPCache *pCache) { ...@@ -310,8 +396,7 @@ static int tdbPCacheOpenImpl(SPCache *pCache) {
pCache->nFree = 0; pCache->nFree = 0;
pCache->pFree = NULL; pCache->pFree = NULL;
for (int i = 0; i < pCache->nPages; i++) { for (int i = 0; i < pCache->nPages; i++) {
ret = tdbPageCreate(pCache->szPage, &pPage, tdbDefaultMalloc, NULL); if (tdbPageCreate(pCache->szPage, &pPage, tdbDefaultMalloc, NULL) < 0) {
if (ret < 0) {
// TODO: handle error // TODO: handle error
return -1; return -1;
} }
......
...@@ -216,6 +216,7 @@ int tdbPagerRestore(SPager *pPager, SBTree *pBt); ...@@ -216,6 +216,7 @@ int tdbPagerRestore(SPager *pPager, SBTree *pBt);
int tdbPCacheOpen(int pageSize, int cacheSize, SPCache **ppCache); int tdbPCacheOpen(int pageSize, int cacheSize, SPCache **ppCache);
int tdbPCacheClose(SPCache *pCache); int tdbPCacheClose(SPCache *pCache);
int tdbPCacheAlter(SPCache *pCache, int32_t nPage);
SPage *tdbPCacheFetch(SPCache *pCache, const SPgid *pPgid, TXN *pTxn); SPage *tdbPCacheFetch(SPCache *pCache, const SPgid *pPgid, TXN *pTxn);
void tdbPCacheRelease(SPCache *pCache, SPage *pPage, TXN *pTxn); void tdbPCacheRelease(SPCache *pCache, SPage *pPage, TXN *pTxn);
int tdbPCacheGetPageSize(SPCache *pCache); int tdbPCacheGetPageSize(SPCache *pCache);
......
...@@ -622,4 +622,56 @@ if $data12 != 2 then ...@@ -622,4 +622,56 @@ if $data12 != 2 then
goto loop3 goto loop3
endi endi
sql create database test4 vgroups 1;
sql use test4;
sql create table t1(ts timestamp, a int, b int , c int, d double);
sql create stream streams4 trigger at_once into streamt4 as select _wstart, count(*) c1 from t1 where a > 5 interval(10s);
sql insert into t1 values(1648791213000,1,2,3,1.0);
sleep 200
sql select * from streamt4;
# row 0
if $rows != 0 then
print =====rows=$rows
return -1
endi
sql insert into t1 values(1648791213000,6,2,3,1.0);
$loop_count = 0
loop4:
sleep 200
sql select * from streamt4;
$loop_count = $loop_count + 1
if $loop_count == 10 then
return -1
endi
if $data01 != 1 then
print =====data01=$data01
goto loop4
endi
sql insert into t1 values(1648791213000,2,2,3,1.0);
$loop_count = 0
loop5:
sleep 200
sql select * from streamt4;
$loop_count = $loop_count + 1
if $loop_count == 10 then
return -1
endi
if $rows != 0 then
print =====rows=$rows
goto loop5
endi
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT
...@@ -587,8 +587,6 @@ sleep 300 ...@@ -587,8 +587,6 @@ sleep 300
sql delete from st where ts = 1648791223000; sql delete from st where ts = 1648791223000;
sql select * from test.streamt5;
$loop_count = 0 $loop_count = 0
loop15: loop15:
...@@ -604,11 +602,10 @@ if $rows != 4 then ...@@ -604,11 +602,10 @@ if $rows != 4 then
print =====rows=$rows print =====rows=$rows
print =====rows=$rows print =====rows=$rows
print =====rows=$rows print =====rows=$rows
# goto loop15 #goto loop15
endi endi
$loop_all = $loop_all + 1 $loop_all = $loop_all + 1
print ============loop_all=$loop_all print ============loop_all=$loop_all
......
...@@ -5,15 +5,15 @@ sleep 50 ...@@ -5,15 +5,15 @@ sleep 50
sql connect sql connect
print =============== create database print =============== create database
sql create database test vgroups 1 sql create database test vgroups 1;
sql select * from information_schema.ins_databases sql select * from information_schema.ins_databases;
if $rows != 3 then if $rows != 3 then
return -1 return -1
endi endi
print $data00 $data01 $data02 print $data00 $data01 $data02
sql use test sql use test;
sql create stable st(ts timestamp, a int, b int, c int, d double) tags(ta int,tb int,tc int); sql create stable st(ts timestamp, a int, b int, c int, d double) tags(ta int,tb int,tc int);
sql create table t1 using st tags(1,1,1); sql create table t1 using st tags(1,1,1);
sql create table t2 using st tags(2,2,2); sql create table t2 using st tags(2,2,2);
...@@ -48,8 +48,9 @@ if $loop_count == 10 then ...@@ -48,8 +48,9 @@ if $loop_count == 10 then
return -1 return -1
endi endi
print step 0
sql select * from streamt sql select * from streamt;
# row 0 # row 0
if $data01 != 1 then if $data01 != 1 then
...@@ -97,7 +98,7 @@ endi ...@@ -97,7 +98,7 @@ endi
print step 1 print step 1
sql select * from streamt2 sql select * from streamt2;
# row 0 # row 0
if $data01 != 1 then if $data01 != 1 then
...@@ -239,6 +240,67 @@ if $data32 != 6 then ...@@ -239,6 +240,67 @@ if $data32 != 6 then
goto loop0 goto loop0
endi endi
print step 3.1
sql insert into t1 values(1648791216001,2,2,3,1.1);
$loop_count = 0
loop00:
sleep 300
$loop_count = $loop_count + 1
if $loop_count == 10 then
return -1
endi
sql select * from streamt2;
# row 0
if $data01 != 1 then
print =====data01=$data01
goto loop00
endi
if $data02 != 1 then
print =====data02=$data02
goto loop00
endi
# row 1
if $data11 != 3 then
print =====data11=$data11
goto loop00
endi
if $data12 != 5 then
print =====data12=$data12
goto loop00
endi
# row 2
if $data21 != 3 then
print =====data21=$data21
goto loop00
endi
if $data22 != 7 then
print =====data22=$data22
goto loop00
endi
# row 3
if $data31 != 1 then
print =====data31=$data31
goto loop00
endi
if $data32 != 3 then
print =====data32=$data32
goto loop00
endi
print step 4 print step 4
sql create database test1 vgroups 1 sql create database test1 vgroups 1
...@@ -513,6 +575,8 @@ endi ...@@ -513,6 +575,8 @@ endi
$loop_count = 0 $loop_count = 0
print step 7
loop4: loop4:
sleep 100 sleep 100
......
...@@ -24,7 +24,7 @@ void pressTabKey(SShellCmd* cmd); ...@@ -24,7 +24,7 @@ void pressTabKey(SShellCmd* cmd);
// press othr key // press othr key
void pressOtherKey(char c); void pressOtherKey(char c);
// init shell auto funciton , shell start call once // init shell auto funciton , shell start call once
bool shellAutoInit(); bool shellAutoInit();
// set conn // set conn
......
...@@ -16,68 +16,65 @@ ...@@ -16,68 +16,65 @@
#ifndef __TRIE__ #ifndef __TRIE__
#define __TRIE__ #define __TRIE__
// //
// The prefix search tree is a efficient storage words and search words tree, it support 95 visible ascii code character // The prefix search tree is a efficient storage words and search words tree, it support 95 visible ascii code character
// //
#define FIRST_ASCII 40 // first visiable char is '0' #define FIRST_ASCII 40 // first visiable char is '0'
#define LAST_ASCII 122 // last visilbe char is 'z' #define LAST_ASCII 122 // last visilbe char is 'z'
// capacity save char is 95 // capacity save char is 95
#define CHAR_CNT (LAST_ASCII - FIRST_ASCII + 1) #define CHAR_CNT (LAST_ASCII - FIRST_ASCII + 1)
#define MAX_WORD_LEN 256 // max insert word length #define MAX_WORD_LEN 256 // max insert word length
// define STire // define STire
#define TIRE_TREE 0 #define TIRE_TREE 0
#define TIRE_LIST 1 #define TIRE_LIST 1
typedef struct STireNode { typedef struct STireNode {
struct STireNode** d; struct STireNode** d;
bool end; // record end flag bool end; // record end flag
}STireNode; } STireNode;
typedef struct StrName { typedef struct StrName {
char * name; char* name;
struct StrName * next; struct StrName* next;
}StrName; } StrName;
typedef struct STire { typedef struct STire {
char type; // see define TIRE_ char type; // see define TIRE_
STireNode root; STireNode root;
StrName * head; StrName* head;
StrName * tail; StrName* tail;
int count; // all count int count; // all count
int ref; int ref;
}STire; } STire;
typedef struct SMatchNode { typedef struct SMatchNode {
char* word; char* word;
struct SMatchNode* next; struct SMatchNode* next;
}SMatchNode; } SMatchNode;
typedef struct SMatch { typedef struct SMatch {
SMatchNode* head; SMatchNode* head;
SMatchNode* tail; // append node to tail SMatchNode* tail; // append node to tail
int count; int count;
char pre[MAX_WORD_LEN]; char pre[MAX_WORD_LEN];
}SMatch; } SMatch;
// ----------- interface ------------- // ----------- interface -------------
// create prefix search tree, return value call freeTire to free // create prefix search tree, return value call freeTire to free
STire* createTire(char type); STire* createTire(char type);
// destroy prefix search tree // destroy prefix search tree
void freeTire(STire* tire); void freeTire(STire* tire);
// add a new word // add a new word
bool insertWord(STire* tire, char* word); bool insertWord(STire* tire, char* word);
// add a new word // add a new word
bool deleteWord(STire* tire, char* word); bool deleteWord(STire* tire, char* word);
// match prefix words, if match is not NULL , put all item to match and return match // match prefix words, if match is not NULL , put all item to match and return match
......
...@@ -25,441 +25,326 @@ ...@@ -25,441 +25,326 @@
// //
#define UNION_ALL " union all " #define UNION_ALL " union all "
// extern function // extern function
void shellClearScreen(int32_t ecmd_pos, int32_t cursor_pos); void shellClearScreen(int32_t ecmd_pos, int32_t cursor_pos);
void shellGetPrevCharSize(const char *str, int32_t pos, int32_t *size, int32_t *width); void shellGetPrevCharSize(const char* str, int32_t pos, int32_t* size, int32_t* width);
void shellShowOnScreen(SShellCmd *cmd); void shellShowOnScreen(SShellCmd* cmd);
void shellInsertChar(SShellCmd *cmd, char *c, int size); void shellInsertChar(SShellCmd* cmd, char* c, int size);
bool appendAfterSelect(TAOS * con, SShellCmd * cmd, char* p, int32_t len); bool appendAfterSelect(TAOS* con, SShellCmd* cmd, char* p, int32_t len);
typedef struct SAutoPtr { typedef struct SAutoPtr {
STire* p; STire* p;
int ref; int ref;
}SAutoPtr; } SAutoPtr;
typedef struct SWord{ typedef struct SWord {
int type ; // word type , see WT_ define int type; // word type , see WT_ define
char * word; char* word;
int32_t len; int32_t len;
struct SWord * next; struct SWord* next;
bool free; // if true need free bool free; // if true need free
}SWord; } SWord;
typedef struct { typedef struct {
char * source; char* source;
int32_t source_len; // valid data length in source int32_t source_len; // valid data length in source
int32_t count; int32_t count;
SWord* head; SWord* head;
// matched information // matched information
int32_t matchIndex; // matched word index in words int32_t matchIndex; // matched word index in words
int32_t matchLen; // matched length at matched word int32_t matchLen; // matched length at matched word
}SWords; } SWords;
SWords shellCommands[] = { SWords shellCommands[] = {
{"alter database <db_name> <alter_db_options> <anyword> <alter_db_options> <anyword> <alter_db_options> <anyword> <alter_db_options> <anyword> <alter_db_options> <anyword> ;", 0, 0, NULL}, {"alter database <db_name> <alter_db_options> <anyword> <alter_db_options> <anyword> <alter_db_options> <anyword> "
{"alter dnode <dnode_id> balance ", 0, 0, NULL}, "<alter_db_options> <anyword> <alter_db_options> <anyword> ;",
{"alter dnode <dnode_id> resetlog;", 0, 0, NULL}, 0, 0, NULL},
{"alter dnode <dnode_id> debugFlag 141;", 0, 0, NULL}, {"alter dnode <dnode_id> balance ", 0, 0, NULL},
{"alter dnode <dnode_id> monitor 1;", 0, 0, NULL}, {"alter dnode <dnode_id> resetlog;", 0, 0, NULL},
{"alter all dnodes monitor ", 0, 0, NULL}, {"alter dnode <dnode_id> debugFlag 141;", 0, 0, NULL},
{"alter alldnodes balance ", 0, 0, NULL}, {"alter dnode <dnode_id> monitor 1;", 0, 0, NULL},
{"alter alldnodes resetlog;", 0, 0, NULL}, {"alter all dnodes monitor ", 0, 0, NULL},
{"alter alldnodes debugFlag 141;", 0, 0, NULL}, {"alter alldnodes balance ", 0, 0, NULL},
{"alter alldnodes monitor 1;", 0, 0, NULL}, {"alter alldnodes resetlog;", 0, 0, NULL},
{"alter table <tb_name> <tb_actions> <anyword> ;", 0, 0, NULL}, {"alter alldnodes debugFlag 141;", 0, 0, NULL},
{"alter table modify column", 0, 0, NULL}, {"alter alldnodes monitor 1;", 0, 0, NULL},
{"alter local resetlog;", 0, 0, NULL}, {"alter table <tb_name> <tb_actions> <anyword> ;", 0, 0, NULL},
{"alter local DebugFlag 143;", 0, 0, NULL}, {"alter table modify column", 0, 0, NULL},
{"alter local cDebugFlag 143;", 0, 0, NULL}, {"alter local resetlog;", 0, 0, NULL},
{"alter local uDebugFlag 143;", 0, 0, NULL}, {"alter local DebugFlag 143;", 0, 0, NULL},
{"alter local rpcDebugFlag 143;", 0, 0, NULL}, {"alter local cDebugFlag 143;", 0, 0, NULL},
{"alter local tmrDebugFlag 143;", 0, 0, NULL}, {"alter local uDebugFlag 143;", 0, 0, NULL},
{"alter topic", 0, 0, NULL}, {"alter local rpcDebugFlag 143;", 0, 0, NULL},
{"alter user <user_name> <user_actions> <anyword> ;", 0, 0, NULL}, {"alter local tmrDebugFlag 143;", 0, 0, NULL},
// 20 {"alter topic", 0, 0, NULL},
{"create table <anyword> using <stb_name> tags(", 0, 0, NULL}, {"alter user <user_name> <user_actions> <anyword> ;", 0, 0, NULL},
{"create database <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> ;", 0, 0, NULL}, // 20
{"create dnode ", 0, 0, NULL}, {"create table <anyword> using <stb_name> tags(", 0, 0, NULL},
{"create index ", 0, 0, NULL}, {"create database <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> "
{"create mnode on dnode <dnode_id> ;", 0, 0, NULL}, "<anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> "
{"create qnode on dnode <dnode_id> ;", 0, 0, NULL}, "<db_options> <anyword> <db_options> <anyword> ;",
{"create stream <anyword> into <anyword> as select", 0, 0, NULL}, // 26 append sub sql 0, 0, NULL},
{"create topic <anyword> as select", 0, 0, NULL}, // 27 append sub sql {"create dnode ", 0, 0, NULL},
{"create function ", 0, 0, NULL}, {"create index ", 0, 0, NULL},
{"create user <anyword> pass <anyword> sysinfo 0;", 0, 0, NULL}, {"create mnode on dnode <dnode_id> ;", 0, 0, NULL},
{"create user <anyword> pass <anyword> sysinfo 1;", 0, 0, NULL}, {"create qnode on dnode <dnode_id> ;", 0, 0, NULL},
{"describe <all_table>", 0, 0, NULL}, {"create stream <anyword> into <anyword> as select", 0, 0, NULL}, // 26 append sub sql
{"delete from <all_table> where ", 0, 0, NULL}, {"create topic <anyword> as select", 0, 0, NULL}, // 27 append sub sql
{"drop database <db_name>", 0, 0, NULL}, {"create function ", 0, 0, NULL},
{"drop table <all_table>", 0, 0, NULL}, {"create user <anyword> pass <anyword> sysinfo 0;", 0, 0, NULL},
{"drop dnode <dnode_id>", 0, 0, NULL}, {"create user <anyword> pass <anyword> sysinfo 1;", 0, 0, NULL},
{"drop mnode on dnode <dnode_id> ;", 0, 0, NULL}, {"describe <all_table>", 0, 0, NULL},
{"drop qnode on dnode <dnode_id> ;", 0, 0, NULL}, {"delete from <all_table> where ", 0, 0, NULL},
{"drop user <user_name> ;", 0, 0, NULL}, {"drop database <db_name>", 0, 0, NULL},
// 40 {"drop table <all_table>", 0, 0, NULL},
{"drop function", 0, 0, NULL}, {"drop dnode <dnode_id>", 0, 0, NULL},
{"drop consumer group <anyword> on ", 0, 0, NULL}, {"drop mnode on dnode <dnode_id> ;", 0, 0, NULL},
{"drop topic <topic_name> ;", 0, 0, NULL}, {"drop qnode on dnode <dnode_id> ;", 0, 0, NULL},
{"drop stream <stream_name> ;", 0, 0, NULL}, {"drop user <user_name> ;", 0, 0, NULL},
{"explain select", 0, 0, NULL}, // 44 append sub sql // 40
{"grant all on <anyword> to <user_name> ;", 0, 0, NULL}, {"drop function", 0, 0, NULL},
{"grant read on <anyword> to <user_name> ;", 0, 0, NULL}, {"drop consumer group <anyword> on ", 0, 0, NULL},
{"grant write on <anyword> to <user_name> ;", 0, 0, NULL}, {"drop topic <topic_name> ;", 0, 0, NULL},
{"kill connection <anyword> ;", 0, 0, NULL}, {"drop stream <stream_name> ;", 0, 0, NULL},
{"kill query ", 0, 0, NULL}, {"explain select", 0, 0, NULL}, // 44 append sub sql
{"kill transaction ", 0, 0, NULL}, {"grant all on <anyword> to <user_name> ;", 0, 0, NULL},
{"merge vgroup ", 0, 0, NULL}, {"grant read on <anyword> to <user_name> ;", 0, 0, NULL},
{"reset query cache;", 0, 0, NULL}, {"grant write on <anyword> to <user_name> ;", 0, 0, NULL},
{"revoke all on <anyword> from <user_name> ;", 0, 0, NULL}, {"kill connection <anyword> ;", 0, 0, NULL},
{"revoke read on <anyword> from <user_name> ;", 0, 0, NULL}, {"kill query ", 0, 0, NULL},
{"revoke write on <anyword> from <user_name> ;", 0, 0, NULL}, {"kill transaction ", 0, 0, NULL},
{"select * from <all_table>", 0, 0, NULL}, {"merge vgroup ", 0, 0, NULL},
{"select _block_dist() from <all_table> \\G;", 0, 0, NULL}, {"reset query cache;", 0, 0, NULL},
{"select client_version();", 0, 0, NULL}, {"revoke all on <anyword> from <user_name> ;", 0, 0, NULL},
// 60 {"revoke read on <anyword> from <user_name> ;", 0, 0, NULL},
{"select current_user();", 0, 0, NULL}, {"revoke write on <anyword> from <user_name> ;", 0, 0, NULL},
{"select database();", 0, 0, NULL}, {"select * from <all_table>", 0, 0, NULL},
{"select server_version();", 0, 0, NULL}, {"select _block_dist() from <all_table> \\G;", 0, 0, NULL},
{"select server_status();", 0, 0, NULL}, {"select client_version();", 0, 0, NULL},
{"select now();", 0, 0, NULL}, // 60
{"select today();", 0, 0, NULL}, {"select current_user();", 0, 0, NULL},
{"select timezone();", 0, 0, NULL}, {"select database();", 0, 0, NULL},
{"set max_binary_display_width ", 0, 0, NULL}, {"select server_version();", 0, 0, NULL},
{"show apps;", 0, 0, NULL}, {"select server_status();", 0, 0, NULL},
{"show create database <db_name> \\G;", 0, 0, NULL}, {"select now();", 0, 0, NULL},
{"show create stable <stb_name> \\G;", 0, 0, NULL}, {"select today();", 0, 0, NULL},
{"show create table <tb_name> \\G;", 0, 0, NULL}, {"select timezone();", 0, 0, NULL},
{"show connections;", 0, 0, NULL}, {"set max_binary_display_width ", 0, 0, NULL},
{"show cluster;", 0, 0, NULL}, {"show apps;", 0, 0, NULL},
{"show databases;", 0, 0, NULL}, {"show create database <db_name> \\G;", 0, 0, NULL},
{"show dnodes;", 0, 0, NULL}, {"show create stable <stb_name> \\G;", 0, 0, NULL},
{"show dnode <dnode_id> variables;", 0, 0, NULL}, {"show create table <tb_name> \\G;", 0, 0, NULL},
{"show functions;", 0, 0, NULL}, {"show connections;", 0, 0, NULL},
{"show mnodes;", 0, 0, NULL}, {"show cluster;", 0, 0, NULL},
{"show queries;", 0, 0, NULL}, {"show databases;", 0, 0, NULL},
// 80 {"show dnodes;", 0, 0, NULL},
{"show query <anyword> ;", 0, 0, NULL}, {"show dnode <dnode_id> variables;", 0, 0, NULL},
{"show qnodes;", 0, 0, NULL}, {"show functions;", 0, 0, NULL},
{"show snodes;", 0, 0, NULL}, {"show mnodes;", 0, 0, NULL},
{"show stables;", 0, 0, NULL}, {"show queries;", 0, 0, NULL},
{"show stables like ", 0, 0, NULL}, // 80
{"show streams;", 0, 0, NULL}, {"show query <anyword> ;", 0, 0, NULL},
{"show scores;", 0, 0, NULL}, {"show qnodes;", 0, 0, NULL},
{"show subscriptions;", 0, 0, NULL}, {"show stables;", 0, 0, NULL},
{"show tables;", 0, 0, NULL}, {"show stables like ", 0, 0, NULL},
{"show tables like", 0, 0, NULL}, {"show streams;", 0, 0, NULL},
{"show table distributed <all_table>", 0, 0, NULL}, {"show scores;", 0, 0, NULL},
{"show tags from <tb_name>", 0, 0, NULL}, {"show snodes;", 0, 0, NULL},
{"show tags from <db_name>", 0, 0, NULL}, {"show subscriptions;", 0, 0, NULL},
{"show topics;", 0, 0, NULL}, {"show tables;", 0, 0, NULL},
{"show transactions;", 0, 0, NULL}, {"show tables like", 0, 0, NULL},
{"show users;", 0, 0, NULL}, {"show table distributed <all_table>", 0, 0, NULL},
{"show variables;", 0, 0, NULL}, {"show tags from <tb_name>", 0, 0, NULL},
{"show local variables;", 0, 0, NULL}, {"show tags from <db_name>", 0, 0, NULL},
{"show vnodes <dnode_id>", 0, 0, NULL}, {"show topics;", 0, 0, NULL},
{"show vgroups;", 0, 0, NULL}, {"show transactions;", 0, 0, NULL},
{"show consumers;", 0, 0, NULL}, {"show users;", 0, 0, NULL},
{"show grants;", 0, 0, NULL}, {"show variables;", 0, 0, NULL},
{"split vgroup ", 0, 0, NULL}, {"show local variables;", 0, 0, NULL},
{"insert into <tb_name> values(", 0, 0, NULL}, {"show vnodes <dnode_id>", 0, 0, NULL},
{"insert into <tb_name> using <stb_name> tags(", 0, 0, NULL}, {"show vgroups;", 0, 0, NULL},
{"insert into <tb_name> using <stb_name> <anyword> values(", 0, 0, NULL}, {"show consumers;", 0, 0, NULL},
{"insert into <tb_name> file ", 0, 0, NULL}, {"show grants;", 0, 0, NULL},
{"trim database <db_name>", 0, 0, NULL}, {"split vgroup ", 0, 0, NULL},
{"use <db_name>", 0, 0, NULL}, {"insert into <tb_name> values(", 0, 0, NULL},
{"quit", 0, 0, NULL} {"insert into <tb_name> using <stb_name> tags(", 0, 0, NULL},
}; {"insert into <tb_name> using <stb_name> <anyword> values(", 0, 0, NULL},
{"insert into <tb_name> file ", 0, 0, NULL},
char * keywords[] = { {"trim database <db_name>", 0, 0, NULL},
"and ", {"use <db_name>", 0, 0, NULL},
"asc ", {"quit", 0, 0, NULL}};
"desc ",
"from ", char* keywords[] = {
"fill(", "and ", "asc ", "desc ", "from ", "fill(", "limit ", "where ",
"limit ", "interval(", "order by ", "order by ", "offset ", "or ", "group by ", "now()",
"where ", "session(", "sliding ", "slimit ", "soffset ", "state_window(", "today() ", "union all select ",
"interval(", "partition by "};
"order by ",
"order by ", char* functions[] = {
"offset ", "count(", "sum(",
"or ", "avg(", "last(",
"group by ", "last_row(", "top(",
"now()", "interp(", "max(",
"session(", "min(", "now()",
"sliding ", "today()", "percentile(",
"slimit ", "tail(", "pow(",
"soffset ", "abs(", "atan(",
"state_window(", "acos(", "asin(",
"today() ", "apercentile(", "bottom(",
"union all select ", "cast(", "ceil(",
"partition by " "char_length(", "cos(",
}; "concat(", "concat_ws(",
"csum(", "diff(",
char * functions[] = { "derivative(", "elapsed(",
"count(", "first(", "floor(",
"sum(", "hyperloglog(", "histogram(",
"avg(", "irate(", "leastsquares(",
"last(", "length(", "log(",
"last_row(", "lower(", "ltrim(",
"top(", "mavg(", "mode(",
"interp(", "tan(", "round(",
"max(", "rtrim(", "sample(",
"min(", "sin(", "spread(",
"now()", "substr(", "statecount(",
"today()", "stateduration(", "stddev(",
"percentile(", "sqrt(", "timediff(",
"tail(", "timezone(", "timetruncate(",
"pow(", "twa(", "to_unixtimestamp(",
"abs(", "unique(", "upper(",
"atan(",
"acos(",
"asin(",
"apercentile(",
"bottom(",
"cast(",
"ceil(",
"char_length(",
"cos(",
"concat(",
"concat_ws(",
"csum(",
"diff(",
"derivative(",
"elapsed(",
"first(",
"floor(",
"hyperloglog(",
"histogram(",
"irate(",
"leastsquares(",
"length(",
"log(",
"lower(",
"ltrim(",
"mavg(",
"mode(",
"tan(",
"round(",
"rtrim(",
"sample(",
"sin(",
"spread(",
"substr(",
"statecount(",
"stateduration(",
"stddev(",
"sqrt(",
"timediff(",
"timezone(",
"timetruncate(",
"twa(",
"to_unixtimestamp(",
"unique(",
"upper(",
};
char * tb_actions[] = {
"add column ",
"modify column ",
"drop column ",
"rename column ",
"add tag ",
"modify tag ",
"drop tag ",
"rename tag ",
"set tag ",
};
char * user_actions[] = {
"pass ",
"enable ",
"sysinfo "
};
char * tb_options[] = {
"comment ",
"watermark ",
"max_delay ",
"ttl ",
"rollup(",
"sma("
};
char * db_options[] = {
"keep ",
"replica ",
"precision ",
"strict ",
"buffer ",
"cachemodel ",
"cachesize ",
"comp ",
"duration ",
"wal_fsync_period",
"maxrows ",
"minrows ",
"pages ",
"pagesize ",
"retentions ",
"wal_level ",
"vgroups ",
"single_stable ",
"wal_retention_period ",
"wal_roll_period ",
"wal_retention_size ",
"wal_segment_size "
};
char * alter_db_options[] = {
"keep ",
"cachemodel ",
"cachesize ",
"wal_fsync_period ",
"wal_level "
};
char * data_types[] = {
"timestamp",
"int",
"int unsigned",
"varchar(16)",
"float",
"double",
"binary(16)",
"nchar(16)",
"bigint",
"bigint unsigned",
"smallint",
"smallint unsigned",
"tinyint",
"tinyint unsigned",
"bool",
"json"
}; };
char * key_tags[] = { char* tb_actions[] = {
"tags(" "add column ", "modify column ", "drop column ", "rename column ", "add tag ",
"modify tag ", "drop tag ", "rename tag ", "set tag ",
}; };
char * key_select[] = { char* user_actions[] = {"pass ", "enable ", "sysinfo "};
"select "
}; char* tb_options[] = {"comment ", "watermark ", "max_delay ", "ttl ", "rollup(", "sma("};
char* db_options[] = {"keep ",
"replica ",
"precision ",
"strict ",
"buffer ",
"cachemodel ",
"cachesize ",
"comp ",
"duration ",
"wal_fsync_period",
"maxrows ",
"minrows ",
"pages ",
"pagesize ",
"retentions ",
"wal_level ",
"vgroups ",
"single_stable ",
"wal_retention_period ",
"wal_roll_period ",
"wal_retention_size ",
"wal_segment_size "};
char* alter_db_options[] = {"keep ", "cachemodel ", "cachesize ", "wal_fsync_period ", "wal_level "};
char* data_types[] = {"timestamp", "int",
"int unsigned", "varchar(16)",
"float", "double",
"binary(16)", "nchar(16)",
"bigint", "bigint unsigned",
"smallint", "smallint unsigned",
"tinyint", "tinyint unsigned",
"bool", "json"};
char* key_tags[] = {"tags("};
char* key_select[] = {"select "};
// //
// ------- gobal variant define --------- // ------- gobal variant define ---------
// //
int32_t firstMatchIndex = -1; // first match shellCommands index int32_t firstMatchIndex = -1; // first match shellCommands index
int32_t lastMatchIndex = -1; // last match shellCommands index int32_t lastMatchIndex = -1; // last match shellCommands index
int32_t curMatchIndex = -1; // current match shellCommands index int32_t curMatchIndex = -1; // current match shellCommands index
int32_t lastWordBytes = -1; // printShow last word length int32_t lastWordBytes = -1; // printShow last word length
bool waitAutoFill = false; bool waitAutoFill = false;
// //
// ----------- global var array define ----------- // ----------- global var array define -----------
// //
#define WT_VAR_DBNAME 0 #define WT_VAR_DBNAME 0
#define WT_VAR_STABLE 1 #define WT_VAR_STABLE 1
#define WT_VAR_TABLE 2 #define WT_VAR_TABLE 2
#define WT_VAR_DNODEID 3 #define WT_VAR_DNODEID 3
#define WT_VAR_USERNAME 4 #define WT_VAR_USERNAME 4
#define WT_VAR_TOPIC 5 #define WT_VAR_TOPIC 5
#define WT_VAR_STREAM 6 #define WT_VAR_STREAM 6
#define WT_VAR_ALLTABLE 7 #define WT_VAR_ALLTABLE 7
#define WT_VAR_FUNC 8 #define WT_VAR_FUNC 8
#define WT_VAR_KEYWORD 9 #define WT_VAR_KEYWORD 9
#define WT_VAR_TBACTION 10 #define WT_VAR_TBACTION 10
#define WT_VAR_DBOPTION 11 #define WT_VAR_DBOPTION 11
#define WT_VAR_ALTER_DBOPTION 12 #define WT_VAR_ALTER_DBOPTION 12
#define WT_VAR_DATATYPE 13 #define WT_VAR_DATATYPE 13
#define WT_VAR_KEYTAGS 14 #define WT_VAR_KEYTAGS 14
#define WT_VAR_ANYWORD 15 #define WT_VAR_ANYWORD 15
#define WT_VAR_TBOPTION 16 #define WT_VAR_TBOPTION 16
#define WT_VAR_USERACTION 17 #define WT_VAR_USERACTION 17
#define WT_VAR_KEYSELECT 18 #define WT_VAR_KEYSELECT 18
#define WT_VAR_CNT 19 #define WT_VAR_CNT 19
#define WT_FROM_DB_MAX 6 // max get content from db #define WT_FROM_DB_MAX 6 // max get content from db
#define WT_FROM_DB_CNT (WT_FROM_DB_MAX + 1) #define WT_FROM_DB_CNT (WT_FROM_DB_MAX + 1)
#define WT_TEXT 0xFF #define WT_TEXT 0xFF
char dbName[256] = ""; // save use database name; char dbName[256] = ""; // save use database name;
// tire array // tire array
STire* tires[WT_VAR_CNT]; STire* tires[WT_VAR_CNT];
TdThreadMutex tiresMutex; TdThreadMutex tiresMutex;
//save thread handle obtain var name from db server // save thread handle obtain var name from db server
TdThread* threads[WT_FROM_DB_CNT]; TdThread* threads[WT_FROM_DB_CNT];
// obtain var name with sql from server // obtain var name with sql from server
char varTypes[WT_VAR_CNT][64] = { char varTypes[WT_VAR_CNT][64] = {"<db_name>", "<stb_name>", "<tb_name>", "<dnode_id>", "<user_name>",
"<db_name>", "<topic_name>", "<stream_name>", "<all_table>", "<function>", "<keyword>",
"<stb_name>", "<tb_actions>", "<db_options>", "<alter_db_options>", "<data_types>", "<key_tags>",
"<tb_name>", "<anyword>", "<tb_options>", "<user_actions>", "<key_select>"};
"<dnode_id>",
"<user_name>",
"<topic_name>",
"<stream_name>",
"<all_table>",
"<function>",
"<keyword>",
"<tb_actions>",
"<db_options>",
"<alter_db_options>",
"<data_types>",
"<key_tags>",
"<anyword>",
"<tb_options>",
"<user_actions>",
"<key_select>"
};
char varSqls[WT_FROM_DB_CNT][64] = {
"show databases;",
"show stables;",
"show tables;",
"show dnodes;",
"show users;",
"show topics;",
"show streams;"
};
char varSqls[WT_FROM_DB_CNT][64] = {"show databases;", "show stables;", "show tables;", "show dnodes;",
"show users;", "show topics;", "show streams;"};
// var words current cursor, if user press any one key except tab, cursorVar can be reset to -1 // var words current cursor, if user press any one key except tab, cursorVar can be reset to -1
int cursorVar = -1; int cursorVar = -1;
bool varMode = false; // enter var names list mode bool varMode = false; // enter var names list mode
TAOS* varCon = NULL;
SShellCmd* varCmd = NULL;
SMatch* lastMatch = NULL; // save last match result
int cntDel = 0; // delete byte count after next press tab
TAOS* varCon = NULL;
SShellCmd* varCmd = NULL;
SMatch* lastMatch = NULL; // save last match result
int cntDel = 0; // delete byte count after next press tab
// show auto tab introduction // show auto tab introduction
void printfIntroduction() { void printfIntroduction() {
printf(" **************************** How To Use TAB Key ********************************\n"); printf(" **************************** How To Use TAB Key ********************************\n");
printf(" * TDengine Command Line supports pressing TAB key to complete word, *\n"); printf(" * TDengine Command Line supports pressing TAB key to complete word, *\n");
printf(" * including database name, table name, function name and keywords. *\n"); printf(" * including database name, table name, function name and keywords. *\n");
printf(" * Press TAB key anywhere, you'll get surprise. *\n"); printf(" * Press TAB key anywhere, you'll get surprise. *\n");
printf(" * KEYBOARD SHORTCUT: *\n"); printf(" * KEYBOARD SHORTCUT: *\n");
printf(" * [ TAB ] ...... Complete the word or show help if no input *\n"); printf(" * [ TAB ] ...... Complete the word or show help if no input *\n");
printf(" * [ Ctrl + A ] ...... move cursor to [A]head of line *\n"); printf(" * [ Ctrl + A ] ...... move cursor to [A]head of line *\n");
printf(" * [ Ctrl + E ] ...... move cursor to [E]nd of line *\n"); printf(" * [ Ctrl + E ] ...... move cursor to [E]nd of line *\n");
printf(" * [ Ctrl + W ] ...... move cursor to line of middle *\n"); printf(" * [ Ctrl + W ] ...... move cursor to line of middle *\n");
printf(" * [ Ctrl + L ] ...... clean screen *\n"); printf(" * [ Ctrl + L ] ...... clean screen *\n");
printf(" * [ Ctrl + K ] ...... clean after cursor *\n"); printf(" * [ Ctrl + K ] ...... clean after cursor *\n");
printf(" * [ Ctrl + U ] ...... clean before cursor *\n"); printf(" * [ Ctrl + U ] ...... clean before cursor *\n");
printf(" * *\n"); printf(" * *\n");
printf(" **********************************************************************************\n\n"); printf(" **********************************************************************************\n\n");
} }
void showHelp() { void showHelp() {
printf("\nThe following are supported commands for TDengine Command Line:"); printf("\nThe following are supported commands for TDengine Command Line:");
printf("\n\ printf(
"\n\
----- A ----- \n\ ----- A ----- \n\
alter database <db_name> <db_options> \n\ alter database <db_name> <db_options> \n\
alter dnode <dnode_id> balance \n\ alter dnode <dnode_id> balance \n\
...@@ -572,9 +457,10 @@ void showHelp() { ...@@ -572,9 +457,10 @@ void showHelp() {
use <db_name>;"); use <db_name>;");
printf("\n\n"); printf("\n\n");
//define in getDuration() function // define in getDuration() function
printf("\ printf(
"\
Timestamp expression Format:\n\ Timestamp expression Format:\n\
b - nanosecond \n\ b - nanosecond \n\
u - microsecond \n\ u - microsecond \n\
...@@ -597,11 +483,10 @@ void showHelp() { ...@@ -597,11 +483,10 @@ void showHelp() {
#define SHELL_COMMAND_COUNT() (sizeof(shellCommands) / sizeof(SWords)) #define SHELL_COMMAND_COUNT() (sizeof(shellCommands) / sizeof(SWords))
// get at // get at
SWord * atWord(SWords * command, int32_t index) { SWord* atWord(SWords* command, int32_t index) {
SWord * word = command->head; SWord* word = command->head;
for (int32_t i = 0; i < index; i++) { for (int32_t i = 0; i < index; i++) {
if (word == NULL) if (word == NULL) return NULL;
return NULL;
word = word->next; word = word->next;
} }
...@@ -612,18 +497,17 @@ SWord * atWord(SWords * command, int32_t index) { ...@@ -612,18 +497,17 @@ SWord * atWord(SWords * command, int32_t index) {
int wordType(const char* p, int32_t len) { int wordType(const char* p, int32_t len) {
for (int i = 0; i < WT_VAR_CNT; i++) { for (int i = 0; i < WT_VAR_CNT; i++) {
if (strncmp(p, varTypes[i], len) == 0) if (strncmp(p, varTypes[i], len) == 0) return i;
return i;
} }
return WT_TEXT; return WT_TEXT;
} }
// add word // add word
SWord * addWord(const char* p, int32_t len, bool pattern) { SWord* addWord(const char* p, int32_t len, bool pattern) {
SWord* word = (SWord *) taosMemoryMalloc(sizeof(SWord)); SWord* word = (SWord*)taosMemoryMalloc(sizeof(SWord));
memset(word, 0, sizeof(SWord)); memset(word, 0, sizeof(SWord));
word->word = (char* )p; word->word = (char*)p;
word->len = len; word->len = len;
// check format // check format
if (pattern) { if (pattern) {
...@@ -636,10 +520,10 @@ SWord * addWord(const char* p, int32_t len, bool pattern) { ...@@ -636,10 +520,10 @@ SWord * addWord(const char* p, int32_t len, bool pattern) {
} }
// parse one command // parse one command
void parseCommand(SWords * command, bool pattern) { void parseCommand(SWords* command, bool pattern) {
char * p = command->source; char* p = command->source;
int32_t start = 0; int32_t start = 0;
int32_t size = command->source_len > 0 ? command->source_len : strlen(p); int32_t size = command->source_len > 0 ? command->source_len : strlen(p);
bool lastBlank = false; bool lastBlank = false;
for (int i = 0; i <= size; i++) { for (int i = 0; i <= size; i++) {
...@@ -647,28 +531,28 @@ void parseCommand(SWords * command, bool pattern) { ...@@ -647,28 +531,28 @@ void parseCommand(SWords * command, bool pattern) {
// check continue blank like ' ' // check continue blank like ' '
if (p[i] == ' ') { if (p[i] == ' ') {
if (lastBlank) { if (lastBlank) {
start ++; start++;
continue; continue;
} }
if (i == 0) { // first blank if (i == 0) { // first blank
lastBlank = true; lastBlank = true;
start ++; start++;
continue; continue;
} }
lastBlank = true; lastBlank = true;
} }
// found split or string end , append word // found split or string end , append word
if (command->head == NULL) { if (command->head == NULL) {
command->head = addWord(p + start, i - start, pattern); command->head = addWord(p + start, i - start, pattern);
command->count = 1; command->count = 1;
} else { } else {
SWord * word = command->head; SWord* word = command->head;
while (word->next) { while (word->next) {
word = word->next; word = word->next;
} }
word->next = addWord(p + start, i - start, pattern); word->next = addWord(p + start, i - start, pattern);
command->count ++; command->count++;
} }
start = i + 1; start = i + 1;
} else { } else {
...@@ -678,25 +562,23 @@ void parseCommand(SWords * command, bool pattern) { ...@@ -678,25 +562,23 @@ void parseCommand(SWords * command, bool pattern) {
} }
// free SShellCmd // free SShellCmd
void freeCommand(SWords * command) { void freeCommand(SWords* command) {
SWord * word = command->head; SWord* word = command->head;
if (word == NULL) { if (word == NULL) {
return ; return;
} }
// loop // loop
while (word->next) { while (word->next) {
SWord * tmp = word; SWord* tmp = word;
word = word->next; word = word->next;
// if malloc need free // if malloc need free
if(tmp->free && tmp->word) if (tmp->free && tmp->word) taosMemoryFree(tmp->word);
taosMemoryFree(tmp->word);
taosMemoryFree(tmp); taosMemoryFree(tmp);
} }
// if malloc need free // if malloc need free
if(word->free && word->word) if (word->free && word->word) taosMemoryFree(word->word);
taosMemoryFree(word->word);
taosMemoryFree(word); taosMemoryFree(word);
} }
...@@ -715,12 +597,11 @@ void GenerateVarType(int type, char** p, int count) { ...@@ -715,12 +597,11 @@ void GenerateVarType(int type, char** p, int count) {
// -------------------- shell auto ---------------- // -------------------- shell auto ----------------
// //
// init shell auto funciton , shell start call once
// init shell auto funciton , shell start call once
bool shellAutoInit() { bool shellAutoInit() {
// command // command
int32_t count = SHELL_COMMAND_COUNT(); int32_t count = SHELL_COMMAND_COUNT();
for (int32_t i = 0; i < count; i ++) { for (int32_t i = 0; i < count; i++) {
parseCommand(shellCommands + i, true); parseCommand(shellCommands + i, true);
} }
...@@ -732,30 +613,28 @@ bool shellAutoInit() { ...@@ -732,30 +613,28 @@ bool shellAutoInit() {
memset(threads, 0, sizeof(TdThread*) * WT_FROM_DB_CNT); memset(threads, 0, sizeof(TdThread*) * WT_FROM_DB_CNT);
// generate varType // generate varType
GenerateVarType(WT_VAR_FUNC, functions, sizeof(functions) /sizeof(char *)); GenerateVarType(WT_VAR_FUNC, functions, sizeof(functions) / sizeof(char*));
GenerateVarType(WT_VAR_KEYWORD, keywords, sizeof(keywords) /sizeof(char *)); GenerateVarType(WT_VAR_KEYWORD, keywords, sizeof(keywords) / sizeof(char*));
GenerateVarType(WT_VAR_DBOPTION, db_options, sizeof(db_options) /sizeof(char *)); GenerateVarType(WT_VAR_DBOPTION, db_options, sizeof(db_options) / sizeof(char*));
GenerateVarType(WT_VAR_ALTER_DBOPTION, alter_db_options, sizeof(alter_db_options) /sizeof(char *)); GenerateVarType(WT_VAR_ALTER_DBOPTION, alter_db_options, sizeof(alter_db_options) / sizeof(char*));
GenerateVarType(WT_VAR_TBACTION, tb_actions, sizeof(tb_actions) /sizeof(char *)); GenerateVarType(WT_VAR_TBACTION, tb_actions, sizeof(tb_actions) / sizeof(char*));
GenerateVarType(WT_VAR_DATATYPE, data_types, sizeof(data_types) /sizeof(char *)); GenerateVarType(WT_VAR_DATATYPE, data_types, sizeof(data_types) / sizeof(char*));
GenerateVarType(WT_VAR_KEYTAGS, key_tags, sizeof(key_tags) /sizeof(char *)); GenerateVarType(WT_VAR_KEYTAGS, key_tags, sizeof(key_tags) / sizeof(char*));
GenerateVarType(WT_VAR_TBOPTION, tb_options, sizeof(tb_options) /sizeof(char *)); GenerateVarType(WT_VAR_TBOPTION, tb_options, sizeof(tb_options) / sizeof(char*));
GenerateVarType(WT_VAR_USERACTION, user_actions, sizeof(user_actions) /sizeof(char *)); GenerateVarType(WT_VAR_USERACTION, user_actions, sizeof(user_actions) / sizeof(char*));
GenerateVarType(WT_VAR_KEYSELECT,key_select, sizeof(key_select) /sizeof(char *)); GenerateVarType(WT_VAR_KEYSELECT, key_select, sizeof(key_select) / sizeof(char*));
return true; return true;
} }
// set conn // set conn
void shellSetConn(TAOS* conn) { void shellSetConn(TAOS* conn) { varCon = conn; }
varCon = conn;
}
// exit shell auto funciton, shell exit call once // exit shell auto funciton, shell exit call once
void shellAutoExit() { void shellAutoExit() {
// free command // free command
int32_t count = SHELL_COMMAND_COUNT(); int32_t count = SHELL_COMMAND_COUNT();
for (int32_t i = 0; i < count; i ++) { for (int32_t i = 0; i < count; i++) {
freeCommand(shellCommands + i); freeCommand(shellCommands + i);
} }
...@@ -765,7 +644,7 @@ void shellAutoExit() { ...@@ -765,7 +644,7 @@ void shellAutoExit() {
if (tires[i]) { if (tires[i]) {
freeTire(tires[i]); freeTire(tires[i]);
tires[i] = NULL; tires[i] = NULL;
} }
} }
taosThreadMutexUnlock(&tiresMutex); taosThreadMutexUnlock(&tiresMutex);
// destory // destory
...@@ -790,8 +669,7 @@ void shellAutoExit() { ...@@ -790,8 +669,7 @@ void shellAutoExit() {
// ------------------- auto ptr for tires -------------------------- // ------------------- auto ptr for tires --------------------------
// //
bool setNewAuotPtr(int type, STire* pNew) { bool setNewAuotPtr(int type, STire* pNew) {
if (pNew == NULL) if (pNew == NULL) return false;
return false;
taosThreadMutexLock(&tiresMutex); taosThreadMutexLock(&tiresMutex);
STire* pOld = tires[type]; STire* pOld = tires[type];
...@@ -826,63 +704,61 @@ STire* getAutoPtr(int type) { ...@@ -826,63 +704,61 @@ STire* getAutoPtr(int type) {
// put back tire to tires[type], if tire not equal tires[type].p, need free tire // put back tire to tires[type], if tire not equal tires[type].p, need free tire
void putBackAutoPtr(int type, STire* tire) { void putBackAutoPtr(int type, STire* tire) {
if (tire == NULL) { if (tire == NULL) {
return ; return;
} }
taosThreadMutexLock(&tiresMutex); taosThreadMutexLock(&tiresMutex);
if (tires[type] != tire) { if (tires[type] != tire) {
//update by out, can't put back , so free // update by out, can't put back , so free
if (--tire->ref == 1) { if (--tire->ref == 1) {
// support multi thread getAuotPtr // support multi thread getAuotPtr
freeTire(tire); freeTire(tire);
} }
} else { } else {
tires[type]->ref--; tires[type]->ref--;
assert(tires[type]->ref > 0); assert(tires[type]->ref > 0);
} }
taosThreadMutexUnlock(&tiresMutex); taosThreadMutexUnlock(&tiresMutex);
return ; return;
} }
// //
// ------------------- var Word -------------------------- // ------------------- var Word --------------------------
// //
#define MAX_CACHED_CNT 100000 // max cached rows 10w #define MAX_CACHED_CNT 100000 // max cached rows 10w
// write sql result to var name, return write rows cnt // write sql result to var name, return write rows cnt
int writeVarNames(int type, TAOS_RES* tres) { int writeVarNames(int type, TAOS_RES* tres) {
// fetch row // fetch row
TAOS_ROW row = taos_fetch_row(tres); TAOS_ROW row = taos_fetch_row(tres);
if (row == NULL) { if (row == NULL) {
return 0; return 0;
} }
TAOS_FIELD *fields = taos_fetch_fields(tres); TAOS_FIELD* fields = taos_fetch_fields(tres);
// create new tires // create new tires
char tireType = type == WT_VAR_TABLE ? TIRE_TREE : TIRE_LIST; char tireType = type == WT_VAR_TABLE ? TIRE_TREE : TIRE_LIST;
STire* tire = createTire(tireType); STire* tire = createTire(tireType);
// enum rows // enum rows
char name[1024]; char name[1024];
int numOfRows = 0; int numOfRows = 0;
do { do {
int32_t* lengths = taos_fetch_lengths(tres); int32_t* lengths = taos_fetch_lengths(tres);
int32_t bytes = lengths[0]; int32_t bytes = lengths[0];
if(fields[0].type == TSDB_DATA_TYPE_INT) { if (fields[0].type == TSDB_DATA_TYPE_INT) {
sprintf(name,"%d", *(int16_t*)row[0]); sprintf(name, "%d", *(int16_t*)row[0]);
} else { } else {
memcpy(name, row[0], bytes); memcpy(name, row[0], bytes);
} }
name[bytes] = 0; //set string end name[bytes] = 0; // set string end
// insert to tire // insert to tire
insertWord(tire, name); insertWord(tire, name);
if (++numOfRows > MAX_CACHED_CNT ) { if (++numOfRows > MAX_CACHED_CNT) {
break; break;
} }
...@@ -895,12 +771,12 @@ int writeVarNames(int type, TAOS_RES* tres) { ...@@ -895,12 +771,12 @@ int writeVarNames(int type, TAOS_RES* tres) {
return numOfRows; return numOfRows;
} }
bool firstMatchCommand(TAOS * con, SShellCmd * cmd); bool firstMatchCommand(TAOS* con, SShellCmd* cmd);
// //
// thread obtain var thread from db server // thread obtain var thread from db server
// //
void* varObtainThread(void* param) { void* varObtainThread(void* param) {
int type = *(int* )param; int type = *(int*)param;
taosMemoryFree(param); taosMemoryFree(param);
if (varCon == NULL || type > WT_FROM_DB_MAX) { if (varCon == NULL || type > WT_FROM_DB_MAX) {
...@@ -919,7 +795,7 @@ void* varObtainThread(void* param) { ...@@ -919,7 +795,7 @@ void* varObtainThread(void* param) {
// free sql // free sql
taos_free_result(pSql); taos_free_result(pSql);
// check need call auto tab // check need call auto tab
if (cnt > 0 && waitAutoFill) { if (cnt > 0 && waitAutoFill) {
// press tab key by program // press tab key by program
firstMatchCommand(varCon, varCmd); firstMatchCommand(varCon, varCmd);
...@@ -949,11 +825,10 @@ char* matchNextPrefix(STire* tire, char* pre) { ...@@ -949,11 +825,10 @@ char* matchNextPrefix(STire* tire, char* pre) {
// NOT EMPTY // NOT EMPTY
match = matchPrefix(tire, pre, NULL); match = matchPrefix(tire, pre, NULL);
} }
// save to lastMatch // save to lastMatch
if (match) { if (match) {
if (lastMatch) if (lastMatch) freeMatch(lastMatch);
freeMatch(lastMatch);
lastMatch = match; lastMatch = match;
} }
} }
...@@ -967,11 +842,11 @@ char* matchNextPrefix(STire* tire, char* pre) { ...@@ -967,11 +842,11 @@ char* matchNextPrefix(STire* tire, char* pre) {
if (cursorVar == -1) { if (cursorVar == -1) {
// first // first
cursorVar = 0; cursorVar = 0;
return strdup(match->head->word); return strdup(match->head->word);
} }
// according to cursorVar , calculate next one // according to cursorVar , calculate next one
int i = 0; int i = 0;
SMatchNode* item = match->head; SMatchNode* item = match->head;
while (item) { while (item) {
if (i == cursorVar + 1) { if (i == cursorVar + 1) {
...@@ -1008,12 +883,11 @@ char* tireSearchWord(int type, char* pre) { ...@@ -1008,12 +883,11 @@ char* tireSearchWord(int type, char* pre) {
return NULL; return NULL;
} }
if(type > WT_FROM_DB_MAX) { if (type > WT_FROM_DB_MAX) {
// NOT FROM DB , tires[type] alwary not null // NOT FROM DB , tires[type] alwary not null
STire* tire = tires[type]; STire* tire = tires[type];
if (tire == NULL) if (tire == NULL) return NULL;
return NULL; return matchNextPrefix(tire, pre);
return matchNextPrefix(tire, pre);
} }
// TYPE CONTEXT GET FROM DB // TYPE CONTEXT GET FROM DB
...@@ -1025,7 +899,7 @@ char* tireSearchWord(int type, char* pre) { ...@@ -1025,7 +899,7 @@ char* tireSearchWord(int type, char* pre) {
// need async obtain var names from db sever // need async obtain var names from db sever
if (threads[type] != NULL) { if (threads[type] != NULL) {
if (taosThreadRunning(threads[type])) { if (taosThreadRunning(threads[type])) {
// thread running , need not obtain again, return // thread running , need not obtain again, return
taosThreadMutexUnlock(&tiresMutex); taosThreadMutexUnlock(&tiresMutex);
return NULL; return NULL;
} }
...@@ -1033,10 +907,10 @@ char* tireSearchWord(int type, char* pre) { ...@@ -1033,10 +907,10 @@ char* tireSearchWord(int type, char* pre) {
taosDestroyThread(threads[type]); taosDestroyThread(threads[type]);
threads[type] = NULL; threads[type] = NULL;
} }
// create new // create new
void * param = taosMemoryMalloc(sizeof(int)); void* param = taosMemoryMalloc(sizeof(int));
*((int* )param) = type; *((int*)param) = type;
threads[type] = taosCreateThread(varObtainThread, param); threads[type] = taosCreateThread(varObtainThread, param);
taosThreadMutexUnlock(&tiresMutex); taosThreadMutexUnlock(&tiresMutex);
return NULL; return NULL;
...@@ -1056,9 +930,9 @@ char* tireSearchWord(int type, char* pre) { ...@@ -1056,9 +930,9 @@ char* tireSearchWord(int type, char* pre) {
return str; return str;
} }
// match var word, word1 is pattern , word2 is input from shell // match var word, word1 is pattern , word2 is input from shell
bool matchVarWord(SWord* word1, SWord* word2) { bool matchVarWord(SWord* word1, SWord* word2) {
// search input word from tire tree // search input word from tire tree
char pre[512]; char pre[512];
memcpy(pre, word2->word, word2->len); memcpy(pre, word2->word, word2->len);
pre[word2->len] = 0; pre[word2->len] = 0;
...@@ -1069,8 +943,7 @@ bool matchVarWord(SWord* word1, SWord* word2) { ...@@ -1069,8 +943,7 @@ bool matchVarWord(SWord* word1, SWord* word2) {
str = tireSearchWord(WT_VAR_STABLE, pre); str = tireSearchWord(WT_VAR_STABLE, pre);
if (str == NULL) { if (str == NULL) {
str = tireSearchWord(WT_VAR_TABLE, pre); str = tireSearchWord(WT_VAR_TABLE, pre);
if(str == NULL) if (str == NULL) return false;
return false;
} }
} else { } else {
// OTHER // OTHER
...@@ -1082,15 +955,15 @@ bool matchVarWord(SWord* word1, SWord* word2) { ...@@ -1082,15 +955,15 @@ bool matchVarWord(SWord* word1, SWord* word2) {
} }
// free previous malloc // free previous malloc
if(word1->free && word1->word) { if (word1->free && word1->word) {
taosMemoryFree(word1->word); taosMemoryFree(word1->word);
} }
// save // save
word1->word = str; word1->word = str;
word1->len = strlen(str); word1->len = strlen(str);
word1->free = true; // need free word1->free = true; // need free
return true; return true;
} }
...@@ -1098,11 +971,10 @@ bool matchVarWord(SWord* word1, SWord* word2) { ...@@ -1098,11 +971,10 @@ bool matchVarWord(SWord* word1, SWord* word2) {
// ------------------- match words -------------------------- // ------------------- match words --------------------------
// //
// compare command cmd1 come from shellCommands , cmd2 come from user input // compare command cmd1 come from shellCommands , cmd2 come from user input
int32_t compareCommand(SWords * cmd1, SWords * cmd2) { int32_t compareCommand(SWords* cmd1, SWords* cmd2) {
SWord * word1 = cmd1->head; SWord* word1 = cmd1->head;
SWord * word2 = cmd2->head; SWord* word2 = cmd2->head;
if (word1 == NULL || word2 == NULL) { if (word1 == NULL || word2 == NULL) {
return -1; return -1;
...@@ -1112,8 +984,7 @@ int32_t compareCommand(SWords * cmd1, SWords * cmd2) { ...@@ -1112,8 +984,7 @@ int32_t compareCommand(SWords * cmd1, SWords * cmd2) {
if (word1->type == WT_TEXT) { if (word1->type == WT_TEXT) {
// WT_TEXT match // WT_TEXT match
if (word1->len == word2->len) { if (word1->len == word2->len) {
if (strncasecmp(word1->word, word2->word, word1->len) != 0) if (strncasecmp(word1->word, word2->word, word1->len) != 0) return -1;
return -1;
} else if (word1->len < word2->len) { } else if (word1->len < word2->len) {
return -1; return -1;
} else { } else {
...@@ -1128,7 +999,7 @@ int32_t compareCommand(SWords * cmd1, SWords * cmd2) { ...@@ -1128,7 +999,7 @@ int32_t compareCommand(SWords * cmd1, SWords * cmd2) {
} }
} else { } else {
// WT_VAR auto match any one word // WT_VAR auto match any one word
if (word2->next == NULL) { // input words last one if (word2->next == NULL) { // input words last one
if (matchVarWord(word1, word2)) { if (matchVarWord(word1, word2)) {
cmd1->matchIndex = i; cmd1->matchIndex = i;
cmd1->matchLen = word2->len; cmd1->matchLen = word2->len;
...@@ -1151,10 +1022,10 @@ int32_t compareCommand(SWords * cmd1, SWords * cmd2) { ...@@ -1151,10 +1022,10 @@ int32_t compareCommand(SWords * cmd1, SWords * cmd2) {
} }
// match command // match command
SWords * matchCommand(SWords * input, bool continueSearch) { SWords* matchCommand(SWords* input, bool continueSearch) {
int32_t count = SHELL_COMMAND_COUNT(); int32_t count = SHELL_COMMAND_COUNT();
for (int32_t i = 0; i < count; i ++) { for (int32_t i = 0; i < count; i++) {
SWords * shellCommand = shellCommands + i; SWords* shellCommand = shellCommands + i;
if (continueSearch && lastMatchIndex != -1 && i <= lastMatchIndex) { if (continueSearch && lastMatchIndex != -1 && i <= lastMatchIndex) {
// new match must greate than lastMatchIndex // new match must greate than lastMatchIndex
if (varMode && i == lastMatchIndex) { if (varMode && i == lastMatchIndex) {
...@@ -1165,15 +1036,14 @@ SWords * matchCommand(SWords * input, bool continueSearch) { ...@@ -1165,15 +1036,14 @@ SWords * matchCommand(SWords * input, bool continueSearch) {
} }
// command is large // command is large
if (input->count > shellCommand->count ) { if (input->count > shellCommand->count) {
continue; continue;
} }
// compare // compare
int32_t index = compareCommand(shellCommand, input); int32_t index = compareCommand(shellCommand, input);
if (index != -1) { if (index != -1) {
if (firstMatchIndex == -1) if (firstMatchIndex == -1) firstMatchIndex = i;
firstMatchIndex = i;
curMatchIndex = i; curMatchIndex = i;
return &shellCommands[i]; return &shellCommands[i];
} }
...@@ -1188,7 +1058,7 @@ SWords * matchCommand(SWords * input, bool continueSearch) { ...@@ -1188,7 +1058,7 @@ SWords * matchCommand(SWords * input, bool continueSearch) {
// //
// delete char count // delete char count
void deleteCount(SShellCmd * cmd, int count) { void deleteCount(SShellCmd* cmd, int count) {
int size = 0; int size = 0;
int width = 0; int width = 0;
int prompt_size = 6; int prompt_size = 6;
...@@ -1207,55 +1077,53 @@ void deleteCount(SShellCmd * cmd, int count) { ...@@ -1207,55 +1077,53 @@ void deleteCount(SShellCmd * cmd, int count) {
} }
// show screen // show screen
void printScreen(TAOS * con, SShellCmd * cmd, SWords * match) { void printScreen(TAOS* con, SShellCmd* cmd, SWords* match) {
// modify SShellCmd // modify SShellCmd
if (firstMatchIndex == -1 || curMatchIndex == -1) { if (firstMatchIndex == -1 || curMatchIndex == -1) {
// no match // no match
return ; return;
} }
// first tab press // first tab press
const char * str = NULL; const char* str = NULL;
int strLen = 0; int strLen = 0;
if (firstMatchIndex == curMatchIndex && lastWordBytes == -1) { if (firstMatchIndex == curMatchIndex && lastWordBytes == -1) {
// first press tab // first press tab
SWord * word = MATCH_WORD(match); SWord* word = MATCH_WORD(match);
str = word->word + match->matchLen; str = word->word + match->matchLen;
strLen = word->len - match->matchLen; strLen = word->len - match->matchLen;
lastMatchIndex = firstMatchIndex; lastMatchIndex = firstMatchIndex;
lastWordBytes = word->len; lastWordBytes = word->len;
} else { } else {
if (lastWordBytes == -1) if (lastWordBytes == -1) return;
return ;
deleteCount(cmd, lastWordBytes); deleteCount(cmd, lastWordBytes);
SWord * word = MATCH_WORD(match); SWord* word = MATCH_WORD(match);
str = word->word; str = word->word;
strLen = word->len; strLen = word->len;
// set current to last // set current to last
lastMatchIndex = curMatchIndex; lastMatchIndex = curMatchIndex;
lastWordBytes = word->len; lastWordBytes = word->len;
} }
// insert new // insert new
shellInsertChar(cmd, (char *)str, strLen); shellInsertChar(cmd, (char*)str, strLen);
} }
// main key press tab , matched return true else false // main key press tab , matched return true else false
bool firstMatchCommand(TAOS * con, SShellCmd * cmd) { bool firstMatchCommand(TAOS* con, SShellCmd* cmd) {
// parse command // parse command
SWords* input = (SWords *)taosMemoryMalloc(sizeof(SWords)); SWords* input = (SWords*)taosMemoryMalloc(sizeof(SWords));
memset(input, 0, sizeof(SWords)); memset(input, 0, sizeof(SWords));
input->source = cmd->command; input->source = cmd->command;
input->source_len = cmd->commandSize; input->source_len = cmd->commandSize;
parseCommand(input, false); parseCommand(input, false);
// if have many , default match first, if press tab again , switch to next // if have many , default match first, if press tab again , switch to next
curMatchIndex = -1; curMatchIndex = -1;
lastMatchIndex = -1; lastMatchIndex = -1;
SWords * match = matchCommand(input, true); SWords* match = matchCommand(input, true);
if (match == NULL) { if (match == NULL) {
// not match , nothing to do // not match , nothing to do
freeCommand(input); freeCommand(input);
...@@ -1271,21 +1139,21 @@ bool firstMatchCommand(TAOS * con, SShellCmd * cmd) { ...@@ -1271,21 +1139,21 @@ bool firstMatchCommand(TAOS * con, SShellCmd * cmd) {
} }
// create input source // create input source
void createInputFromFirst(SWords* input, SWords * firstMatch) { void createInputFromFirst(SWords* input, SWords* firstMatch) {
// //
// if next pressTabKey , input context come from firstMatch, set matched length with source_len // if next pressTabKey , input context come from firstMatch, set matched length with source_len
// //
input->source = (char*)taosMemoryMalloc(1024); input->source = (char*)taosMemoryMalloc(1024);
memset((void* )input->source, 0, 1024); memset((void*)input->source, 0, 1024);
SWord * word = firstMatch->head; SWord* word = firstMatch->head;
// source_len = full match word->len + half match with firstMatch->matchLen // source_len = full match word->len + half match with firstMatch->matchLen
for (int i = 0; i < firstMatch->matchIndex && word; i++) { for (int i = 0; i < firstMatch->matchIndex && word; i++) {
// combine source from each word // combine source from each word
strncpy(input->source + input->source_len, word->word, word->len); strncpy(input->source + input->source_len, word->word, word->len);
strcat(input->source, " "); // append blank splite strcat(input->source, " "); // append blank splite
input->source_len += word->len + 1; // 1 is blank length input->source_len += word->len + 1; // 1 is blank length
// move next // move next
word = word->next; word = word->next;
} }
...@@ -1297,11 +1165,11 @@ void createInputFromFirst(SWords* input, SWords * firstMatch) { ...@@ -1297,11 +1165,11 @@ void createInputFromFirst(SWords* input, SWords * firstMatch) {
} }
// user press Tabkey again is named next , matched return true else false // user press Tabkey again is named next , matched return true else false
bool nextMatchCommand(TAOS * con, SShellCmd * cmd, SWords * firstMatch) { bool nextMatchCommand(TAOS* con, SShellCmd* cmd, SWords* firstMatch) {
if (firstMatch == NULL || firstMatch->head == NULL) { if (firstMatch == NULL || firstMatch->head == NULL) {
return false; return false;
} }
SWords* input = (SWords *)taosMemoryMalloc(sizeof(SWords)); SWords* input = (SWords*)taosMemoryMalloc(sizeof(SWords));
memset(input, 0, sizeof(SWords)); memset(input, 0, sizeof(SWords));
// create input from firstMatch // create input from firstMatch
...@@ -1311,16 +1179,15 @@ bool nextMatchCommand(TAOS * con, SShellCmd * cmd, SWords * firstMatch) { ...@@ -1311,16 +1179,15 @@ bool nextMatchCommand(TAOS * con, SShellCmd * cmd, SWords * firstMatch) {
parseCommand(input, false); parseCommand(input, false);
// if have many , default match first, if press tab again , switch to next // if have many , default match first, if press tab again , switch to next
SWords * match = matchCommand(input, true); SWords* match = matchCommand(input, true);
if (match == NULL) { if (match == NULL) {
// if not match , reset all index // if not match , reset all index
firstMatchIndex = -1; firstMatchIndex = -1;
curMatchIndex = -1; curMatchIndex = -1;
match = matchCommand(input, false); match = matchCommand(input, false);
if (match == NULL) { if (match == NULL) {
freeCommand(input); freeCommand(input);
if (input->source) if (input->source) taosMemoryFree(input->source);
taosMemoryFree(input->source);
taosMemoryFree(input); taosMemoryFree(input);
return false; return false;
} }
...@@ -1341,41 +1208,40 @@ bool nextMatchCommand(TAOS * con, SShellCmd * cmd, SWords * firstMatch) { ...@@ -1341,41 +1208,40 @@ bool nextMatchCommand(TAOS * con, SShellCmd * cmd, SWords * firstMatch) {
} }
// fill with type // fill with type
bool fillWithType(TAOS * con, SShellCmd * cmd, char* pre, int type) { bool fillWithType(TAOS* con, SShellCmd* cmd, char* pre, int type) {
// get type // get type
STire* tire = tires[type]; STire* tire = tires[type];
char* str = matchNextPrefix(tire, pre); char* str = matchNextPrefix(tire, pre);
if (str == NULL) { if (str == NULL) {
return false; return false;
} }
// need insert part string // need insert part string
char * part = str + strlen(pre); char* part = str + strlen(pre);
// show // show
int count = strlen(part); int count = strlen(part);
shellInsertChar(cmd, part, count); shellInsertChar(cmd, part, count);
cntDel = count; // next press tab delete current append count cntDel = count; // next press tab delete current append count
taosMemoryFree(str); taosMemoryFree(str);
return true; return true;
} }
// fill with type // fill with type
bool fillTableName(TAOS * con, SShellCmd * cmd, char* pre) { bool fillTableName(TAOS* con, SShellCmd* cmd, char* pre) {
// search stable and table // search stable and table
char * str = tireSearchWord(WT_VAR_STABLE, pre); char* str = tireSearchWord(WT_VAR_STABLE, pre);
if (str == NULL) { if (str == NULL) {
str = tireSearchWord(WT_VAR_TABLE, pre); str = tireSearchWord(WT_VAR_TABLE, pre);
if(str == NULL) if (str == NULL) return false;
return false;
} }
// need insert part string // need insert part string
char * part = str + strlen(pre); char* part = str + strlen(pre);
// delete autofill count last append // delete autofill count last append
if(cntDel > 0) { if (cntDel > 0) {
deleteCount(cmd, cntDel); deleteCount(cmd, cntDel);
cntDel = 0; cntDel = 0;
} }
...@@ -1383,8 +1249,8 @@ bool fillTableName(TAOS * con, SShellCmd * cmd, char* pre) { ...@@ -1383,8 +1249,8 @@ bool fillTableName(TAOS * con, SShellCmd * cmd, char* pre) {
// show // show
int count = strlen(part); int count = strlen(part);
shellInsertChar(cmd, part, count); shellInsertChar(cmd, part, count);
cntDel = count; // next press tab delete current append count cntDel = count; // next press tab delete current append count
taosMemoryFree(str); taosMemoryFree(str);
return true; return true;
} }
...@@ -1396,20 +1262,20 @@ bool fillTableName(TAOS * con, SShellCmd * cmd, char* pre) { ...@@ -1396,20 +1262,20 @@ bool fillTableName(TAOS * con, SShellCmd * cmd, char* pre) {
// 2 select count(*),su -> select count(*), sum( // 2 select count(*),su -> select count(*), sum(
// 3 select count(*), su -> select count(*), sum( // 3 select count(*), su -> select count(*), sum(
// //
char * lastWord(char * p) { char* lastWord(char* p) {
// get near from end revert find ' ' and ',' // get near from end revert find ' ' and ','
char * p1 = strrchr(p, ' '); char* p1 = strrchr(p, ' ');
char * p2 = strrchr(p, ','); char* p2 = strrchr(p, ',');
if (p1 && p2) { if (p1 && p2) {
return p1 > p2 ? p1 : p2 + 1; return p1 > p2 ? p1 : p2 + 1;
} else if (p1) { } else if (p1) {
return p1 + 1; return p1 + 1;
} else if(p2) { } else if (p2) {
return p2 + 1; return p2 + 1;
} else { } else {
return p; return p;
} }
} }
bool fieldsInputEnd(char* sql) { bool fieldsInputEnd(char* sql) {
...@@ -1425,18 +1291,18 @@ bool fieldsInputEnd(char* sql) { ...@@ -1425,18 +1291,18 @@ bool fieldsInputEnd(char* sql) {
} }
// not in ',' // not in ','
char * p3 = strrchr(sql, ','); char* p3 = strrchr(sql, ',');
char * p = p3; char* p = p3;
// like select ts, age,' ' // like select ts, age,' '
if (p) { if (p) {
++p; ++p;
bool allBlank = true; // after last ',' all char is blank bool allBlank = true; // after last ',' all char is blank
int cnt = 0; // blank count , like ' ' as one blank int cnt = 0; // blank count , like ' ' as one blank
char * plast = NULL; // last blank position char* plast = NULL; // last blank position
while(*p) { while (*p) {
if (*p == ' ') { if (*p == ' ') {
plast = p; plast = p;
cnt ++; cnt++;
} else { } else {
allBlank = false; allBlank = false;
} }
...@@ -1444,7 +1310,7 @@ bool fieldsInputEnd(char* sql) { ...@@ -1444,7 +1310,7 @@ bool fieldsInputEnd(char* sql) {
} }
// any one word is not blank // any one word is not blank
if(allBlank) { if (allBlank) {
return false; return false;
} }
...@@ -1454,13 +1320,13 @@ bool fieldsInputEnd(char* sql) { ...@@ -1454,13 +1320,13 @@ bool fieldsInputEnd(char* sql) {
} }
// if last char not ' ', then not end field, like 'select count(*), su' can fill sum( // if last char not ' ', then not end field, like 'select count(*), su' can fill sum(
if(sql[strlen(sql)-1] != ' ' && cnt <= 1) { if (sql[strlen(sql) - 1] != ' ' && cnt <= 1) {
return false; return false;
} }
} }
char * p4 = strrchr(sql, ' '); char* p4 = strrchr(sql, ' ');
if(p4 == NULL) { if (p4 == NULL) {
// only one word // only one word
return false; return false;
} }
...@@ -1469,9 +1335,9 @@ bool fieldsInputEnd(char* sql) { ...@@ -1469,9 +1335,9 @@ bool fieldsInputEnd(char* sql) {
} }
// need insert from // need insert from
bool needInsertFrom(char * sql, int len) { bool needInsertFrom(char* sql, int len) {
// last is blank // last is blank
if(sql[len-1] != ' ') { if (sql[len - 1] != ' ') {
// insert from keyword // insert from keyword
return false; return false;
} }
...@@ -1486,45 +1352,45 @@ bool needInsertFrom(char * sql, int len) { ...@@ -1486,45 +1352,45 @@ bool needInsertFrom(char * sql, int len) {
} }
// p is string following select keyword // p is string following select keyword
bool appendAfterSelect(TAOS * con, SShellCmd * cmd, char* sql, int32_t len) { bool appendAfterSelect(TAOS* con, SShellCmd* cmd, char* sql, int32_t len) {
char* p = strndup(sql, len); char* p = strndup(sql, len);
// union all // union all
char * p1; char* p1;
do { do {
p1 = strstr(p, UNION_ALL); p1 = strstr(p, UNION_ALL);
if(p1) { if (p1) {
p = p1 + strlen(UNION_ALL); p = p1 + strlen(UNION_ALL);
} }
} while (p1); } while (p1);
char * from = strstr(p, " from "); char* from = strstr(p, " from ");
//last word , maybe empty string or some letters of a string // last word , maybe empty string or some letters of a string
char * last = lastWord(p); char* last = lastWord(p);
bool ret = false; bool ret = false;
if (from == NULL) { if (from == NULL) {
bool fieldEnd = fieldsInputEnd(p); bool fieldEnd = fieldsInputEnd(p);
// cheeck fields input end then insert from keyword // cheeck fields input end then insert from keyword
if (fieldEnd && p[len-1] == ' ') { if (fieldEnd && p[len - 1] == ' ') {
shellInsertChar(cmd, "from", 4); shellInsertChar(cmd, "from", 4);
taosMemoryFree(p); taosMemoryFree(p);
return true; return true;
} }
// fill funciton // fill funciton
if(fieldEnd) { if (fieldEnd) {
// fields is end , need match keyword // fields is end , need match keyword
ret = fillWithType(con, cmd, last, WT_VAR_KEYWORD); ret = fillWithType(con, cmd, last, WT_VAR_KEYWORD);
} else { } else {
ret = fillWithType(con, cmd, last, WT_VAR_FUNC); ret = fillWithType(con, cmd, last, WT_VAR_FUNC);
} }
taosMemoryFree(p); taosMemoryFree(p);
return ret; return ret;
} }
// have from // have from
char * blank = strstr(from + 6, " "); char* blank = strstr(from + 6, " ");
if (blank == NULL) { if (blank == NULL) {
// no table name, need fill // no table name, need fill
ret = fillTableName(con, cmd, last); ret = fillTableName(con, cmd, last);
...@@ -1538,13 +1404,12 @@ bool appendAfterSelect(TAOS * con, SShellCmd * cmd, char* sql, int32_t len) { ...@@ -1538,13 +1404,12 @@ bool appendAfterSelect(TAOS * con, SShellCmd * cmd, char* sql, int32_t len) {
int32_t searchAfterSelect(char* p, int32_t len) { int32_t searchAfterSelect(char* p, int32_t len) {
// select * from st; // select * from st;
if(strncasecmp(p, "select ", 7) == 0) { if (strncasecmp(p, "select ", 7) == 0) {
// check nest query // check nest query
char *p1 = p + 7; char* p1 = p + 7;
while(1) { while (1) {
char *p2 = strstr(p1, "select "); char* p2 = strstr(p1, "select ");
if(p2 == NULL) if (p2 == NULL) break;
break;
p1 = p2 + 7; p1 = p2 + 7;
} }
...@@ -1552,29 +1417,29 @@ int32_t searchAfterSelect(char* p, int32_t len) { ...@@ -1552,29 +1417,29 @@ int32_t searchAfterSelect(char* p, int32_t len) {
} }
// explain as select * from st; // explain as select * from st;
if(strncasecmp(p, "explain select ", 15) == 0) { if (strncasecmp(p, "explain select ", 15) == 0) {
return 15; return 15;
} }
char* as_pos_end = strstr(p, " as select "); char* as_pos_end = strstr(p, " as select ");
if (as_pos_end == NULL) if (as_pos_end == NULL) return -1;
return -1;
as_pos_end += 11; as_pos_end += 11;
// create stream <stream_name> as select // create stream <stream_name> as select
if(strncasecmp(p, "create stream ", 14) == 0) { if (strncasecmp(p, "create stream ", 14) == 0) {
return as_pos_end - p;; return as_pos_end - p;
;
} }
// create topic <topic_name> as select // create topic <topic_name> as select
if(strncasecmp(p, "create topic ", 13) == 0) { if (strncasecmp(p, "create topic ", 13) == 0) {
return as_pos_end - p; return as_pos_end - p;
} }
return -1; return -1;
} }
bool matchSelectQuery(TAOS * con, SShellCmd * cmd) { bool matchSelectQuery(TAOS* con, SShellCmd* cmd) {
// if continue press Tab , delete bytes by previous autofill // if continue press Tab , delete bytes by previous autofill
if (cntDel > 0) { if (cntDel > 0) {
deleteCount(cmd, cntDel); deleteCount(cmd, cntDel);
...@@ -1582,8 +1447,8 @@ bool matchSelectQuery(TAOS * con, SShellCmd * cmd) { ...@@ -1582,8 +1447,8 @@ bool matchSelectQuery(TAOS * con, SShellCmd * cmd) {
} }
// match select ... // match select ...
int len = cmd->commandSize; int len = cmd->commandSize;
char * p = cmd->command; char* p = cmd->command;
// remove prefix blank // remove prefix blank
while (p[0] == ' ' && len > 0) { while (p[0] == ' ' && len > 0) {
...@@ -1592,17 +1457,16 @@ bool matchSelectQuery(TAOS * con, SShellCmd * cmd) { ...@@ -1592,17 +1457,16 @@ bool matchSelectQuery(TAOS * con, SShellCmd * cmd) {
} }
// special range // special range
if(len < 7 || len > 512) { if (len < 7 || len > 512) {
return false; return false;
} }
// search // search
char* sql_cp = strndup(p, len); char* sql_cp = strndup(p, len);
int32_t n = searchAfterSelect(sql_cp, len); int32_t n = searchAfterSelect(sql_cp, len);
taosMemoryFree(sql_cp); taosMemoryFree(sql_cp);
if(n == -1 || n > len) if (n == -1 || n > len) return false;
return false; p += n;
p += n;
len -= n; len -= n;
// append // append
...@@ -1610,15 +1474,15 @@ bool matchSelectQuery(TAOS * con, SShellCmd * cmd) { ...@@ -1610,15 +1474,15 @@ bool matchSelectQuery(TAOS * con, SShellCmd * cmd) {
} }
// if is input create fields or tags area, return true // if is input create fields or tags area, return true
bool isCreateFieldsArea(char * p) { bool isCreateFieldsArea(char* p) {
char * left = strrchr(p, '('); char* left = strrchr(p, '(');
if (left == NULL) { if (left == NULL) {
// like 'create table st' // like 'create table st'
return false; return false;
} }
char * right = strrchr(p, ')'); char* right = strrchr(p, ')');
if(right == NULL) { if (right == NULL) {
// like 'create table st( ' // like 'create table st( '
return true; return true;
} }
...@@ -1631,7 +1495,7 @@ bool isCreateFieldsArea(char * p) { ...@@ -1631,7 +1495,7 @@ bool isCreateFieldsArea(char * p) {
return false; return false;
} }
bool matchCreateTable(TAOS * con, SShellCmd * cmd) { bool matchCreateTable(TAOS* con, SShellCmd* cmd) {
// if continue press Tab , delete bytes by previous autofill // if continue press Tab , delete bytes by previous autofill
if (cntDel > 0) { if (cntDel > 0) {
deleteCount(cmd, cntDel); deleteCount(cmd, cntDel);
...@@ -1639,8 +1503,8 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) { ...@@ -1639,8 +1503,8 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
} }
// match select ... // match select ...
int len = cmd->commandSize; int len = cmd->commandSize;
char * p = cmd->command; char* p = cmd->command;
// remove prefix blank // remove prefix blank
while (p[0] == ' ' && len > 0) { while (p[0] == ' ' && len > 0) {
...@@ -1649,12 +1513,12 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) { ...@@ -1649,12 +1513,12 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
} }
// special range // special range
if(len < 7 || len > 1024) { if (len < 7 || len > 1024) {
return false; return false;
} }
// select and from // select and from
if(strncasecmp(p, "create table ", 13) != 0) { if (strncasecmp(p, "create table ", 13) != 0) {
// not select query clause // not select query clause
return false; return false;
} }
...@@ -1662,8 +1526,8 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) { ...@@ -1662,8 +1526,8 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
len -= 13; len -= 13;
char* ps = strndup(p, len); char* ps = strndup(p, len);
bool ret = false; bool ret = false;
char * last = lastWord(ps); char* last = lastWord(ps);
// check in create fields or tags input area // check in create fields or tags input area
if (isCreateFieldsArea(ps)) { if (isCreateFieldsArea(ps)) {
...@@ -1673,9 +1537,9 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) { ...@@ -1673,9 +1537,9 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
// tags // tags
if (!ret) { if (!ret) {
// find only one ')' , can insert tags // find only one ')' , can insert tags
char * p1 = strchr(ps, ')'); char* p1 = strchr(ps, ')');
if (p1) { if (p1) {
if(strchr(p1 + 1, ')') == NULL && strstr(p1 + 1, "tags") == NULL) { if (strchr(p1 + 1, ')') == NULL && strstr(p1 + 1, "tags") == NULL) {
// can insert tags keyword // can insert tags keyword
ret = fillWithType(con, cmd, last, WT_VAR_KEYTAGS); ret = fillWithType(con, cmd, last, WT_VAR_KEYTAGS);
} }
...@@ -1685,9 +1549,9 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) { ...@@ -1685,9 +1549,9 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
// tb options // tb options
if (!ret) { if (!ret) {
// find like create talbe st (...) tags(..) <here is fill tb option area> // find like create talbe st (...) tags(..) <here is fill tb option area>
char * p1 = strchr(ps, ')'); // first ')' end char* p1 = strchr(ps, ')'); // first ')' end
if (p1) { if (p1) {
if(strchr(p1 + 1, ')')) { // second ')' end if (strchr(p1 + 1, ')')) { // second ')' end
// here is tb options area, can insert option // here is tb options area, can insert option
ret = fillWithType(con, cmd, last, WT_VAR_TBOPTION); ret = fillWithType(con, cmd, last, WT_VAR_TBOPTION);
} }
...@@ -1698,8 +1562,8 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) { ...@@ -1698,8 +1562,8 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
return ret; return ret;
} }
bool matchOther(TAOS * con, SShellCmd * cmd) { bool matchOther(TAOS* con, SShellCmd* cmd) {
int len = cmd->commandSize; int len = cmd->commandSize;
char* p = cmd->command; char* p = cmd->command;
// '\\' // '\\'
...@@ -1711,8 +1575,7 @@ bool matchOther(TAOS * con, SShellCmd * cmd) { ...@@ -1711,8 +1575,7 @@ bool matchOther(TAOS * con, SShellCmd * cmd) {
} }
// too small // too small
if(len < 8) if (len < 8) return false;
return false;
// like 'from ( ' // like 'from ( '
char* sql = strndup(p, len); char* sql = strndup(p, len);
...@@ -1721,36 +1584,35 @@ bool matchOther(TAOS * con, SShellCmd * cmd) { ...@@ -1721,36 +1584,35 @@ bool matchOther(TAOS * con, SShellCmd * cmd) {
if (strcmp(last, "from(") == 0) { if (strcmp(last, "from(") == 0) {
fillWithType(con, cmd, "", WT_VAR_KEYSELECT); fillWithType(con, cmd, "", WT_VAR_KEYSELECT);
taosMemoryFree(sql); taosMemoryFree(sql);
return true; return true;
} }
if (strncmp(last, "(", 1) == 0) { if (strncmp(last, "(", 1) == 0) {
last += 1; last += 1;
} }
char* from = strstr(sql, " from"); char* from = strstr(sql, " from");
// find last ' from' // find last ' from'
while (from) { while (from) {
char* p1 = strstr(from + 5, " from"); char* p1 = strstr(from + 5, " from");
if (p1 == NULL) if (p1 == NULL) break;
break;
from = p1; from = p1;
} }
if (from) { if (from) {
// find next is '(' // find next is '('
char * p2 = from + 5; char* p2 = from + 5;
bool found = false; // found 'from ... ( ...' ... is any count of blank bool found = false; // found 'from ... ( ...' ... is any count of blank
bool found1 = false; // found '(' bool found1 = false; // found '('
while (1) { while (1) {
if ( p2 == last || *p2 == '\0') { if (p2 == last || *p2 == '\0') {
// last word or string end // last word or string end
if (found1) { if (found1) {
found = true; found = true;
} }
break; break;
} else if(*p2 == '(') { } else if (*p2 == '(') {
found1 = true; found1 = true;
} else if(*p2 == ' ') { } else if (*p2 == ' ') {
// do nothing // do nothing
} else { } else {
// have any other char // have any other char
...@@ -1768,24 +1630,22 @@ bool matchOther(TAOS * con, SShellCmd * cmd) { ...@@ -1768,24 +1630,22 @@ bool matchOther(TAOS * con, SShellCmd * cmd) {
} }
} }
// INSERT // INSERT
taosMemoryFree(sql); taosMemoryFree(sql);
return false; return false;
} }
// main key press tab // main key press tab
void pressTabKey(SShellCmd * cmd) { void pressTabKey(SShellCmd* cmd) {
// check // check
if (cmd->commandSize == 0) { if (cmd->commandSize == 0) {
// empty // empty
showHelp(); showHelp();
shellShowOnScreen(cmd); shellShowOnScreen(cmd);
return ; return;
} }
// save connection to global // save connection to global
varCmd = cmd; varCmd = cmd;
...@@ -1793,45 +1653,41 @@ void pressTabKey(SShellCmd * cmd) { ...@@ -1793,45 +1653,41 @@ void pressTabKey(SShellCmd * cmd) {
// manual match like create table st( ... // manual match like create table st( ...
matched = matchCreateTable(varCon, cmd); matched = matchCreateTable(varCon, cmd);
if (matched) if (matched) return;
return ;
// shellCommands match // shellCommands match
if (firstMatchIndex == -1) { if (firstMatchIndex == -1) {
matched = firstMatchCommand(varCon, cmd); matched = firstMatchCommand(varCon, cmd);
} else { } else {
matched = nextMatchCommand(varCon, cmd, &shellCommands[firstMatchIndex]); matched = nextMatchCommand(varCon, cmd, &shellCommands[firstMatchIndex]);
} }
if (matched) if (matched) return;
return ;
// NOT MATCHED ANYONE // NOT MATCHED ANYONE
// match other like '\G' ... // match other like '\G' ...
matched = matchOther(varCon, cmd); matched = matchOther(varCon, cmd);
if (matched) if (matched) return;
return ;
// manual match like select * from ... // manual match like select * from ...
matched = matchSelectQuery(varCon, cmd); matched = matchSelectQuery(varCon, cmd);
if (matched) if (matched) return;
return ;
return ; return;
} }
// press othr key // press othr key
void pressOtherKey(char c) { void pressOtherKey(char c) {
// reset global variant // reset global variant
firstMatchIndex = -1; firstMatchIndex = -1;
lastMatchIndex = -1; lastMatchIndex = -1;
curMatchIndex = -1; curMatchIndex = -1;
lastWordBytes = -1; lastWordBytes = -1;
// var names // var names
cursorVar = -1; cursorVar = -1;
varMode = false; varMode = false;
waitAutoFill = false; waitAutoFill = false;
cntDel = 0; cntDel = 0;
if (lastMatch) { if (lastMatch) {
freeMatch(lastMatch); freeMatch(lastMatch);
...@@ -1840,18 +1696,18 @@ void pressOtherKey(char c) { ...@@ -1840,18 +1696,18 @@ void pressOtherKey(char c) {
} }
// put name into name, return name length // put name into name, return name length
int getWordName(char* p, char * name, int nameLen) { int getWordName(char* p, char* name, int nameLen) {
//remove prefix blank // remove prefix blank
while (*p == ' ') { while (*p == ' ') {
p++; p++;
} }
// get databases name; // get databases name;
int i = 0; int i = 0;
while(p[i] != 0 && i < nameLen - 1) { while (p[i] != 0 && i < nameLen - 1) {
name[i] = p[i]; name[i] = p[i];
i++; i++;
if(p[i] == ' ' || p[i] == ';'|| p[i] == '(') { if (p[i] == ' ' || p[i] == ';' || p[i] == '(') {
// name end // name end
break; break;
} }
...@@ -1862,22 +1718,22 @@ int getWordName(char* p, char * name, int nameLen) { ...@@ -1862,22 +1718,22 @@ int getWordName(char* p, char * name, int nameLen) {
} }
// deal use db, if have 'use' return true // deal use db, if have 'use' return true
bool dealUseDB(char * sql) { bool dealUseDB(char* sql) {
// check use keyword // check use keyword
if(strncasecmp(sql, "use ", 4) != 0) { if (strncasecmp(sql, "use ", 4) != 0) {
return false; return false;
} }
char db[256]; char db[256];
char *p = sql + 4; char* p = sql + 4;
if (getWordName(p, db, sizeof(db)) == 0) { if (getWordName(p, db, sizeof(db)) == 0) {
// no name , return // no name , return
return true; return true;
} }
// dbName is previous use open db name // dbName is previous use open db name
if (strcasecmp(db, dbName) == 0) { if (strcasecmp(db, dbName) == 0) {
// same , no need switch // same , no need switch
return true; return true;
} }
...@@ -1886,13 +1742,13 @@ bool dealUseDB(char * sql) { ...@@ -1886,13 +1742,13 @@ bool dealUseDB(char * sql) {
// STABLE set null // STABLE set null
STire* tire = tires[WT_VAR_STABLE]; STire* tire = tires[WT_VAR_STABLE];
tires[WT_VAR_STABLE] = NULL; tires[WT_VAR_STABLE] = NULL;
if(tire) { if (tire) {
freeTire(tire); freeTire(tire);
} }
// TABLE set null // TABLE set null
tire = tires[WT_VAR_TABLE]; tire = tires[WT_VAR_TABLE];
tires[WT_VAR_TABLE] = NULL; tires[WT_VAR_TABLE] = NULL;
if(tire) { if (tire) {
freeTire(tire); freeTire(tire);
} }
// save // save
...@@ -1903,16 +1759,16 @@ bool dealUseDB(char * sql) { ...@@ -1903,16 +1759,16 @@ bool dealUseDB(char * sql) {
} }
// deal create, if have 'create' return true // deal create, if have 'create' return true
bool dealCreateCommand(char * sql) { bool dealCreateCommand(char* sql) {
// check keyword // check keyword
if(strncasecmp(sql, "create ", 7) != 0) { if (strncasecmp(sql, "create ", 7) != 0) {
return false; return false;
} }
char name[1024]; char name[1024];
char *p = sql + 7; char* p = sql + 7;
if (getWordName(p, name, sizeof(name)) == 0) { if (getWordName(p, name, sizeof(name)) == 0) {
// no name , return // no name , return
return true; return true;
} }
...@@ -1921,7 +1777,7 @@ bool dealCreateCommand(char * sql) { ...@@ -1921,7 +1777,7 @@ bool dealCreateCommand(char * sql) {
if (strcasecmp(name, "database") == 0) { if (strcasecmp(name, "database") == 0) {
type = WT_VAR_DBNAME; type = WT_VAR_DBNAME;
} else if (strcasecmp(name, "table") == 0) { } else if (strcasecmp(name, "table") == 0) {
if(strstr(sql, " tags") != NULL && strstr(sql, " using ") == NULL) if (strstr(sql, " tags") != NULL && strstr(sql, " using ") == NULL)
type = WT_VAR_STABLE; type = WT_VAR_STABLE;
else else
type = WT_VAR_TABLE; type = WT_VAR_TABLE;
...@@ -1932,7 +1788,7 @@ bool dealCreateCommand(char * sql) { ...@@ -1932,7 +1788,7 @@ bool dealCreateCommand(char * sql) {
} else if (strcasecmp(name, "stream") == 0) { } else if (strcasecmp(name, "stream") == 0) {
type = WT_VAR_STREAM; type = WT_VAR_STREAM;
} else { } else {
// no match , return // no match , return
return true; return true;
} }
...@@ -1941,7 +1797,7 @@ bool dealCreateCommand(char * sql) { ...@@ -1941,7 +1797,7 @@ bool dealCreateCommand(char * sql) {
// get next word , that is table name // get next word , that is table name
if (getWordName(p, name, sizeof(name)) == 0) { if (getWordName(p, name, sizeof(name)) == 0) {
// no name , return // no name , return
return true; return true;
} }
...@@ -1949,7 +1805,7 @@ bool dealCreateCommand(char * sql) { ...@@ -1949,7 +1805,7 @@ bool dealCreateCommand(char * sql) {
taosThreadMutexLock(&tiresMutex); taosThreadMutexLock(&tiresMutex);
// STABLE set null // STABLE set null
STire* tire = tires[type]; STire* tire = tires[type];
if(tire) { if (tire) {
insertWord(tire, name); insertWord(tire, name);
} }
taosThreadMutexUnlock(&tiresMutex); taosThreadMutexUnlock(&tiresMutex);
...@@ -1958,16 +1814,16 @@ bool dealCreateCommand(char * sql) { ...@@ -1958,16 +1814,16 @@ bool dealCreateCommand(char * sql) {
} }
// deal create, if have 'drop' return true // deal create, if have 'drop' return true
bool dealDropCommand(char * sql) { bool dealDropCommand(char* sql) {
// check keyword // check keyword
if(strncasecmp(sql, "drop ", 5) != 0) { if (strncasecmp(sql, "drop ", 5) != 0) {
return false; return false;
} }
char name[1024]; char name[1024];
char *p = sql + 5; char* p = sql + 5;
if (getWordName(p, name, sizeof(name)) == 0) { if (getWordName(p, name, sizeof(name)) == 0) {
// no name , return // no name , return
return true; return true;
} }
...@@ -1986,7 +1842,7 @@ bool dealDropCommand(char * sql) { ...@@ -1986,7 +1842,7 @@ bool dealDropCommand(char * sql) {
} else if (strcasecmp(name, "stream") == 0) { } else if (strcasecmp(name, "stream") == 0) {
type = WT_VAR_STREAM; type = WT_VAR_STREAM;
} else { } else {
// no match , return // no match , return
return true; return true;
} }
...@@ -1995,30 +1851,27 @@ bool dealDropCommand(char * sql) { ...@@ -1995,30 +1851,27 @@ bool dealDropCommand(char * sql) {
// get next word , that is table name // get next word , that is table name
if (getWordName(p, name, sizeof(name)) == 0) { if (getWordName(p, name, sizeof(name)) == 0) {
// no name , return // no name , return
return true; return true;
} }
// switch new db // switch new db
taosThreadMutexLock(&tiresMutex); taosThreadMutexLock(&tiresMutex);
// STABLE set null // STABLE set null
if(type == WT_VAR_ALLTABLE) { if (type == WT_VAR_ALLTABLE) {
bool del = false; bool del = false;
// del in stable // del in stable
STire* tire = tires[WT_VAR_STABLE]; STire* tire = tires[WT_VAR_STABLE];
if(tire) if (tire) del = deleteWord(tire, name);
del = deleteWord(tire, name);
// del in table // del in table
if(!del) { if (!del) {
tire = tires[WT_VAR_TABLE]; tire = tires[WT_VAR_TABLE];
if(tire) if (tire) del = deleteWord(tire, name);
del = deleteWord(tire, name);
} }
} else { } else {
// OTHER TYPE // OTHER TYPE
STire* tire = tires[type]; STire* tire = tires[type];
if(tire) if (tire) deleteWord(tire, name);
deleteWord(tire, name);
} }
taosThreadMutexUnlock(&tiresMutex); taosThreadMutexUnlock(&tiresMutex);
...@@ -2027,26 +1880,26 @@ bool dealDropCommand(char * sql) { ...@@ -2027,26 +1880,26 @@ bool dealDropCommand(char * sql) {
// callback autotab module after shell sql execute // callback autotab module after shell sql execute
void callbackAutoTab(char* sqlstr, TAOS* pSql, bool usedb) { void callbackAutoTab(char* sqlstr, TAOS* pSql, bool usedb) {
char * sql = sqlstr; char* sql = sqlstr;
// remove prefix blank // remove prefix blank
while (*sql == ' ') { while (*sql == ' ') {
sql++; sql++;
} }
if(dealUseDB(sql)) { if (dealUseDB(sql)) {
// change to new db // change to new db
return ; return;
} }
// create command add name to autotab // create command add name to autotab
if(dealCreateCommand(sql)) { if (dealCreateCommand(sql)) {
return ; return;
} }
// drop command remove name from autotab // drop command remove name from autotab
if(dealDropCommand(sql)) { if (dealDropCommand(sql)) {
return ; return;
} }
return ; return;
} }
...@@ -22,414 +22,405 @@ ...@@ -22,414 +22,405 @@
// create prefix search tree // create prefix search tree
STire* createTire(char type) { STire* createTire(char type) {
STire* tire = taosMemoryMalloc(sizeof(STire)); STire* tire = taosMemoryMalloc(sizeof(STire));
memset(tire, 0, sizeof(STire)); memset(tire, 0, sizeof(STire));
tire->ref = 1; // init is 1 tire->ref = 1; // init is 1
tire->type = type; tire->type = type;
tire->root.d = (STireNode **)taosMemoryCalloc(CHAR_CNT, sizeof(STireNode *)); tire->root.d = (STireNode**)taosMemoryCalloc(CHAR_CNT, sizeof(STireNode*));
return tire; return tire;
} }
// free tire node // free tire node
void freeTireNode(STireNode* node) { void freeTireNode(STireNode* node) {
if (node == NULL) if (node == NULL) return;
return ;
// nest free sub node on array d
// nest free sub node on array d if (node->d) {
if(node->d) { for (int i = 0; i < CHAR_CNT; i++) {
for (int i = 0; i < CHAR_CNT; i++) { freeTireNode(node->d[i]);
freeTireNode(node->d[i]);
}
taosMemoryFree(node->d);
} }
taosMemoryFree(node->d);
}
// free self // free self
taosMemoryFree(node); taosMemoryFree(node);
} }
// destroy prefix search tree // destroy prefix search tree
void freeTire(STire* tire) { void freeTire(STire* tire) {
// free nodes // free nodes
for (int i = 0; i < CHAR_CNT; i++) { for (int i = 0; i < CHAR_CNT; i++) {
freeTireNode(tire->root.d[i]); freeTireNode(tire->root.d[i]);
} }
taosMemoryFree(tire->root.d); taosMemoryFree(tire->root.d);
// free from list // free from list
StrName * item = tire->head; StrName* item = tire->head;
while (item) { while (item) {
StrName * next = item->next; StrName* next = item->next;
// free string // free string
taosMemoryFree(item->name); taosMemoryFree(item->name);
// free node // free node
taosMemoryFree(item); taosMemoryFree(item);
// move next // move next
item = next; item = next;
} }
tire->head = tire->tail = NULL; tire->head = tire->tail = NULL;
// free tire // free tire
taosMemoryFree(tire); taosMemoryFree(tire);
} }
// insert a new word to list // insert a new word to list
bool insertToList(STire* tire, char* word) { bool insertToList(STire* tire, char* word) {
StrName * p = (StrName *)taosMemoryMalloc(sizeof(StrName)); StrName* p = (StrName*)taosMemoryMalloc(sizeof(StrName));
p->name = strdup(word); p->name = strdup(word);
p->next = NULL; p->next = NULL;
if(tire->head == NULL) { if (tire->head == NULL) {
tire->head = p; tire->head = p;
tire->tail = p; tire->tail = p;
}else { } else {
tire->tail->next = p; tire->tail->next = p;
tire->tail = p; tire->tail = p;
} }
return true; return true;
} }
// insert a new word to tree // insert a new word to tree
bool insertToTree(STire* tire, char* word, int len) { bool insertToTree(STire* tire, char* word, int len) {
int m = 0; int m = 0;
STireNode ** nodes = tire->root.d; STireNode** nodes = tire->root.d;
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
m = word[i] - FIRST_ASCII; m = word[i] - FIRST_ASCII;
if (m < 0 || m > CHAR_CNT) { if (m < 0 || m > CHAR_CNT) {
return false; return false;
}
if (nodes[m] == NULL) {
// no pointer
STireNode* p = (STireNode* )taosMemoryMalloc(sizeof(STireNode));
memset(p, 0, sizeof(STireNode));
nodes[m] = p;
if (i == len - 1) {
// is end
p->end = true;
break;
}
}
if (nodes[m]->d == NULL) {
// malloc d
nodes[m]->d = (STireNode **)taosMemoryCalloc(CHAR_CNT, sizeof(STireNode *));
}
// move to next node
nodes = nodes[m]->d;
} }
// add count if (nodes[m] == NULL) {
tire->count += 1; // no pointer
return true; STireNode* p = (STireNode*)taosMemoryMalloc(sizeof(STireNode));
memset(p, 0, sizeof(STireNode));
nodes[m] = p;
if (i == len - 1) {
// is end
p->end = true;
break;
}
}
if (nodes[m]->d == NULL) {
// malloc d
nodes[m]->d = (STireNode**)taosMemoryCalloc(CHAR_CNT, sizeof(STireNode*));
}
// move to next node
nodes = nodes[m]->d;
}
// add count
tire->count += 1;
return true;
} }
// insert a new word // insert a new word
bool insertWord(STire* tire, char* word) { bool insertWord(STire* tire, char* word) {
int len = strlen(word); int len = strlen(word);
if (len >= MAX_WORD_LEN) { if (len >= MAX_WORD_LEN) {
return false;
}
switch (tire->type) {
case TIRE_TREE:
return insertToTree(tire, word, len);
case TIRE_LIST:
return insertToList(tire, word);
default:
break;
}
return false; return false;
}
switch (tire->type) {
case TIRE_TREE:
return insertToTree(tire, word, len);
case TIRE_LIST:
return insertToList(tire, word);
default:
break;
}
return false;
} }
// delete one word from list // delete one word from list
bool deleteFromList(STire* tire, char* word) { bool deleteFromList(STire* tire, char* word) {
StrName * item = tire->head; StrName* item = tire->head;
while (item) { while (item) {
if (strcmp(item->name, word) == 0) { if (strcmp(item->name, word) == 0) {
// found, reset empty to delete // found, reset empty to delete
item->name[0] = 0; item->name[0] = 0;
}
// move next
item = item->next;
} }
return true;
// move next
item = item->next;
}
return true;
} }
// delete one word from tree // delete one word from tree
bool deleteFromTree(STire* tire, char* word, int len) { bool deleteFromTree(STire* tire, char* word, int len) {
int m = 0; int m = 0;
bool del = false; bool del = false;
STireNode** nodes = tire->root.d; STireNode** nodes = tire->root.d;
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
m = word[i] - FIRST_ASCII; m = word[i] - FIRST_ASCII;
if (m < 0 || m >= CHAR_CNT) { if (m < 0 || m >= CHAR_CNT) {
return false; return false;
}
if (nodes[m] == NULL) {
// no found
return false;
} else {
// not null
if(i == len - 1) {
// this is last, only set end false , not free node
nodes[m]->end = false;
del = true;
break;
}
}
if(nodes[m]->d == NULL)
break;
// move to next node
nodes = nodes[m]->d;
} }
// reduce count if (nodes[m] == NULL) {
if (del) { // no found
tire->count -= 1; return false;
} else {
// not null
if (i == len - 1) {
// this is last, only set end false , not free node
nodes[m]->end = false;
del = true;
break;
}
} }
return del; if (nodes[m]->d == NULL) break;
// move to next node
nodes = nodes[m]->d;
}
// reduce count
if (del) {
tire->count -= 1;
}
return del;
} }
// insert a new word // insert a new word
bool deleteWord(STire* tire, char* word) { bool deleteWord(STire* tire, char* word) {
int len = strlen(word); int len = strlen(word);
if (len >= MAX_WORD_LEN) { if (len >= MAX_WORD_LEN) {
return false;
}
switch (tire->type) {
case TIRE_TREE:
return deleteFromTree(tire, word, len);
case TIRE_LIST:
return deleteFromList(tire, word);
default:
break;
}
return false; return false;
}
switch (tire->type) {
case TIRE_TREE:
return deleteFromTree(tire, word, len);
case TIRE_LIST:
return deleteFromList(tire, word);
default:
break;
}
return false;
} }
void addWordToMatch(SMatch* match, char* word){ void addWordToMatch(SMatch* match, char* word) {
// malloc new // malloc new
SMatchNode* node = (SMatchNode* )taosMemoryMalloc(sizeof(SMatchNode)); SMatchNode* node = (SMatchNode*)taosMemoryMalloc(sizeof(SMatchNode));
memset(node, 0, sizeof(SMatchNode)); memset(node, 0, sizeof(SMatchNode));
node->word = strdup(word); node->word = strdup(word);
// append to match // append to match
if (match->head == NULL) { if (match->head == NULL) {
match->head = match->tail = node; match->head = match->tail = node;
} else { } else {
match->tail->next = node; match->tail->next = node;
match->tail = node; match->tail = node;
} }
match->count += 1; match->count += 1;
} }
// enum all words from node // enum all words from node
void enumAllWords(STireNode** nodes, char* prefix, SMatch* match) { void enumAllWords(STireNode** nodes, char* prefix, SMatch* match) {
STireNode * c; STireNode* c;
char word[MAX_WORD_LEN]; char word[MAX_WORD_LEN];
int len = strlen(prefix); int len = strlen(prefix);
for (int i = 0; i < CHAR_CNT; i++) { for (int i = 0; i < CHAR_CNT; i++) {
c = nodes[i]; c = nodes[i];
if (c == NULL) { if (c == NULL) {
// chain end node // chain end node
continue; continue;
} else { } else {
// combine word string // combine word string
memset(word, 0, sizeof(word)); memset(word, 0, sizeof(word));
strcpy(word, prefix); strcpy(word, prefix);
word[len] = FIRST_ASCII + i; // append current char word[len] = FIRST_ASCII + i; // append current char
// chain middle node // chain middle node
if (c->end) { if (c->end) {
// have end flag // have end flag
addWordToMatch(match, word); addWordToMatch(match, word);
} }
// nested call next layer // nested call next layer
if (c->d) if (c->d) enumAllWords(c->d, word, match);
enumAllWords(c->d, word, match);
}
} }
}
} }
// match prefix from list // match prefix from list
void matchPrefixFromList(STire* tire, char* prefix, SMatch* match) { void matchPrefixFromList(STire* tire, char* prefix, SMatch* match) {
StrName * item = tire->head; StrName* item = tire->head;
int len = strlen(prefix); int len = strlen(prefix);
while (item) { while (item) {
if ( strncmp(item->name, prefix, len) == 0) { if (strncmp(item->name, prefix, len) == 0) {
// prefix matched // prefix matched
addWordToMatch(match, item->name); addWordToMatch(match, item->name);
}
// move next
item = item->next;
} }
// move next
item = item->next;
}
} }
// match prefix words, if match is not NULL , put all item to match and return match // match prefix words, if match is not NULL , put all item to match and return match
void matchPrefixFromTree(STire* tire, char* prefix, SMatch* match) { void matchPrefixFromTree(STire* tire, char* prefix, SMatch* match) {
SMatch* root = match; SMatch* root = match;
int m = 0; int m = 0;
STireNode* c = 0; STireNode* c = 0;
int len = strlen(prefix); int len = strlen(prefix);
if (len >= MAX_WORD_LEN) { if (len >= MAX_WORD_LEN) {
return; return;
}
STireNode** nodes = tire->root.d;
for (int i = 0; i < len; i++) {
m = prefix[i] - FIRST_ASCII;
if (m < 0 || m > CHAR_CNT) {
return;
} }
STireNode** nodes = tire->root.d; // match
for (int i = 0; i < len; i++) { c = nodes[m];
m = prefix[i] - FIRST_ASCII; if (c == NULL) {
if (m < 0 || m > CHAR_CNT) { // arrive end
return; break;
}
// match
c = nodes[m];
if (c == NULL) {
// arrive end
break;
}
// previous items already matched
if (i == len - 1) {
// malloc match if not pass by param match
if (root == NULL) {
root = (SMatch* )taosMemoryMalloc(sizeof(SMatch));
memset(root, 0, sizeof(SMatch));
strcpy(root->pre, prefix);
}
// prefix is match to end char
if (c->d)
enumAllWords(c->d, prefix, root);
} else {
// move to next node continue match
if(c->d == NULL)
break;
nodes = c->d;
}
}
// return
return ;
}
SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match) {
if(match == NULL) {
match = (SMatch* )taosMemoryMalloc(sizeof(SMatch));
memset(match, 0, sizeof(SMatch));
} }
switch (tire->type) { // previous items already matched
case TIRE_TREE: if (i == len - 1) {
matchPrefixFromTree(tire, prefix, match); // malloc match if not pass by param match
case TIRE_LIST: if (root == NULL) {
matchPrefixFromList(tire, prefix, match); root = (SMatch*)taosMemoryMalloc(sizeof(SMatch));
default: memset(root, 0, sizeof(SMatch));
break; strcpy(root->pre, prefix);
}
// prefix is match to end char
if (c->d) enumAllWords(c->d, prefix, root);
} else {
// move to next node continue match
if (c->d == NULL) break;
nodes = c->d;
} }
}
// return if need // return
if (match->count == 0) { return;
freeMatch(match);
match = NULL;
}
return match;
} }
SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match) {
if (match == NULL) {
match = (SMatch*)taosMemoryMalloc(sizeof(SMatch));
memset(match, 0, sizeof(SMatch));
}
switch (tire->type) {
case TIRE_TREE:
matchPrefixFromTree(tire, prefix, match);
case TIRE_LIST:
matchPrefixFromList(tire, prefix, match);
default:
break;
}
// return if need
if (match->count == 0) {
freeMatch(match);
match = NULL;
}
return match;
}
// get all items from tires tree // get all items from tires tree
void enumFromList(STire* tire, SMatch* match) { void enumFromList(STire* tire, SMatch* match) {
StrName * item = tire->head; StrName* item = tire->head;
while (item) { while (item) {
if (item->name[0] != 0) { if (item->name[0] != 0) {
// not delete // not delete
addWordToMatch(match, item->name); addWordToMatch(match, item->name);
}
// move next
item = item->next;
} }
// move next
item = item->next;
}
} }
// get all items from tires tree // get all items from tires tree
void enumFromTree(STire* tire, SMatch* match) { void enumFromTree(STire* tire, SMatch* match) {
char pre[2] ={0, 0}; char pre[2] = {0, 0};
STireNode* c; STireNode* c;
// enum first layer // enum first layer
for (int i = 0; i < CHAR_CNT; i++) { for (int i = 0; i < CHAR_CNT; i++) {
pre[0] = FIRST_ASCII + i; pre[0] = FIRST_ASCII + i;
// each node // each node
c = tire->root.d[i]; c = tire->root.d[i];
if (c == NULL) { if (c == NULL) {
// this branch no data // this branch no data
continue; continue;
}
// this branch have data
if(c->end)
addWordToMatch(match, pre);
else
matchPrefix(tire, pre, match);
} }
// this branch have data
if (c->end)
addWordToMatch(match, pre);
else
matchPrefix(tire, pre, match);
}
} }
// get all items from tires tree // get all items from tires tree
SMatch* enumAll(STire* tire) { SMatch* enumAll(STire* tire) {
SMatch* match = (SMatch* )taosMemoryMalloc(sizeof(SMatch)); SMatch* match = (SMatch*)taosMemoryMalloc(sizeof(SMatch));
memset(match, 0, sizeof(SMatch)); memset(match, 0, sizeof(SMatch));
switch (tire->type) { switch (tire->type) {
case TIRE_TREE: case TIRE_TREE:
enumFromTree(tire, match); enumFromTree(tire, match);
case TIRE_LIST: case TIRE_LIST:
enumFromList(tire, match); enumFromList(tire, match);
default: default:
break; break;
} }
// return if need // return if need
if (match->count == 0) { if (match->count == 0) {
freeMatch(match); freeMatch(match);
match = NULL; match = NULL;
} }
return match; return match;
} }
// free match result // free match result
void freeMatchNode(SMatchNode* node) { void freeMatchNode(SMatchNode* node) {
// first free next // first free next
if (node->next) if (node->next) freeMatchNode(node->next);
freeMatchNode(node->next);
// second free self
// second free self if (node->word) taosMemoryFree(node->word);
if (node->word) taosMemoryFree(node);
taosMemoryFree(node->word);
taosMemoryFree(node);
} }
// free match result // free match result
void freeMatch(SMatch* match) { void freeMatch(SMatch* match) {
// first free next // first free next
if (match->head) { if (match->head) {
freeMatchNode(match->head); freeMatchNode(match->head);
} }
// second free self // second free self
taosMemoryFree(match); taosMemoryFree(match);
} }
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册