未验证 提交 5da10761 编写于 作者: S Shengliang Guan 提交者: GitHub

Merge pull request #3000 from taosdata/feature/query

Feature/query
...@@ -277,6 +277,9 @@ void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRo ...@@ -277,6 +277,9 @@ void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRo
void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp); void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp);
int tscSetMgmtEpSetFromCfg(const char *first, const char *second); int tscSetMgmtEpSetFromCfg(const char *first, const char *second);
bool tscSetSqlOwner(SSqlObj* pSql);
void tscClearSqlOwner(SSqlObj* pSql);
void* malloc_throw(size_t size); void* malloc_throw(size_t size);
void* calloc_throw(size_t nmemb, size_t size); void* calloc_throw(size_t nmemb, size_t size);
char* strdup_throw(const char* str); char* strdup_throw(const char* str);
......
...@@ -80,8 +80,9 @@ typedef struct STableMetaInfo { ...@@ -80,8 +80,9 @@ typedef struct STableMetaInfo {
* 2. keep the vgroup index for multi-vnode insertion * 2. keep the vgroup index for multi-vnode insertion
*/ */
int32_t vgroupIndex; int32_t vgroupIndex;
char name[TSDB_TABLE_ID_LEN]; // (super) table name char name[TSDB_TABLE_FNAME_LEN]; // (super) table name
SArray* tagColList; // SArray<SColumn*>, involved tag columns char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql
SArray* tagColList; // SArray<SColumn*>, involved tag columns
} STableMetaInfo; } STableMetaInfo;
/* the structure for sql function in select clause */ /* the structure for sql function in select clause */
...@@ -106,7 +107,7 @@ typedef struct SColumnIndex { ...@@ -106,7 +107,7 @@ typedef struct SColumnIndex {
typedef struct SFieldSupInfo { typedef struct SFieldSupInfo {
bool visible; bool visible;
SExprInfo *pArithExprInfo; SExprInfo *pArithExprInfo;
SSqlExpr * pSqlExpr; SSqlExpr *pSqlExpr;
} SFieldSupInfo; } SFieldSupInfo;
typedef struct SFieldInfo { typedef struct SFieldInfo {
...@@ -128,7 +129,7 @@ typedef struct SCond { ...@@ -128,7 +129,7 @@ typedef struct SCond {
} SCond; } SCond;
typedef struct SJoinNode { typedef struct SJoinNode {
char tableId[TSDB_TABLE_ID_LEN]; char tableId[TSDB_TABLE_FNAME_LEN];
uint64_t uid; uint64_t uid;
int16_t tagColId; int16_t tagColId;
} SJoinNode; } SJoinNode;
...@@ -162,7 +163,7 @@ typedef struct SParamInfo { ...@@ -162,7 +163,7 @@ typedef struct SParamInfo {
} SParamInfo; } SParamInfo;
typedef struct STableDataBlocks { typedef struct STableDataBlocks {
char tableId[TSDB_TABLE_ID_LEN]; char tableId[TSDB_TABLE_FNAME_LEN];
int8_t tsSource; // where does the UNIX timestamp come from, server or client int8_t tsSource; // where does the UNIX timestamp come from, server or client
bool ordered; // if current rows are ordered or not bool ordered; // if current rows are ordered or not
int64_t vgId; // virtual group id int64_t vgId; // virtual group id
...@@ -255,6 +256,7 @@ typedef struct SResRec { ...@@ -255,6 +256,7 @@ typedef struct SResRec {
typedef struct { typedef struct {
int64_t numOfRows; // num of results in current retrieved int64_t numOfRows; // num of results in current retrieved
int64_t numOfRowsGroup; // num of results of current group
int64_t numOfTotal; // num of total results int64_t numOfTotal; // num of total results
int64_t numOfClauseTotal; // num of total result in current subclause int64_t numOfClauseTotal; // num of total result in current subclause
char * pRsp; char * pRsp;
...@@ -301,6 +303,7 @@ typedef struct STscObj { ...@@ -301,6 +303,7 @@ typedef struct STscObj {
typedef struct SSqlObj { typedef struct SSqlObj {
void *signature; void *signature;
pthread_t owner; // owner of sql object, by which it is executed
STscObj *pTscObj; STscObj *pTscObj;
void *pRpcCtx; void *pRpcCtx;
void (*fp)(); void (*fp)();
...@@ -419,7 +422,6 @@ char *tscGetErrorMsgPayload(SSqlCmd *pCmd); ...@@ -419,7 +422,6 @@ char *tscGetErrorMsgPayload(SSqlCmd *pCmd);
int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql); int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql);
int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo); int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo);
//void tscGetResultColumnChr(SSqlRes *pRes, SFieldInfo* pFieldInfo, int32_t column);
static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t columnIndex) { static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t columnIndex) {
SFieldSupInfo* pInfo = (SFieldSupInfo*) TARRAY_GET_ELEM(pFieldInfo->pSupportInfo, columnIndex); SFieldSupInfo* pInfo = (SFieldSupInfo*) TARRAY_GET_ELEM(pFieldInfo->pSupportInfo, columnIndex);
......
...@@ -220,14 +220,13 @@ void taos_fetch_rows_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, int), voi ...@@ -220,14 +220,13 @@ void taos_fetch_rows_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, int), voi
if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) { if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
tscFetchDatablockFromSubquery(pSql); tscFetchDatablockFromSubquery(pSql);
} else if (pRes->completed) { } else if (pRes->completed) {
if(pCmd->command == TSDB_SQL_FETCH) { if(pCmd->command == TSDB_SQL_FETCH || (pCmd->command >= TSDB_SQL_SERV_STATUS && pCmd->command <= TSDB_SQL_CURRENT_USER)) {
if (hasMoreVnodesToTry(pSql)) { // sequentially retrieve data from remain vnodes. if (hasMoreVnodesToTry(pSql)) { // sequentially retrieve data from remain vnodes.
tscTryQueryNextVnode(pSql, tscAsyncQueryRowsForNextVnode); tscTryQueryNextVnode(pSql, tscAsyncQueryRowsForNextVnode);
return;
} else { } else {
/* /*
* all available virtual node has been checked already, now we need to check * all available virtual nodes in current clause has been checked already, now try the
* for the next subclause queries * next one in the following union subclause
*/ */
if (pCmd->clauseIndex < pCmd->numOfClause - 1) { if (pCmd->clauseIndex < pCmd->numOfClause - 1) {
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode); tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
...@@ -235,11 +234,12 @@ void taos_fetch_rows_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, int), voi ...@@ -235,11 +234,12 @@ void taos_fetch_rows_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, int), voi
} }
/* /*
* 1. has reach the limitation * 1. has reach the limitation
* 2. no remain virtual nodes to be retrieved anymore * 2. no remain virtual nodes to be retrieved anymore
*/ */
(*pSql->fetchFp)(param, pSql, 0); (*pSql->fetchFp)(param, pSql, 0);
} }
return; return;
} else if (pCmd->command == TSDB_SQL_RETRIEVE || pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE) { } else if (pCmd->command == TSDB_SQL_RETRIEVE || pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE) {
// in case of show command, return no data // in case of show command, return no data
......
...@@ -1942,11 +1942,12 @@ static void do_top_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData, ...@@ -1942,11 +1942,12 @@ static void do_top_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData,
static void do_bottom_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData, int64_t ts, uint16_t type, static void do_bottom_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData, int64_t ts, uint16_t type,
SExtTagsInfo *pTagInfo, char *pTags, int16_t stage) { SExtTagsInfo *pTagInfo, char *pTags, int16_t stage) {
tValuePair **pList = pInfo->res;
tVariant val = {0}; tVariant val = {0};
tVariantCreateFromBinary(&val, pData, tDataTypeDesc[type].nSize, type); tVariantCreateFromBinary(&val, pData, tDataTypeDesc[type].nSize, type);
tValuePair **pList = pInfo->res;
assert(pList != NULL);
if (pInfo->num < maxLen) { if (pInfo->num < maxLen) {
if (pInfo->num == 0) { if (pInfo->num == 0) {
valuePairAssign(pList[pInfo->num], type, (const char*) &val.i64Key, ts, pTags, pTagInfo, stage); valuePairAssign(pList[pInfo->num], type, (const char*) &val.i64Key, ts, pTags, pTagInfo, stage);
......
...@@ -293,7 +293,7 @@ static void tscProcessCurrentDB(SSqlObj *pSql) { ...@@ -293,7 +293,7 @@ static void tscProcessCurrentDB(SSqlObj *pSql) {
char db[TSDB_DB_NAME_LEN] = {0}; char db[TSDB_DB_NAME_LEN] = {0};
extractDBName(pSql->pTscObj->db, db); extractDBName(pSql->pTscObj->db, db);
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
pExpr->resType = TSDB_DATA_TYPE_BINARY; pExpr->resType = TSDB_DATA_TYPE_BINARY;
...@@ -314,7 +314,7 @@ static void tscProcessCurrentDB(SSqlObj *pSql) { ...@@ -314,7 +314,7 @@ static void tscProcessCurrentDB(SSqlObj *pSql) {
static void tscProcessServerVer(SSqlObj *pSql) { static void tscProcessServerVer(SSqlObj *pSql) {
const char* v = pSql->pTscObj->sversion; const char* v = pSql->pTscObj->sversion;
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0);
pExpr->resType = TSDB_DATA_TYPE_BINARY; pExpr->resType = TSDB_DATA_TYPE_BINARY;
......
...@@ -68,7 +68,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc ...@@ -68,7 +68,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc
SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, i); SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, i);
pCtx->aOutputBuf = pCtx->aOutputBuf =
pReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pReducer->resColModel->capacity; pReducer->pResultBuf->data + pExpr->offset * pReducer->resColModel->capacity;
pCtx->order = pQueryInfo->order.order; pCtx->order = pQueryInfo->order.order;
pCtx->functionId = pExpr->functionId; pCtx->functionId = pExpr->functionId;
...@@ -321,6 +321,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd ...@@ -321,6 +321,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
pReducer->finalRowSize = tscGetResRowLength(pQueryInfo->exprList); pReducer->finalRowSize = tscGetResRowLength(pQueryInfo->exprList);
pReducer->resColModel = finalmodel; pReducer->resColModel = finalmodel;
pReducer->resColModel->capacity = pReducer->nResultBufSize; pReducer->resColModel->capacity = pReducer->nResultBufSize;
assert(pReducer->finalRowSize > 0); assert(pReducer->finalRowSize > 0);
if (pReducer->finalRowSize > 0) { if (pReducer->finalRowSize > 0) {
pReducer->resColModel->capacity /= pReducer->finalRowSize; pReducer->resColModel->capacity /= pReducer->finalRowSize;
...@@ -328,7 +329,6 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd ...@@ -328,7 +329,6 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
assert(pReducer->finalRowSize <= pReducer->rowSize); assert(pReducer->finalRowSize <= pReducer->rowSize);
pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity); pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity);
// pReducer->pBufForInterpo = calloc(1, pReducer->nResultBufSize);
if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL || if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL ||
/*pReducer->pBufForInterpo == NULL || */pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) { /*pReducer->pBufForInterpo == NULL || */pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
...@@ -856,24 +856,6 @@ void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo ...@@ -856,24 +856,6 @@ void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo
tColModelAppend(pModel, pLocalReducer->discardData, pLocalReducer->prevRowOfInput, 0, 1, 1); tColModelAppend(pModel, pLocalReducer->discardData, pLocalReducer->prevRowOfInput, 0, 1, 1);
} }
// todo merge with following function
// static void reversedCopyResultToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tFilePage *pFinalDataPage) {
//
// for (int32_t i = 0; i < pQueryInfo->exprList.numOfExprs; ++i) {
// TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
//
// int32_t offset = tscFieldInfoGetOffset(pQueryInfo, i);
// char * src = pFinalDataPage->data + (pRes->numOfRows - 1) * pField->bytes + pRes->numOfRows * offset;
// char * dst = pRes->data + pRes->numOfRows * offset;
//
// for (int32_t j = 0; j < pRes->numOfRows; ++j) {
// memcpy(dst, src, (size_t)pField->bytes);
// dst += pField->bytes;
// src -= pField->bytes;
// }
// }
//}
static void reversedCopyFromInterpolationToDstBuf(SQueryInfo *pQueryInfo, SSqlRes *pRes, tFilePage **pResPages, static void reversedCopyFromInterpolationToDstBuf(SQueryInfo *pQueryInfo, SSqlRes *pRes, tFilePage **pResPages,
SLocalReducer *pLocalReducer) { SLocalReducer *pLocalReducer) {
assert(0); assert(0);
...@@ -907,20 +889,10 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO ...@@ -907,20 +889,10 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
tFilePage * pFinalDataPage = pLocalReducer->pResultBuf; tFilePage * pFinalDataPage = pLocalReducer->pResultBuf;
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
// if (pRes->pLocalReducer != pLocalReducer) {
// /*
// * Release the SSqlObj is called, and it is int destroying function invoked by other thread.
// * However, the other thread will WAIT until current process fully completes.
// * Since the flag of release struct is set by doLocalReduce function
// */
// assert(pRes->pLocalReducer == NULL);
// }
// no interval query, no fill operation // no interval query, no fill operation
if (pQueryInfo->intervalTime == 0 || pQueryInfo->fillType == TSDB_FILL_NONE) { if (pQueryInfo->intervalTime == 0 || pQueryInfo->fillType == TSDB_FILL_NONE) {
pRes->data = pLocalReducer->pFinalRes; pRes->data = pLocalReducer->pFinalRes;
pRes->numOfRows = pFinalDataPage->num; pRes->numOfRows = pFinalDataPage->num;
pRes->numOfClauseTotal += pRes->numOfRows;
if (pQueryInfo->limit.offset > 0) { if (pQueryInfo->limit.offset > 0) {
if (pQueryInfo->limit.offset < pRes->numOfRows) { if (pQueryInfo->limit.offset < pRes->numOfRows) {
...@@ -931,22 +903,22 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO ...@@ -931,22 +903,22 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
tColModelCompact(pLocalReducer->resColModel, pFinalDataPage, prevSize); tColModelCompact(pLocalReducer->resColModel, pFinalDataPage, prevSize);
pRes->numOfRows -= pQueryInfo->limit.offset; pRes->numOfRows -= pQueryInfo->limit.offset;
pRes->numOfClauseTotal -= pQueryInfo->limit.offset;
pQueryInfo->limit.offset = 0; pQueryInfo->limit.offset = 0;
} else { } else {
pQueryInfo->limit.offset -= pRes->numOfRows; pQueryInfo->limit.offset -= pRes->numOfRows;
pRes->numOfRows = 0; pRes->numOfRows = 0;
pRes->numOfClauseTotal = 0;
} }
} }
if (pQueryInfo->limit.limit >= 0 && pRes->numOfClauseTotal > pQueryInfo->limit.limit) { pRes->numOfRowsGroup += pRes->numOfRows;
if (pQueryInfo->limit.limit >= 0 && pRes->numOfRowsGroup > pQueryInfo->limit.limit) {
/* impose the limitation of output rows on the final result */ /* impose the limitation of output rows on the final result */
int32_t prevSize = (int32_t)pFinalDataPage->num; int32_t prevSize = pFinalDataPage->num;
int32_t overflow = (int32_t)(pRes->numOfClauseTotal - pQueryInfo->limit.limit); int32_t overflow = pRes->numOfRowsGroup - pQueryInfo->limit.limit;
assert(overflow < pRes->numOfRows); assert(overflow < pRes->numOfRows);
pRes->numOfClauseTotal = pQueryInfo->limit.limit; pRes->numOfRowsGroup = pQueryInfo->limit.limit;
pRes->numOfRows -= overflow; pRes->numOfRows -= overflow;
pFinalDataPage->num -= overflow; pFinalDataPage->num -= overflow;
...@@ -957,6 +929,8 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO ...@@ -957,6 +929,8 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
} }
memcpy(pRes->data, pFinalDataPage->data, pRes->numOfRows * pLocalReducer->finalRowSize); memcpy(pRes->data, pFinalDataPage->data, pRes->numOfRows * pLocalReducer->finalRowSize);
pRes->numOfClauseTotal += pRes->numOfRows;
pFinalDataPage->num = 0; pFinalDataPage->num = 0;
return; return;
} }
...@@ -969,7 +943,7 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO ...@@ -969,7 +943,7 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i); TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
pResPages[i] = calloc(1, sizeof(tFilePage) + pField->bytes * pLocalReducer->resColModel->capacity); pResPages[i] = calloc(1, sizeof(tFilePage) + pField->bytes * pLocalReducer->resColModel->capacity);
} }
while (1) { while (1) {
int64_t newRows = taosGenerateDataBlock(pFillInfo, pResPages, pLocalReducer->resColModel->capacity); int64_t newRows = taosGenerateDataBlock(pFillInfo, pResPages, pLocalReducer->resColModel->capacity);
...@@ -986,7 +960,6 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO ...@@ -986,7 +960,6 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
pRes->data = pLocalReducer->pFinalRes; pRes->data = pLocalReducer->pFinalRes;
pRes->numOfRows = newRows; pRes->numOfRows = newRows;
pRes->numOfClauseTotal += newRows;
pQueryInfo->limit.offset = 0; pQueryInfo->limit.offset = 0;
break; break;
...@@ -1010,15 +983,13 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO ...@@ -1010,15 +983,13 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
} }
if (pRes->numOfRows > 0) { if (pRes->numOfRows > 0) {
if (pQueryInfo->limit.limit >= 0 && pRes->numOfClauseTotal > pQueryInfo->limit.limit) { if (pQueryInfo->limit.limit >= 0 && pRes->numOfRows > pQueryInfo->limit.limit) {
int32_t overflow = (int32_t)(pRes->numOfClauseTotal - pQueryInfo->limit.limit); int32_t overflow = pRes->numOfRows - pQueryInfo->limit.limit;
pRes->numOfRows -= overflow; pRes->numOfRows -= overflow;
assert(pRes->numOfRows >= 0);
pRes->numOfClauseTotal = pQueryInfo->limit.limit;
pFinalDataPage->num -= overflow; pFinalDataPage->num -= overflow;
assert(pRes->numOfRows >= 0 && pFinalDataPage->num > 0);
/* set remain data to be discarded, and reset the interpolation information */ /* set remain data to be discarded, and reset the interpolation information */
savePrevRecordAndSetupInterpoInfo(pLocalReducer, pQueryInfo, pFillInfo); savePrevRecordAndSetupInterpoInfo(pLocalReducer, pQueryInfo, pFillInfo);
} }
...@@ -1032,6 +1003,9 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO ...@@ -1032,6 +1003,9 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO
} else { // todo bug?? } else { // todo bug??
reversedCopyFromInterpolationToDstBuf(pQueryInfo, pRes, pResPages, pLocalReducer); reversedCopyFromInterpolationToDstBuf(pQueryInfo, pRes, pResPages, pLocalReducer);
} }
pRes->numOfRowsGroup += pRes->numOfRows;
pRes->numOfClauseTotal += pRes->numOfRows;
} }
pFinalDataPage->num = 0; pFinalDataPage->num = 0;
...@@ -1227,7 +1201,10 @@ static bool saveGroupResultInfo(SSqlObj *pSql) { ...@@ -1227,7 +1201,10 @@ static bool saveGroupResultInfo(SSqlObj *pSql) {
SSqlRes *pRes = &pSql->res; SSqlRes *pRes = &pSql->res;
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
pRes->numOfGroups += 1;
if (pRes->numOfRowsGroup > 0) {
pRes->numOfGroups += 1;
}
// the output group is limited by the slimit clause // the output group is limited by the slimit clause
if (reachGroupResultLimit(pQueryInfo, pRes)) { if (reachGroupResultLimit(pQueryInfo, pRes)) {
...@@ -1266,7 +1243,12 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no ...@@ -1266,7 +1243,12 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
pRes->numOfRows = 0; pRes->numOfRows = 0;
pQueryInfo->slimit.offset -= 1; pQueryInfo->slimit.offset -= 1;
pLocalReducer->discard = !noMoreCurrentGroupRes; pLocalReducer->discard = !noMoreCurrentGroupRes;
if (pLocalReducer->discard) {
SColumnModel *pInternModel = pLocalReducer->pDesc->pColumnModel;
tColModelAppend(pInternModel, pLocalReducer->discardData, pLocalReducer->pTempBuffer->data, 0, 1, 1);
}
return false; return false;
} }
...@@ -1299,7 +1281,7 @@ void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) { // ...@@ -1299,7 +1281,7 @@ void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) { //
static void resetEnvForNewResultset(SSqlRes *pRes, SSqlCmd *pCmd, SLocalReducer *pLocalReducer) { static void resetEnvForNewResultset(SSqlRes *pRes, SSqlCmd *pCmd, SLocalReducer *pLocalReducer) {
// In handling data in other groups, we need to reset the interpolation information for a new group data // In handling data in other groups, we need to reset the interpolation information for a new group data
pRes->numOfRows = 0; pRes->numOfRows = 0;
pRes->numOfClauseTotal = 0; pRes->numOfRowsGroup = 0;
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
...@@ -1363,7 +1345,8 @@ static bool doHandleLastRemainData(SSqlObj *pSql) { ...@@ -1363,7 +1345,8 @@ static bool doHandleLastRemainData(SSqlObj *pSql) {
if ((isAllSourcesCompleted(pLocalReducer) && !pLocalReducer->hasPrevRow) || pLocalReducer->pLocalDataSrc[0] == NULL || if ((isAllSourcesCompleted(pLocalReducer) && !pLocalReducer->hasPrevRow) || pLocalReducer->pLocalDataSrc[0] == NULL ||
prevGroupCompleted) { prevGroupCompleted) {
// if fillType == TSDB_FILL_NONE, return directly // if fillType == TSDB_FILL_NONE, return directly
if (pQueryInfo->fillType != TSDB_FILL_NONE) { if (pQueryInfo->fillType != TSDB_FILL_NONE &&
((pRes->numOfRowsGroup < pQueryInfo->limit.limit && pQueryInfo->limit.limit > 0) || (pQueryInfo->limit.limit < 0))) {
int64_t etime = (pQueryInfo->window.skey < pQueryInfo->window.ekey) ? pQueryInfo->window.ekey : pQueryInfo->window.skey; int64_t etime = (pQueryInfo->window.skey < pQueryInfo->window.ekey) ? pQueryInfo->window.ekey : pQueryInfo->window.skey;
assert(pFillInfo->numOfRows == 0); assert(pFillInfo->numOfRows == 0);
......
...@@ -989,7 +989,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) { ...@@ -989,7 +989,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) {
} }
int validateTableName(char *tblName, int len, SSQLToken* psTblToken) { int validateTableName(char *tblName, int len, SSQLToken* psTblToken) {
tstrncpy(psTblToken->z, tblName, TSDB_TABLE_ID_LEN); tstrncpy(psTblToken->z, tblName, TSDB_TABLE_FNAME_LEN);
psTblToken->n = len; psTblToken->n = len;
psTblToken->type = TK_ID; psTblToken->type = TK_ID;
...@@ -1038,7 +1038,7 @@ int tsParseInsertSql(SSqlObj *pSql) { ...@@ -1038,7 +1038,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
} }
if (NULL == pCmd->pTableList) { if (NULL == pCmd->pTableList) {
pCmd->pTableList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false); pCmd->pTableList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
pCmd->pDataBlocks = taosArrayInit(4, POINTER_BYTES); pCmd->pDataBlocks = taosArrayInit(4, POINTER_BYTES);
if (NULL == pCmd->pTableList || NULL == pSql->cmd.pDataBlocks) { if (NULL == pCmd->pTableList || NULL == pSql->cmd.pDataBlocks) {
code = TSDB_CODE_TSC_OUT_OF_MEMORY; code = TSDB_CODE_TSC_OUT_OF_MEMORY;
...@@ -1077,7 +1077,7 @@ int tsParseInsertSql(SSqlObj *pSql) { ...@@ -1077,7 +1077,7 @@ int tsParseInsertSql(SSqlObj *pSql) {
} }
pCmd->curSql = sToken.z; pCmd->curSql = sToken.z;
char buf[TSDB_TABLE_ID_LEN]; char buf[TSDB_TABLE_FNAME_LEN];
SSQLToken sTblToken; SSQLToken sTblToken;
sTblToken.z = buf; sTblToken.z = buf;
// Check if the table name available or not // Check if the table name available or not
......
...@@ -86,7 +86,7 @@ static int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQueryS ...@@ -86,7 +86,7 @@ static int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQueryS
static int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); static int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo); static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
static int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); static int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
static int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString); static int32_t arithmeticExprToString(tSQLExpr* pExpr, char** exprString);
static int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); static int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type); static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type);
static int32_t validateEp(char* ep); static int32_t validateEp(char* ep);
...@@ -1087,11 +1087,11 @@ int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQL ...@@ -1087,11 +1087,11 @@ int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQL
*xlen = totalLen; *xlen = totalLen;
} }
if (totalLen < TSDB_TABLE_ID_LEN) { if (totalLen < TSDB_TABLE_FNAME_LEN) {
fullName[totalLen] = 0; fullName[totalLen] = 0;
} }
return (totalLen < TSDB_TABLE_ID_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL; return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
} }
static void extractColumnNameFromString(tSQLExprItem* pItem) { static void extractColumnNameFromString(tSQLExprItem* pItem) {
...@@ -1106,23 +1106,138 @@ static void extractColumnNameFromString(tSQLExprItem* pItem) { ...@@ -1106,23 +1106,138 @@ static void extractColumnNameFromString(tSQLExprItem* pItem) {
} }
} }
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
const char* msg1 = "invalid column name, or illegal column type";
const char* msg2 = "invalid arithmetic expression in select clause";
const char* msg3 = "tag columns can not be used in arithmetic expression";
const char* msg4 = "columns from different table mixed up in arithmetic expression";
// arithmetic function in select clause
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
SColumnList columnList = {0};
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
if (validateArithmeticSQLExpr(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
int32_t tableIndex = columnList.ids[0].tableIndex;
// todo potential data overflow
char arithmeticExprStr[1024*12];
char* p = arithmeticExprStr;
if (arithmeticType == NORMAL_ARITHMETIC) {
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
// all columns in arithmetic expression must belong to the same table
for (int32_t f = 1; f < columnList.num; ++f) {
if (columnList.ids[f].tableIndex != tableIndex) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
}
if (arithmeticExprToString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
// expr string is set as the parameter of function
SColumnIndex index = {.tableIndex = tableIndex};
SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double),
sizeof(double), false);
char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
tExprNode* pNode = NULL;
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo->exprList, pQueryInfo, colList);
if (ret != TSDB_CODE_SUCCESS) {
tExprTreeDestroy(&pNode, NULL);
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
size_t numOfNode = taosArrayGetSize(colList);
for(int32_t k = 0; k < numOfNode; ++k) {
SColIndex* pIndex = taosArrayGet(colList, k);
if (pIndex->flag == 1) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
}
SBufferWriter bw = tbufInitWriter(NULL, false);
TRY(0) {
exprTreeToBinary(&bw, pNode);
} CATCH(code) {
tbufCloseWriter(&bw);
UNUSED(code);
// TODO: other error handling
} END_TRY
size_t len = tbufTell(&bw);
char* c = tbufGetData(&bw, true);
// set the serialized binary string as the parameter of arithmetic expression
addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, len, index.tableIndex);
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
taosArrayDestroy(colList);
tExprTreeDestroy(&pNode, NULL);
} else {
if (arithmeticExprToString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
columnList.num = 0;
columnList.ids[0] = (SColumnIndex) {0, 0};
char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, name, NULL);
int32_t slot = tscNumOfFields(pQueryInfo) - 1;
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, slot);
if (pInfo->pSqlExpr == NULL) {
SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo));
// arithmetic expression always return result in the format of double float
pArithExprInfo->bytes = sizeof(double);
pArithExprInfo->interBytes = sizeof(double);
pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE;
int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo->exprList, pQueryInfo, NULL);
if (ret != TSDB_CODE_SUCCESS) {
tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
}
pInfo->pArithExprInfo = pArithExprInfo;
}
}
return TSDB_CODE_SUCCESS;
}
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable) { int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable) {
assert(pSelection != NULL && pCmd != NULL); assert(pSelection != NULL && pCmd != NULL);
const char* msg1 = "invalid column name, or illegal column type";
const char* msg2 = "functions can not be mixed up"; const char* msg2 = "functions can not be mixed up";
const char* msg3 = "not support query expression"; const char* msg3 = "not support query expression";
const char* msg4 = "columns from different table mixed up in arithmetic expression";
const char* msg5 = "invalid function name"; const char* msg5 = "invalid function name";
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
if (pQueryInfo->colList == NULL) { if (pQueryInfo->colList == NULL) {
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
} }
for (int32_t i = 0; i < pSelection->nExpr; ++i) { for (int32_t i = 0; i < pSelection->nExpr; ++i) {
int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); int32_t outputIndex = tscSqlExprNumOfExprs(pQueryInfo);
tSQLExprItem* pItem = &pSelection->a[i]; tSQLExprItem* pItem = &pSelection->a[i];
// project on all fields // project on all fields
...@@ -1147,96 +1262,11 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel ...@@ -1147,96 +1262,11 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
} }
} else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) { } else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
// arithmetic function in select clause int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
SColumnList columnList = {0}; if (code != TSDB_CODE_SUCCESS) {
int32_t arithmeticType = NON_ARITHMEIC_EXPR; return code;
if (validateArithmeticSQLExpr(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
int32_t tableIndex = columnList.ids[0].tableIndex;
char arithmeticExprStr[1024] = {0};
char* p = arithmeticExprStr;
if (arithmeticType == NORMAL_ARITHMETIC) {
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
// all columns in arithmetic expression must belong to the same table
for (int32_t f = 1; f < columnList.num; ++f) {
if (columnList.ids[f].tableIndex != tableIndex) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
}
if (buildArithmeticExprString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
// expr string is set as the parameter of function
SColumnIndex index = {.tableIndex = tableIndex};
SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE,
sizeof(double), sizeof(double), false);
/* todo alias name should use the original sql string */
char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
tExprNode* pNode = NULL;
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo->exprList, pQueryInfo, colList);
if (ret != TSDB_CODE_SUCCESS) {
tExprTreeDestroy(&pNode, NULL);
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid arithmetic expression in select clause");
}
SBufferWriter bw = tbufInitWriter(NULL, false);
TRY(0) {
exprTreeToBinary(&bw, pNode);
} CATCH(code) {
tbufCloseWriter(&bw);
UNUSED(code);
// TODO: other error handling
} END_TRY
size_t len = tbufTell(&bw);
char* c = tbufGetData(&bw, true);
// set the serialized binary string as the parameter of arithmetic expression
addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len, index.tableIndex);
insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
taosArrayDestroy(colList);
tExprTreeDestroy(&pNode, NULL);
} else {
columnList.num = 0;
columnList.ids[0] = (SColumnIndex) {0, 0};
insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, "dummy_column", NULL);
int32_t slot = tscNumOfFields(pQueryInfo) - 1;
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, slot);
if (pInfo->pSqlExpr == NULL) {
SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo));
// arithmetic expression always return result in the format of double float
pArithExprInfo->bytes = sizeof(double);
pArithExprInfo->interBytes = sizeof(double);
pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE;
int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo->exprList, pQueryInfo, NULL);
if (ret != TSDB_CODE_SUCCESS) {
tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
}
pInfo->pArithExprInfo = pArithExprInfo;
}
} }
} else { } else {
/* /*
* not support such expression * not support such expression
...@@ -2106,13 +2136,10 @@ int32_t getTableIndexImpl(SSQLToken* pTableToken, SQueryInfo* pQueryInfo, SColum ...@@ -2106,13 +2136,10 @@ int32_t getTableIndexImpl(SSQLToken* pTableToken, SQueryInfo* pQueryInfo, SColum
} }
pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL; pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
char tableName[TSDB_TABLE_ID_LEN] = {0};
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
extractTableName(pTableMetaInfo->name, tableName); char* name = pTableMetaInfo->aliasName;
if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) {
if (strncasecmp(tableName, pTableToken->z, pTableToken->n) == 0 && strlen(tableName) == pTableToken->n) {
pIndex->tableIndex = i; pIndex->tableIndex = i;
break; break;
} }
...@@ -3081,14 +3108,14 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* ...@@ -3081,14 +3108,14 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr*
} }
// todo error handle / such as and /or mixed with +/-/*/ // todo error handle / such as and /or mixed with +/-/*/
int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) { int32_t doArithmeticExprToString(tSQLExpr* pExpr, char** exprString) {
tSQLExpr* pLeft = pExpr->pLeft; tSQLExpr* pLeft = pExpr->pLeft;
tSQLExpr* pRight = pExpr->pRight; tSQLExpr* pRight = pExpr->pRight;
*(*exprString)++ = '('; *(*exprString)++ = '(';
if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) { if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
buildArithmeticExprString(pLeft, exprString); doArithmeticExprToString(pLeft, exprString);
} else { } else {
int32_t ret = tSQLExprNodeToString(pLeft, exprString); int32_t ret = tSQLExprNodeToString(pLeft, exprString);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
...@@ -3099,7 +3126,7 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) { ...@@ -3099,7 +3126,7 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
optrToString(pExpr, exprString); optrToString(pExpr, exprString);
if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) { if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
buildArithmeticExprString(pRight, exprString); doArithmeticExprToString(pRight, exprString);
} else { } else {
int32_t ret = tSQLExprNodeToString(pRight, exprString); int32_t ret = tSQLExprNodeToString(pRight, exprString);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
...@@ -3112,6 +3139,19 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) { ...@@ -3112,6 +3139,19 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t arithmeticExprToString(tSQLExpr* pExpr, char** str) {
char* start = *str;
int32_t code = doArithmeticExprToString(pExpr, str);
if (code == TSDB_CODE_SUCCESS) { // remove out the parenthesis
int32_t len = strlen(start);
memmove(start, start + 1, len - 2);
start[len - 2] = 0;
}
return code;
}
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) { static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
if (pExpr->nSQLOptr == TK_ID) { if (pExpr->nSQLOptr == TK_ID) {
if (*type == NON_ARITHMEIC_EXPR) { if (*type == NON_ARITHMEIC_EXPR) {
...@@ -3615,7 +3655,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, ...@@ -3615,7 +3655,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1)); SStringBuilder sb1; memset(&sb1, 0, sizeof(sb1));
taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN); taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
char db[TSDB_TABLE_ID_LEN] = {0}; char db[TSDB_TABLE_FNAME_LEN] = {0};
// remove the duplicated input table names // remove the duplicated input table names
int32_t num = 0; int32_t num = 0;
...@@ -3640,7 +3680,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, ...@@ -3640,7 +3680,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1); taosStringBuilderAppendStringLen(&sb1, TBNAME_LIST_SEP, 1);
} }
char idBuf[TSDB_TABLE_ID_LEN] = {0}; char idBuf[TSDB_TABLE_FNAME_LEN] = {0};
int32_t xlen = (int32_t)strlen(segments[i]); int32_t xlen = (int32_t)strlen(segments[i]);
SSQLToken t = {.z = segments[i], .n = xlen, .type = TK_STRING}; SSQLToken t = {.z = segments[i], .n = xlen, .type = TK_STRING};
...@@ -4345,7 +4385,8 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -4345,7 +4385,8 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
const char* msg16 = "only support one column"; const char* msg16 = "only support one column";
const char* msg17 = "invalid column name"; const char* msg17 = "invalid column name";
const char* msg18 = "primary timestamp column cannot be dropped"; const char* msg18 = "primary timestamp column cannot be dropped";
const char* msg19 = "invalid new tag name";
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo; SAlterTableSQL* pAlterSQL = pInfo->pAlterInfo;
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
...@@ -4446,12 +4487,12 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -4446,12 +4487,12 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
SSQLToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING}; SSQLToken srcToken = {.z = pSrcItem->pVar.pz, .n = pSrcItem->pVar.nLen, .type = TK_STRING};
if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) { if (getColumnIndexByName(pCmd, &srcToken, pQueryInfo, &srcIndex) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL; return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg17);
} }
SSQLToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING}; SSQLToken destToken = {.z = pDstItem->pVar.pz, .n = pDstItem->pVar.nLen, .type = TK_STRING};
if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) { if (getColumnIndexByName(pCmd, &destToken, pQueryInfo, &destIndex) == TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL; return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg19);
} }
char name[TSDB_COL_NAME_LEN] = {0}; char name[TSDB_COL_NAME_LEN] = {0};
...@@ -5872,15 +5913,16 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { ...@@ -5872,15 +5913,16 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
assert(pQuerySql != NULL && (pQuerySql->from == NULL || pQuerySql->from->nExpr > 0)); assert(pQuerySql != NULL && (pQuerySql->from == NULL || pQuerySql->from->nExpr > 0));
const char* msg0 = "invalid table name"; const char* msg0 = "invalid table name";
const char* msg1 = "table name too long"; const char* msg1 = "table name too long";
const char* msg2 = "point interpolation query needs timestamp"; const char* msg2 = "point interpolation query needs timestamp";
const char* msg5 = "fill only available for interval query"; const char* msg5 = "fill only available for interval query";
const char* msg6 = "start(end) time of query range required or time range too large"; const char* msg6 = "start(end) time of query range required or time range too large";
const char* msg7 = "illegal number of tables in from clause"; const char* msg7 = "illegal number of tables in from clause";
const char* msg8 = "too many columns in selection clause"; const char* msg8 = "too many columns in selection clause";
const char* msg9 = "TWA query requires both the start and end time"; const char* msg9 = "TWA query requires both the start and end time";
const char* msg10= "too many tables in from clause"; const char* msg10 = "too many tables in from clause";
const char* msg11 = "invalid table alias name";
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
...@@ -5912,18 +5954,18 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { ...@@ -5912,18 +5954,18 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql); return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
} }
if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM) { if (pQuerySql->from->nExpr > TSDB_MAX_JOIN_TABLE_NUM * 2) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
} }
pQueryInfo->command = TSDB_SQL_SELECT; pQueryInfo->command = TSDB_SQL_SELECT;
if (pQuerySql->from->nExpr > 2) { if (pQuerySql->from->nExpr > 4) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
} }
// set all query tables, which are maybe more than one. // set all query tables, which are maybe more than one.
for (int32_t i = 0; i < pQuerySql->from->nExpr; ++i) { for (int32_t i = 0; i < pQuerySql->from->nExpr; ) {
tVariant* pTableItem = &pQuerySql->from->a[i].pVar; tVariant* pTableItem = &pQuerySql->from->a[i].pVar;
if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) { if (pTableItem->nType != TSDB_DATA_TYPE_BINARY) {
...@@ -5937,24 +5979,34 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { ...@@ -5937,24 +5979,34 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
} }
if (pQueryInfo->numOfTables <= i) { // more than one table if (pQueryInfo->numOfTables <= i/2) { // more than one table
tscAddEmptyMetaInfo(pQueryInfo); tscAddEmptyMetaInfo(pQueryInfo);
} }
STableMetaInfo* pMeterInfo1 = tscGetMetaInfo(pQueryInfo, i); STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i/2);
SSQLToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz}; SSQLToken t = {.type = TSDB_DATA_TYPE_BINARY, .n = pTableItem->nLen, .z = pTableItem->pz};
if (tscSetTableFullName(pMeterInfo1, &t, pSql) != TSDB_CODE_SUCCESS) { if (tscSetTableFullName(pTableMetaInfo1, &t, pSql) != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
code = tscGetTableMeta(pSql, pMeterInfo1); tVariant* pTableItem1 = &pQuerySql->from->a[i + 1].pVar;
SSQLToken aliasName = {.z = pTableItem1->pz, .n = pTableItem1->nLen, .type = TK_STRING};
if (tscValidateName(&aliasName) != TSDB_CODE_SUCCESS) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11);
}
tstrncpy(pTableMetaInfo1->aliasName, pTableItem1->pz, sizeof(pTableMetaInfo1->aliasName));
code = tscGetTableMeta(pSql, pTableMetaInfo1);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
i += 2;
} }
assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr); assert(pQueryInfo->numOfTables == pQuerySql->from->nExpr / 2);
bool isSTable = false; bool isSTable = false;
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
...@@ -6122,12 +6174,14 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS ...@@ -6122,12 +6174,14 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
return ret; return ret;
} }
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
int32_t numOfColumns = tscGetNumOfColumns(pTableMeta);
*pExpr = calloc(1, sizeof(tExprNode)); *pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_COL; (*pExpr)->nodeType = TSQL_NODE_COL;
(*pExpr)->pSchema = calloc(1, sizeof(SSchema)); (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
*(*pExpr)->pSchema = *pSchema; *(*pExpr)->pSchema = *pSchema;
...@@ -6136,7 +6190,8 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS ...@@ -6136,7 +6190,8 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name)); tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
colIndex.colId = pSchema->colId; colIndex.colId = pSchema->colId;
colIndex.colIndex = index.columnIndex; colIndex.colIndex = index.columnIndex;
colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;
taosArrayPush(pCols, &colIndex); taosArrayPush(pCols, &colIndex);
} }
......
...@@ -45,19 +45,27 @@ void tscSaveSubscriptionProgress(void* sub); ...@@ -45,19 +45,27 @@ void tscSaveSubscriptionProgress(void* sub);
static int32_t minMsgSize() { return tsRpcHeadSize + 100; } static int32_t minMsgSize() { return tsRpcHeadSize + 100; }
static void tscSetDnodeEpSet(SSqlObj* pSql, SCMVgroupInfo* pVgroupInfo) { static void tscSetDnodeEpSet(SSqlObj* pSql, SCMVgroupInfo* pVgroupInfo) {
assert(pSql != NULL && pVgroupInfo != NULL && pVgroupInfo->numOfEps > 0);
SRpcEpSet* pEpSet = &pSql->epSet; SRpcEpSet* pEpSet = &pSql->epSet;
pEpSet->inUse = 0; pEpSet->inUse = 0;
if (pVgroupInfo == NULL) {
pEpSet->numOfEps = 0; // apply the FQDN string length check here
return; bool hasFqdn = false;
}
pEpSet->numOfEps = pVgroupInfo->numOfEps; pEpSet->numOfEps = pVgroupInfo->numOfEps;
for(int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) { for(int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) {
strcpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn); strcpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn);
pEpSet->port[i] = pVgroupInfo->epAddr[i].port; pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
if (!hasFqdn) {
hasFqdn = (strlen(pEpSet->fqdn[i]) > 0);
}
} }
assert(hasFqdn);
} }
static void tscDumpMgmtEpSet(SRpcEpSet *epSet) { static void tscDumpMgmtEpSet(SRpcEpSet *epSet) {
taosCorBeginRead(&tscMgmtEpSet.version); taosCorBeginRead(&tscMgmtEpSet.version);
*epSet = tscMgmtEpSet.epSet; *epSet = tscMgmtEpSet.epSet;
...@@ -127,21 +135,6 @@ void tscPrintMgmtEp() { ...@@ -127,21 +135,6 @@ void tscPrintMgmtEp() {
} }
} }
/*
* For each management node, try twice at least in case of poor network situation.
* If the client start to connect to a non-management node from the client, and the first retry may fail due to
* the poor network quality. And then, the second retry get the response with redirection command.
* The retry will not be executed since only *two* retry is allowed in case of single management node in the cluster.
* Therefore, we need to multiply the retry times by factor of 2 to fix this problem.
*/
UNUSED_FUNC
static int32_t tscGetMgmtConnMaxRetryTimes() {
int32_t factor = 2;
SRpcEpSet dump;
tscDumpMgmtEpSet(&dump);
return dump.numOfEps * factor;
}
void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) { void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
STscObj *pObj = (STscObj *)param; STscObj *pObj = (STscObj *)param;
if (pObj == NULL) return; if (pObj == NULL) return;
...@@ -424,21 +417,18 @@ int doProcessSql(SSqlObj *pSql) { ...@@ -424,21 +417,18 @@ int doProcessSql(SSqlObj *pSql) {
} }
int tscProcessSql(SSqlObj *pSql) { int tscProcessSql(SSqlObj *pSql) {
char * name = NULL; char *name = NULL;
SSqlCmd *pCmd = &pSql->cmd; SSqlCmd *pCmd = &pSql->cmd;
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
STableMetaInfo *pTableMetaInfo = NULL; STableMetaInfo *pTableMetaInfo = NULL;
uint32_t type = 0; uint32_t type = 0;
if (pQueryInfo != NULL) { if (pQueryInfo != NULL) {
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if (pTableMetaInfo != NULL) { name = (pTableMetaInfo != NULL)? pTableMetaInfo->name:NULL;
name = pTableMetaInfo->name;
}
type = pQueryInfo->type; type = pQueryInfo->type;
// while numOfTables equals to 0, it must be Heartbeat // while numOfTables equals to 0, it must be Heartbeat
assert((pQueryInfo->numOfTables == 0 && pQueryInfo->command == TSDB_SQL_HB) || pQueryInfo->numOfTables > 0); assert((pQueryInfo->numOfTables == 0 && pQueryInfo->command == TSDB_SQL_HB) || pQueryInfo->numOfTables > 0);
} }
...@@ -450,7 +440,6 @@ int tscProcessSql(SSqlObj *pSql) { ...@@ -450,7 +440,6 @@ int tscProcessSql(SSqlObj *pSql) {
return pSql->res.code; return pSql->res.code;
} }
} else if (pCmd->command < TSDB_SQL_LOCAL) { } else if (pCmd->command < TSDB_SQL_LOCAL) {
//pSql->epSet = tscMgmtEpSet; //pSql->epSet = tscMgmtEpSet;
} else { // local handler } else { // local handler
return (*tscProcessMsgRsp[pCmd->command])(pSql); return (*tscProcessMsgRsp[pCmd->command])(pSql);
...@@ -597,11 +586,11 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char ...@@ -597,11 +586,11 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
} else { } else {
pVgroupInfo = &pTableMeta->vgroupInfo; pVgroupInfo = &pTableMeta->vgroupInfo;
} }
tscSetDnodeEpSet(pSql, pVgroupInfo);
if (pVgroupInfo != NULL) { assert(pVgroupInfo != NULL);
pQueryMsg->head.vgId = htonl(pVgroupInfo->vgId);
} tscSetDnodeEpSet(pSql, pVgroupInfo);
pQueryMsg->head.vgId = htonl(pVgroupInfo->vgId);
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg; STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
pTableIdInfo->tid = htonl(pTableMeta->id.tid); pTableIdInfo->tid = htonl(pTableMeta->id.tid);
...@@ -1460,7 +1449,7 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) { ...@@ -1460,7 +1449,7 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) { if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) {
tscSetResultPointer(pQueryInfo, pRes); tscCreateResPointerInfo(pRes, pQueryInfo);
} }
pRes->row = 0; pRes->row = 0;
...@@ -1562,7 +1551,7 @@ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { ...@@ -1562,7 +1551,7 @@ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
// fill head info // fill head info
SMgmtHead *pMgmt = (SMgmtHead *)(pCmd->payload + tsRpcHeadSize); SMgmtHead *pMgmt = (SMgmtHead *)(pCmd->payload + tsRpcHeadSize);
memset(pMgmt->db, 0, TSDB_TABLE_ID_LEN); // server don't need the db memset(pMgmt->db, 0, TSDB_TABLE_FNAME_LEN); // server don't need the db
SCMMultiTableInfoMsg *pInfoMsg = (SCMMultiTableInfoMsg *)(pCmd->payload + tsRpcHeadSize + sizeof(SMgmtHead)); SCMMultiTableInfoMsg *pInfoMsg = (SCMMultiTableInfoMsg *)(pCmd->payload + tsRpcHeadSize + sizeof(SMgmtHead));
pInfoMsg->numOfTables = htonl((int32_t)pCmd->count); pInfoMsg->numOfTables = htonl((int32_t)pCmd->count);
...@@ -1603,7 +1592,7 @@ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { ...@@ -1603,7 +1592,7 @@ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
//// tagLen += strlen(pQueryInfo->tagCond.tbnameCond.cond) * TSDB_NCHAR_SIZE; //// tagLen += strlen(pQueryInfo->tagCond.tbnameCond.cond) * TSDB_NCHAR_SIZE;
//// } //// }
//// ////
//// int32_t joinCondLen = (TSDB_TABLE_ID_LEN + sizeof(int16_t)) * 2; //// int32_t joinCondLen = (TSDB_TABLE_FNAME_LEN + sizeof(int16_t)) * 2;
//// int32_t elemSize = sizeof(SSuperTableMetaElemMsg) * pQueryInfo->numOfTables; //// int32_t elemSize = sizeof(SSuperTableMetaElemMsg) * pQueryInfo->numOfTables;
//// ////
//// int32_t colSize = pQueryInfo->groupbyExpr.numOfGroupCols*sizeof(SColIndex); //// int32_t colSize = pQueryInfo->groupbyExpr.numOfGroupCols*sizeof(SColIndex);
...@@ -1884,11 +1873,10 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) { ...@@ -1884,11 +1873,10 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
for (int32_t k = 0; k < pVgroups->numOfEps; ++k) { for (int32_t k = 0; k < pVgroups->numOfEps; ++k) {
pVgroups->epAddr[k].port = htons(pVgroups->epAddr[k].port); pVgroups->epAddr[k].port = htons(pVgroups->epAddr[k].port);
} }
pMsg += size;
} }
pMsg += size;
} }
return pSql->res.code; return pSql->res.code;
...@@ -1966,7 +1954,7 @@ int tscProcessShowRsp(SSqlObj *pSql) { ...@@ -1966,7 +1954,7 @@ int tscProcessShowRsp(SSqlObj *pSql) {
} }
int tscProcessConnectRsp(SSqlObj *pSql) { int tscProcessConnectRsp(SSqlObj *pSql) {
char temp[TSDB_TABLE_ID_LEN * 2]; char temp[TSDB_TABLE_FNAME_LEN * 2];
STscObj *pObj = pSql->pTscObj; STscObj *pObj = pSql->pTscObj;
SSqlRes *pRes = &pSql->res; SSqlRes *pRes = &pSql->res;
...@@ -2114,21 +2102,6 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { ...@@ -2114,21 +2102,6 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
return 0; return 0;
} }
int tscProcessRetrieveRspFromLocal(SSqlObj *pSql) {
SSqlRes * pRes = &pSql->res;
SSqlCmd * pCmd = &pSql->cmd;
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
SRetrieveTableRsp *pRetrieve = (SRetrieveTableRsp *)pRes->pRsp;
pRes->numOfRows = htonl(pRetrieve->numOfRows);
pRes->data = pRetrieve->data;
tscSetResultPointer(pQueryInfo, pRes);
pRes->row = 0;
return 0;
}
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code); void tscTableMetaCallBack(void *param, TAOS_RES *res, int code);
static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) { static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
......
...@@ -233,35 +233,6 @@ static void waitForRetrieveRsp(void *param, TAOS_RES *tres, int numOfRows) { ...@@ -233,35 +233,6 @@ static void waitForRetrieveRsp(void *param, TAOS_RES *tres, int numOfRows) {
sem_post(&pSql->rspSem); sem_post(&pSql->rspSem);
} }
TAOS_RES* taos_query(TAOS *taos, const char *sqlstr) {
STscObj *pObj = (STscObj *)taos;
if (pObj == NULL || pObj->signature != pObj) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
return NULL;
}
int32_t sqlLen = (int32_t)strlen(sqlstr);
if (sqlLen > tsMaxSQLStringLen) {
tscError("sql string exceeds max length:%d", tsMaxSQLStringLen);
terrno = TSDB_CODE_TSC_INVALID_SQL;
return NULL;
}
taosNotePrintTsc(sqlstr);
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
if (pSql == NULL) {
tscError("failed to malloc sqlObj");
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
return NULL;
}
doAsyncQuery(pObj, pSql, waitForQueryRsp, taos, sqlstr, sqlLen);
// wait for the callback function to post the semaphore
tsem_wait(&pSql->rspSem);
return pSql;
}
TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) { TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) {
STscObj *pObj = (STscObj *)taos; STscObj *pObj = (STscObj *)taos;
if (pObj == NULL || pObj->signature != pObj) { if (pObj == NULL || pObj->signature != pObj) {
...@@ -274,7 +245,9 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) { ...@@ -274,7 +245,9 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) {
terrno = TSDB_CODE_TSC_INVALID_SQL; terrno = TSDB_CODE_TSC_INVALID_SQL;
return NULL; return NULL;
} }
taosNotePrintTsc(sqlstr);
SSqlObj* pSql = calloc(1, sizeof(SSqlObj)); SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
if (pSql == NULL) { if (pSql == NULL) {
tscError("failed to malloc sqlObj"); tscError("failed to malloc sqlObj");
...@@ -287,6 +260,11 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) { ...@@ -287,6 +260,11 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen) {
tsem_wait(&pSql->rspSem); tsem_wait(&pSql->rspSem);
return pSql; return pSql;
} }
TAOS_RES* taos_query(TAOS *taos, const char *sqlstr) {
return taos_query_c(taos, sqlstr, strlen(sqlstr));
}
int taos_result_precision(TAOS_RES *res) { int taos_result_precision(TAOS_RES *res) {
SSqlObj *pSql = (SSqlObj *)res; SSqlObj *pSql = (SSqlObj *)res;
if (pSql == NULL || pSql->signature != pSql) return 0; if (pSql == NULL || pSql->signature != pSql) return 0;
...@@ -422,7 +400,10 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) { ...@@ -422,7 +400,10 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
pCmd->command == TSDB_SQL_INSERT) { pCmd->command == TSDB_SQL_INSERT) {
return NULL; return NULL;
} }
// set the sql object owner
tscSetSqlOwner(pSql);
// current data set are exhausted, fetch more data from node // current data set are exhausted, fetch more data from node
if (pRes->row >= pRes->numOfRows && (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) && if (pRes->row >= pRes->numOfRows && (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) &&
(pCmd->command == TSDB_SQL_RETRIEVE || (pCmd->command == TSDB_SQL_RETRIEVE ||
...@@ -441,7 +422,10 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) { ...@@ -441,7 +422,10 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
sem_wait(&pSql->rspSem); sem_wait(&pSql->rspSem);
} }
return doSetResultRowData(pSql, true); void* data = doSetResultRowData(pSql, true);
tscClearSqlOwner(pSql);
return data;
} }
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) { int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
...@@ -509,7 +493,7 @@ int taos_select_db(TAOS *taos, const char *db) { ...@@ -509,7 +493,7 @@ int taos_select_db(TAOS *taos, const char *db) {
} }
// send free message to vnode to free qhandle and corresponding resources in vnode // send free message to vnode to free qhandle and corresponding resources in vnode
static bool tscFreeQhandleInVnode(SSqlObj* pSql) { static bool tscKillQueryInVnode(SSqlObj* pSql) {
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
SSqlRes* pRes = &pSql->res; SSqlRes* pRes = &pSql->res;
...@@ -557,16 +541,14 @@ void taos_free_result(TAOS_RES *res) { ...@@ -557,16 +541,14 @@ void taos_free_result(TAOS_RES *res) {
} }
pQueryInfo->type = TSDB_QUERY_TYPE_FREE_RESOURCE; pQueryInfo->type = TSDB_QUERY_TYPE_FREE_RESOURCE;
if (!tscFreeQhandleInVnode(pSql)) { if (!tscKillQueryInVnode(pSql)) {
tscFreeSqlObj(pSql); tscFreeSqlObj(pSql);
tscDebug("%p sqlObj is freed by app", pSql); tscDebug("%p sqlObj is freed by app", pSql);
} }
} }
// todo should not be used in async query
int taos_errno(TAOS_RES *tres) { int taos_errno(TAOS_RES *tres) {
SSqlObj *pSql = (SSqlObj *) tres; SSqlObj *pSql = (SSqlObj *) tres;
if (pSql == NULL || pSql->signature != pSql) { if (pSql == NULL || pSql->signature != pSql) {
return terrno; return terrno;
} }
...@@ -812,7 +794,7 @@ static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t t ...@@ -812,7 +794,7 @@ static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t t
} }
char *nextStr; char *nextStr;
char tblName[TSDB_TABLE_ID_LEN]; char tblName[TSDB_TABLE_FNAME_LEN];
int payloadLen = 0; int payloadLen = 0;
char *pMsg = pCmd->payload; char *pMsg = pCmd->payload;
while (1) { while (1) {
......
...@@ -1026,9 +1026,11 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { ...@@ -1026,9 +1026,11 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) {
} }
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
pRes->pColumnIndex = calloc(1, sizeof(SColumnIndex) * pQueryInfo->fieldsInfo.numOfOutput);
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { int32_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
pRes->pColumnIndex = calloc(1, sizeof(SColumnIndex) * numOfExprs);
for (int32_t i = 0; i < numOfExprs; ++i) {
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
int32_t tableIndexOfSub = -1; int32_t tableIndexOfSub = -1;
...@@ -1045,8 +1047,8 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { ...@@ -1045,8 +1047,8 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) {
SSqlCmd* pSubCmd = &pSql->pSubs[tableIndexOfSub]->cmd; SSqlCmd* pSubCmd = &pSql->pSubs[tableIndexOfSub]->cmd;
SQueryInfo* pSubQueryInfo = tscGetQueryInfoDetail(pSubCmd, 0); SQueryInfo* pSubQueryInfo = tscGetQueryInfoDetail(pSubCmd, 0);
size_t numOfExprs = taosArrayGetSize(pSubQueryInfo->exprList); size_t numOfSubExpr = taosArrayGetSize(pSubQueryInfo->exprList);
for (int32_t k = 0; k < numOfExprs; ++k) { for (int32_t k = 0; k < numOfSubExpr; ++k) {
SSqlExpr* pSubExpr = tscSqlExprGet(pSubQueryInfo, k); SSqlExpr* pSubExpr = tscSqlExprGet(pSubQueryInfo, k);
if (pExpr->functionId == pSubExpr->functionId && pExpr->colInfo.colId == pSubExpr->colInfo.colId) { if (pExpr->functionId == pSubExpr->functionId && pExpr->colInfo.colId == pSubExpr->colInfo.colId) {
pRes->pColumnIndex[i] = (SColumnIndex){.tableIndex = tableIndexOfSub, .columnIndex = k}; pRes->pColumnIndex[i] = (SColumnIndex){.tableIndex = tableIndexOfSub, .columnIndex = k};
...@@ -1054,6 +1056,10 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { ...@@ -1054,6 +1056,10 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) {
} }
} }
} }
// restore the offset value for super table query in case of final result.
tscRestoreSQLFuncForSTableQuery(pQueryInfo);
tscFieldInfoUpdateOffset(pQueryInfo);
} }
void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
...@@ -1079,7 +1085,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { ...@@ -1079,7 +1085,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
if (taos_errno(pSql) != TSDB_CODE_SUCCESS) { if (taos_errno(pSql) != TSDB_CODE_SUCCESS) {
assert(taos_errno(pSql) == code); assert(taos_errno(pSql) == code);
tscError("%p abort query, code:%d, global code:%d", pSql, code, pParentSql->res.code); tscError("%p abort query, code:%s, global code:%s", pSql, tstrerror(code), tstrerror(pParentSql->res.code));
pParentSql->res.code = code; pParentSql->res.code = code;
quitAllSubquery(pParentSql, pSupporter); quitAllSubquery(pParentSql, pSupporter);
...@@ -2052,9 +2058,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { ...@@ -2052,9 +2058,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
} }
while (1) { while (1) {
if (pRes->row < pRes->numOfRows) { assert (pRes->row >= pRes->numOfRows);
assert(0);
}
doBuildResFromSubqueries(pSql); doBuildResFromSubqueries(pSql);
sem_post(&pSql->rspSem); sem_post(&pSql->rspSem);
......
...@@ -644,7 +644,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SArray* pTableDataBlockList) { ...@@ -644,7 +644,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SArray* pTableDataBlockList) {
STableDataBlocks* pOneTableBlock = taosArrayGetP(pTableDataBlockList, 0); STableDataBlocks* pOneTableBlock = taosArrayGetP(pTableDataBlockList, 0);
int32_t expandSize = getRowExpandSize(pOneTableBlock->pTableMeta); int32_t expandSize = getRowExpandSize(pOneTableBlock->pTableMeta);
void* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false); void* pVnodeDataBlockHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
SArray* pVnodeDataBlockList = taosArrayInit(8, POINTER_BYTES); SArray* pVnodeDataBlockList = taosArrayInit(8, POINTER_BYTES);
size_t total = taosArrayGetSize(pTableDataBlockList); size_t total = taosArrayGetSize(pTableDataBlockList);
...@@ -858,12 +858,13 @@ void tscFieldInfoCopy(SFieldInfo* dst, const SFieldInfo* src) { ...@@ -858,12 +858,13 @@ void tscFieldInfoCopy(SFieldInfo* dst, const SFieldInfo* src) {
} }
TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) { TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) {
assert(index < pFieldInfo->numOfOutput);
return TARRAY_GET_ELEM(pFieldInfo->pFields, index); return TARRAY_GET_ELEM(pFieldInfo->pFields, index);
} }
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) { int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, index); SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, index);
assert(pInfo != NULL); assert(pInfo != NULL && pInfo->pSqlExpr != NULL);
return pInfo->pSqlExpr->offset; return pInfo->pSqlExpr->offset;
} }
...@@ -1680,6 +1681,77 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cm ...@@ -1680,6 +1681,77 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cm
return pNew; return pNew;
} }
// current sql function is not direct output result, so create a dummy output field
static void doSetNewFieldInfo(SQueryInfo* pNewQueryInfo, SSqlExpr* pExpr) {
TAOS_FIELD f = {.type = pExpr->resType, .bytes = pExpr->resBytes};
tstrncpy(f.name, pExpr->aliasName, sizeof(f.name));
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, &f);
pInfo1->pSqlExpr = pExpr;
pInfo1->visible = false;
}
static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pQueryInfo, SQueryInfo* pNewQueryInfo, int64_t uid) {
int32_t numOfOutput = tscSqlExprNumOfExprs(pNewQueryInfo);
if (numOfOutput == 0) {
return;
}
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo;
// set the field info in pNewQueryInfo object
for (int32_t i = 0; i < numOfExprs; ++i) {
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
if (pExpr->uid == uid) {
if (i < pFieldInfo->numOfOutput) {
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, i);
if (pInfo->pSqlExpr != NULL) {
TAOS_FIELD* p = tscFieldInfoGetField(pFieldInfo, i);
assert(strcmp(p->name, pExpr->aliasName) == 0);
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, p);
*pInfo1 = *pInfo;
} else {
assert(pInfo->pArithExprInfo != NULL);
doSetNewFieldInfo(pNewQueryInfo, pExpr);
}
} else { // it is a arithmetic column, does not have actual field for sqlExpr, so build it
doSetNewFieldInfo(pNewQueryInfo, pExpr);
}
}
}
// make sure the the sqlExpr for each fields is correct
numOfExprs = tscSqlExprNumOfExprs(pNewQueryInfo);
// update the pSqlExpr pointer in SFieldSupInfo according the field name
// make sure the pSqlExpr point to the correct SqlExpr in pNewQueryInfo, not SqlExpr in pQueryInfo
for (int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutput; ++f) {
TAOS_FIELD* field = tscFieldInfoGetField(&pNewQueryInfo->fieldsInfo, f);
bool matched = false;
for (int32_t k1 = 0; k1 < numOfExprs; ++k1) {
SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1);
if (strcmp(field->name, pExpr1->aliasName) == 0) { // establish link according to the result field name
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pNewQueryInfo->fieldsInfo, f);
pInfo->pSqlExpr = pExpr1;
matched = true;
break;
}
}
assert(matched);
}
tscFieldInfoUpdateOffset(pNewQueryInfo);
}
SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void* param, int32_t cmd, SSqlObj* pPrevSql) { SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void* param, int32_t cmd, SSqlObj* pPrevSql) {
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
SSqlObj* pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj)); SSqlObj* pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj));
...@@ -1773,49 +1845,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void ...@@ -1773,49 +1845,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; uint64_t uid = pTableMetaInfo->pTableMeta->id.uid;
tscSqlExprCopy(pNewQueryInfo->exprList, pQueryInfo->exprList, uid, true); tscSqlExprCopy(pNewQueryInfo->exprList, pQueryInfo->exprList, uid, true);
int32_t numOfOutput = (int32_t)tscSqlExprNumOfExprs(pNewQueryInfo); doSetSqlExprAndResultFieldInfo(pQueryInfo, pNewQueryInfo, uid);
if (numOfOutput > 0) { // todo refactor to extract method
size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo;
for (int32_t i = 0; i < numOfExprs; ++i) {
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
if (pExpr->uid == uid) {
TAOS_FIELD* p = tscFieldInfoGetField(pFieldInfo, i);
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, i);
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, p);
*pInfo1 = *pInfo;
}
}
// make sure the the sqlExpr for each fields is correct
// todo handle the agg arithmetic expression
numOfExprs = tscSqlExprNumOfExprs(pNewQueryInfo);
for(int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutput; ++f) {
TAOS_FIELD* field = tscFieldInfoGetField(&pNewQueryInfo->fieldsInfo, f);
bool matched = false;
for(int32_t k1 = 0; k1 < numOfExprs; ++k1) {
SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1);
if (strcmp(field->name, pExpr1->aliasName) == 0) { // establish link according to the result field name
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pNewQueryInfo->fieldsInfo, f);
pInfo->pSqlExpr = pExpr1;
matched = true;
break;
}
}
assert(matched);
}
tscFieldInfoUpdateOffset(pNewQueryInfo);
}
pNew->fp = fp; pNew->fp = fp;
pNew->fetchFp = fp; pNew->fetchFp = fp;
...@@ -2013,6 +2043,10 @@ bool hasMoreVnodesToTry(SSqlObj* pSql) { ...@@ -2013,6 +2043,10 @@ bool hasMoreVnodesToTry(SSqlObj* pSql) {
} }
int32_t numOfVgroups = pTableMetaInfo->vgroupList->numOfVgroups; int32_t numOfVgroups = pTableMetaInfo->vgroupList->numOfVgroups;
if (pTableMetaInfo->pVgroupTables != NULL) {
numOfVgroups = taosArrayGetSize(pTableMetaInfo->pVgroupTables);
}
return tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && return tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
(!tscHasReachLimitation(pQueryInfo, pRes)) && (pTableMetaInfo->vgroupIndex < numOfVgroups - 1); (!tscHasReachLimitation(pQueryInfo, pRes)) && (pTableMetaInfo->vgroupIndex < numOfVgroups - 1);
} }
...@@ -2200,3 +2234,21 @@ int tscSetMgmtEpSetFromCfg(const char *first, const char *second) { ...@@ -2200,3 +2234,21 @@ int tscSetMgmtEpSetFromCfg(const char *first, const char *second) {
return 0; return 0;
} }
bool tscSetSqlOwner(SSqlObj* pSql) {
SSqlRes* pRes = &pSql->res;
// set the sql object owner
uint64_t threadId = taosGetPthreadId();
if (atomic_val_compare_exchange_64(&pSql->owner, 0, threadId) != 0) {
pRes->code = TSDB_CODE_QRY_IN_EXEC;
return false;
}
return true;
}
void tscClearSqlOwner(SSqlObj* pSql) {
assert(pSql->owner != 0);
atomic_store_64(&pSql->owner, 0);
}
\ No newline at end of file
...@@ -202,8 +202,9 @@ static void *dnodeProcessReadQueue(void *param) { ...@@ -202,8 +202,9 @@ static void *dnodeProcessReadQueue(void *param) {
break; break;
} }
dDebug("%p, msg:%s will be processed in vread queue, qtype:%d", pReadMsg->rpcMsg.ahandle, dDebug("%p, msg:%s will be processed in vread queue, qtype:%d, msg:%p", pReadMsg->rpcMsg.ahandle,
taosMsg[pReadMsg->rpcMsg.msgType], type); taosMsg[pReadMsg->rpcMsg.msgType], type, pReadMsg);
int32_t code = vnodeProcessRead(pVnode, pReadMsg); int32_t code = vnodeProcessRead(pVnode, pReadMsg);
if (type == TAOS_QTYPE_RPC && code != TSDB_CODE_QRY_NOT_READY) { if (type == TAOS_QTYPE_RPC && code != TSDB_CODE_QRY_NOT_READY) {
......
...@@ -76,6 +76,9 @@ void* qGetResultRetrieveMsg(qinfo_t qinfo); ...@@ -76,6 +76,9 @@ void* qGetResultRetrieveMsg(qinfo_t qinfo);
*/ */
int32_t qKillQuery(qinfo_t qinfo); int32_t qKillQuery(qinfo_t qinfo);
int32_t qQueryCompleted(qinfo_t qinfo);
/** /**
* destroy query info structure * destroy query info structure
* @param qHandle * @param qHandle
......
...@@ -232,7 +232,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size); ...@@ -232,7 +232,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
#define TSDB_NODE_NAME_LEN 64 #define TSDB_NODE_NAME_LEN 64
#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string #define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string
#define TSDB_DB_NAME_LEN 33 #define TSDB_DB_NAME_LEN 33
#define TSDB_TABLE_ID_LEN (TSDB_ACCT_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN) #define TSDB_TABLE_FNAME_LEN (TSDB_ACCT_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN)
#define TSDB_COL_NAME_LEN 65 #define TSDB_COL_NAME_LEN 65
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64 #define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE #define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
......
...@@ -219,6 +219,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_DUP_JOIN_KEY, 0, 0x0705, "Duplicated ...@@ -219,6 +219,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_DUP_JOIN_KEY, 0, 0x0705, "Duplicated
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_EXCEED_TAGS_LIMIT, 0, 0x0706, "Tag conditon too many") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_EXCEED_TAGS_LIMIT, 0, 0x0706, "Tag conditon too many")
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_NOT_READY, 0, 0x0707, "Query not ready") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_NOT_READY, 0, 0x0707, "Query not ready")
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_HAS_RSP, 0, 0x0708, "Query should response") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_HAS_RSP, 0, 0x0708, "Query should response")
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_IN_EXEC, 0, 0x0709, "Multiple retrieval of this query")
// grant // grant
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, 0, 0x0800, "License expired") TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, 0, 0x0800, "License expired")
......
...@@ -246,13 +246,13 @@ typedef struct { ...@@ -246,13 +246,13 @@ typedef struct {
uint64_t uid; uint64_t uid;
uint64_t superTableUid; uint64_t superTableUid;
uint64_t createdTime; uint64_t createdTime;
char tableId[TSDB_TABLE_ID_LEN]; char tableId[TSDB_TABLE_FNAME_LEN];
char superTableId[TSDB_TABLE_ID_LEN]; char superTableId[TSDB_TABLE_FNAME_LEN];
char data[]; char data[];
} SMDCreateTableMsg; } SMDCreateTableMsg;
typedef struct { typedef struct {
char tableId[TSDB_TABLE_ID_LEN]; char tableId[TSDB_TABLE_FNAME_LEN];
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
int8_t igExists; int8_t igExists;
int8_t getMeta; int8_t getMeta;
...@@ -265,12 +265,12 @@ typedef struct { ...@@ -265,12 +265,12 @@ typedef struct {
} SCMCreateTableMsg; } SCMCreateTableMsg;
typedef struct { typedef struct {
char tableId[TSDB_TABLE_ID_LEN]; char tableId[TSDB_TABLE_FNAME_LEN];
int8_t igNotExists; int8_t igNotExists;
} SCMDropTableMsg; } SCMDropTableMsg;
typedef struct { typedef struct {
char tableId[TSDB_TABLE_ID_LEN]; char tableId[TSDB_TABLE_FNAME_LEN];
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
int16_t type; /* operation type */ int16_t type; /* operation type */
int16_t numOfCols; /* number of schema */ int16_t numOfCols; /* number of schema */
...@@ -297,7 +297,7 @@ typedef struct { ...@@ -297,7 +297,7 @@ typedef struct {
typedef struct { typedef struct {
char clientVersion[TSDB_VERSION_LEN]; char clientVersion[TSDB_VERSION_LEN];
char msgVersion[TSDB_VERSION_LEN]; char msgVersion[TSDB_VERSION_LEN];
char db[TSDB_TABLE_ID_LEN]; char db[TSDB_TABLE_FNAME_LEN];
} SCMConnectMsg; } SCMConnectMsg;
typedef struct { typedef struct {
...@@ -347,14 +347,14 @@ typedef struct { ...@@ -347,14 +347,14 @@ typedef struct {
int32_t vgId; int32_t vgId;
int32_t sid; int32_t sid;
uint64_t uid; uint64_t uid;
char tableId[TSDB_TABLE_ID_LEN]; char tableId[TSDB_TABLE_FNAME_LEN];
} SMDDropTableMsg; } SMDDropTableMsg;
typedef struct { typedef struct {
int32_t contLen; int32_t contLen;
int32_t vgId; int32_t vgId;
uint64_t uid; uint64_t uid;
char tableId[TSDB_TABLE_ID_LEN]; char tableId[TSDB_TABLE_FNAME_LEN];
} SMDDropSTableMsg; } SMDDropSTableMsg;
typedef struct { typedef struct {
...@@ -527,7 +527,7 @@ typedef struct { ...@@ -527,7 +527,7 @@ typedef struct {
} SCMCreateDbMsg, SCMAlterDbMsg; } SCMCreateDbMsg, SCMAlterDbMsg;
typedef struct { typedef struct {
char db[TSDB_TABLE_ID_LEN]; char db[TSDB_TABLE_FNAME_LEN];
uint8_t ignoreNotExists; uint8_t ignoreNotExists;
} SCMDropDbMsg, SCMUseDbMsg; } SCMDropDbMsg, SCMUseDbMsg;
...@@ -637,7 +637,7 @@ typedef struct { ...@@ -637,7 +637,7 @@ typedef struct {
} SMDCreateVnodeMsg, SMDAlterVnodeMsg; } SMDCreateVnodeMsg, SMDAlterVnodeMsg;
typedef struct { typedef struct {
char tableId[TSDB_TABLE_ID_LEN]; char tableId[TSDB_TABLE_FNAME_LEN];
int16_t createFlag; int16_t createFlag;
char tags[]; char tags[];
} SCMTableInfoMsg; } SCMTableInfoMsg;
...@@ -664,7 +664,7 @@ typedef struct { ...@@ -664,7 +664,7 @@ typedef struct {
typedef struct STableMetaMsg { typedef struct STableMetaMsg {
int32_t contLen; int32_t contLen;
char tableId[TSDB_TABLE_ID_LEN]; // table id char tableId[TSDB_TABLE_FNAME_LEN]; // table id
uint8_t numOfTags; uint8_t numOfTags;
uint8_t precision; uint8_t precision;
uint8_t tableType; uint8_t tableType;
...@@ -685,7 +685,7 @@ typedef struct SMultiTableMeta { ...@@ -685,7 +685,7 @@ typedef struct SMultiTableMeta {
typedef struct { typedef struct {
int32_t dataLen; int32_t dataLen;
char name[TSDB_TABLE_ID_LEN]; char name[TSDB_TABLE_FNAME_LEN];
char data[TSDB_MAX_TAGS_LEN + TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * TSDB_MAX_TAGS]; char data[TSDB_MAX_TAGS_LEN + TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * TSDB_MAX_TAGS];
} STagData; } STagData;
...@@ -771,7 +771,7 @@ typedef struct { ...@@ -771,7 +771,7 @@ typedef struct {
uint64_t uid; uint64_t uid;
uint64_t stime; // stream starting time uint64_t stime; // stream starting time
int32_t status; int32_t status;
char tableId[TSDB_TABLE_ID_LEN]; char tableId[TSDB_TABLE_FNAME_LEN];
} SMDAlterStreamMsg; } SMDAlterStreamMsg;
typedef struct { typedef struct {
......
...@@ -167,9 +167,14 @@ typedef struct SDataBlockInfo { ...@@ -167,9 +167,14 @@ typedef struct SDataBlockInfo {
} SDataBlockInfo; } SDataBlockInfo;
typedef struct { typedef struct {
size_t numOfTables; void *pTable;
TSKEY lastKey;
} STableKeyInfo;
typedef struct {
size_t numOfTables;
SArray *pGroupList; SArray *pGroupList;
SHashObj *map; // speedup acquire the tableQueryInfo from STableId SHashObj *map; // speedup acquire the tableQueryInfo by table uid
} STableGroupInfo; } STableGroupInfo;
/** /**
...@@ -177,24 +182,24 @@ typedef struct { ...@@ -177,24 +182,24 @@ typedef struct {
* *
* @param tsdb tsdb handle * @param tsdb tsdb handle
* @param pCond query condition, including time window, result set order, and basic required columns for each block * @param pCond query condition, including time window, result set order, and basic required columns for each block
* @param tableqinfoGroupInfo tableId list in the form of set, seperated into different groups according to group by condition * @param tableInfoGroup table object list in the form of set, grouped into different sets according to the
* group by condition
* @param qinfo query info handle from query processor * @param qinfo query info handle from query processor
* @return * @return
*/ */
TsdbQueryHandleT *tsdbQueryTables(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableqinfoGroupInfo, void *qinfo); TsdbQueryHandleT *tsdbQueryTables(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfoGroup, void *qinfo);
/** /**
* Get the last row of the given query time window for all the tables in STableGroupInfo object. * Get the last row of the given query time window for all the tables in STableGroupInfo object.
* Note that only one data block with only row will be returned while invoking retrieve data block function for * Note that only one data block with only row will be returned while invoking retrieve data block function for
* all tables in this group. * all tables in this group.
* *
* @param tsdb tsdb handle * @param tsdb tsdb handle
* @param pCond query condition, including time window, result set order, and basic required columns for each * @param pCond query condition, including time window, result set order, and basic required columns for each block
* block * @param tableInfo table list.
* @param tableqinfoGroupInfo tableId list.
* @return * @return
*/ */
TsdbQueryHandleT tsdbQueryLastRow(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableqinfoGroupInfo, void *qinfo); TsdbQueryHandleT tsdbQueryLastRow(TSDB_REPO_T *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfo, void *qinfo);
/** /**
* get the queried table object list * get the queried table object list
...@@ -260,7 +265,7 @@ SArray *tsdbRetrieveDataBlock(TsdbQueryHandleT *pQueryHandle, SArray *pColumnIdL ...@@ -260,7 +265,7 @@ SArray *tsdbRetrieveDataBlock(TsdbQueryHandleT *pQueryHandle, SArray *pColumnIdL
* @param stableid. super table sid * @param stableid. super table sid
* @param pTagCond. tag query condition * @param pTagCond. tag query condition
*/ */
int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T *tsdb, uint64_t uid, const char *pTagCond, size_t len, int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T *tsdb, uint64_t uid, TSKEY key, const char *pTagCond, size_t len,
int16_t tagNameRelType, const char *tbnameCond, STableGroupInfo *pGroupList, int16_t tagNameRelType, const char *tbnameCond, STableGroupInfo *pGroupList,
SColIndex *pColIndex, int32_t numOfCols); SColIndex *pColIndex, int32_t numOfCols);
...@@ -278,7 +283,7 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList); ...@@ -278,7 +283,7 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList);
* @param pGroupInfo the generated result * @param pGroupInfo the generated result
* @return * @return
*/ */
int32_t tsdbGetOneTableGroup(TSDB_REPO_T *tsdb, uint64_t uid, STableGroupInfo *pGroupInfo); int32_t tsdbGetOneTableGroup(TSDB_REPO_T *tsdb, uint64_t uid, TSKEY startKey, STableGroupInfo *pGroupInfo);
/** /**
* *
......
...@@ -193,7 +193,7 @@ void mnodeDecDbRef(SDbObj *pDb) { ...@@ -193,7 +193,7 @@ void mnodeDecDbRef(SDbObj *pDb) {
} }
SDbObj *mnodeGetDbByTableId(char *tableId) { SDbObj *mnodeGetDbByTableId(char *tableId) {
char db[TSDB_TABLE_ID_LEN], *pos; char db[TSDB_TABLE_FNAME_LEN], *pos;
// tableId format should be : acct.db.table // tableId format should be : acct.db.table
pos = strstr(tableId, TS_PATH_DELIMITER); pos = strstr(tableId, TS_PATH_DELIMITER);
...@@ -1046,7 +1046,7 @@ static int32_t mnodeProcessDropDbMsg(SMnodeMsg *pMsg) { ...@@ -1046,7 +1046,7 @@ static int32_t mnodeProcessDropDbMsg(SMnodeMsg *pMsg) {
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pDrop->db); if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pDrop->db);
if (pMsg->pDb == NULL) { if (pMsg->pDb == NULL) {
if (pDrop->ignoreNotExists) { if (pDrop->ignoreNotExists) {
mDebug("db:%s, db is not exist, think drop success", pDrop->db); mDebug("db:%s, db is not exist, treat as success", pDrop->db);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} else { } else {
mError("db:%s, failed to drop, invalid db", pDrop->db); mError("db:%s, failed to drop, invalid db", pDrop->db);
......
...@@ -73,13 +73,13 @@ int32_t mnodeInitProfile() { ...@@ -73,13 +73,13 @@ int32_t mnodeInitProfile() {
void mnodeCleanupProfile() { void mnodeCleanupProfile() {
if (tsMnodeConnCache != NULL) { if (tsMnodeConnCache != NULL) {
mInfo("conn cache is cleanup");
taosCacheCleanup(tsMnodeConnCache); taosCacheCleanup(tsMnodeConnCache);
tsMnodeConnCache = NULL; tsMnodeConnCache = NULL;
} }
} }
SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) { SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
#if 0
int32_t connSize = taosHashGetSize(tsMnodeConnCache->pHashTable); int32_t connSize = taosHashGetSize(tsMnodeConnCache->pHashTable);
if (connSize > tsMaxShellConns) { if (connSize > tsMaxShellConns) {
mError("failed to create conn for user:%s ip:%s:%u, conns:%d larger than maxShellConns:%d, ", user, taosIpStr(ip), mError("failed to create conn for user:%s ip:%s:%u, conns:%d larger than maxShellConns:%d, ", user, taosIpStr(ip),
...@@ -87,6 +87,7 @@ SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) { ...@@ -87,6 +87,7 @@ SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
terrno = TSDB_CODE_MND_TOO_MANY_SHELL_CONNS; terrno = TSDB_CODE_MND_TOO_MANY_SHELL_CONNS;
return NULL; return NULL;
} }
#endif
int32_t connId = atomic_add_fetch_32(&tsConnIndex, 1); int32_t connId = atomic_add_fetch_32(&tsConnIndex, 1);
if (connId == 0) atomic_add_fetch_32(&tsConnIndex, 1); if (connId == 0) atomic_add_fetch_32(&tsConnIndex, 1);
...@@ -100,7 +101,7 @@ SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) { ...@@ -100,7 +101,7 @@ SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
tstrncpy(connObj.user, user, sizeof(connObj.user)); tstrncpy(connObj.user, user, sizeof(connObj.user));
SConnObj *pConn = taosCachePut(tsMnodeConnCache, &connId, sizeof(int32_t), &connObj, sizeof(connObj), CONN_KEEP_TIME); SConnObj *pConn = taosCachePut(tsMnodeConnCache, &connId, sizeof(int32_t), &connObj, sizeof(connObj), CONN_KEEP_TIME);
mDebug("connId:%d, is created, user:%s ip:%s:%u", connId, user, taosIpStr(ip), port); mDebug("connId:%d, is created, user:%s ip:%s:%u", connId, user, taosIpStr(ip), port);
return pConn; return pConn;
} }
...@@ -112,7 +113,7 @@ void mnodeReleaseConn(SConnObj *pConn) { ...@@ -112,7 +113,7 @@ void mnodeReleaseConn(SConnObj *pConn) {
SConnObj *mnodeAccquireConn(int32_t connId, char *user, uint32_t ip, uint16_t port) { SConnObj *mnodeAccquireConn(int32_t connId, char *user, uint32_t ip, uint16_t port) {
uint64_t expireTime = CONN_KEEP_TIME * 1000 + (uint64_t)taosGetTimestampMs(); uint64_t expireTime = CONN_KEEP_TIME * 1000 + (uint64_t)taosGetTimestampMs();
SConnObj *pConn = taosCacheUpdateExpireTimeByName(tsMnodeConnCache, &connId, sizeof(int32_t), expireTime); SConnObj *pConn = taosCacheAcquireByKey(tsMnodeConnCache, &connId, sizeof(int32_t));
if (pConn == NULL) { if (pConn == NULL) {
mDebug("connId:%d, is already destroyed, user:%s ip:%s:%u", connId, user, taosIpStr(ip), port); mDebug("connId:%d, is already destroyed, user:%s ip:%s:%u", connId, user, taosIpStr(ip), port);
return NULL; return NULL;
......
...@@ -874,7 +874,7 @@ void *sdbOpenTable(SSdbTableDesc *pDesc) { ...@@ -874,7 +874,7 @@ void *sdbOpenTable(SSdbTableDesc *pDesc) {
if (pTable->keyType == SDB_KEY_STRING || pTable->keyType == SDB_KEY_VAR_STRING) { if (pTable->keyType == SDB_KEY_STRING || pTable->keyType == SDB_KEY_VAR_STRING) {
hashFp = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); hashFp = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
} }
pTable->iHandle = taosHashInit(pTable->hashSessions, hashFp, true); pTable->iHandle = taosHashInit(pTable->hashSessions, hashFp, true, true);
tsSdbObj.numOfTables++; tsSdbObj.numOfTables++;
tsSdbObj.tableList[pTable->tableId] = pTable; tsSdbObj.tableList[pTable->tableId] = pTable;
......
...@@ -302,7 +302,7 @@ static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) { ...@@ -302,7 +302,7 @@ static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) {
SAcctObj *pAcct = pUser->pAcct; SAcctObj *pAcct = pUser->pAcct;
if (pConnectMsg->db[0]) { if (pConnectMsg->db[0]) {
char dbName[TSDB_TABLE_ID_LEN * 3] = {0}; char dbName[TSDB_TABLE_FNAME_LEN * 3] = {0};
sprintf(dbName, "%x%s%s", pAcct->acctId, TS_PATH_DELIMITER, pConnectMsg->db); sprintf(dbName, "%x%s%s", pAcct->acctId, TS_PATH_DELIMITER, pConnectMsg->db);
SDbObj *pDb = mnodeGetDb(dbName); SDbObj *pDb = mnodeGetDb(dbName);
if (pDb == NULL) { if (pDb == NULL) {
......
...@@ -215,7 +215,7 @@ static int32_t mnodeChildTableActionEncode(SSdbOper *pOper) { ...@@ -215,7 +215,7 @@ static int32_t mnodeChildTableActionEncode(SSdbOper *pOper) {
assert(pTable != NULL && pOper->rowData != NULL); assert(pTable != NULL && pOper->rowData != NULL);
int32_t len = strlen(pTable->info.tableId); int32_t len = strlen(pTable->info.tableId);
if (len >= TSDB_TABLE_ID_LEN) return TSDB_CODE_MND_INVALID_TABLE_ID; if (len >= TSDB_TABLE_FNAME_LEN) return TSDB_CODE_MND_INVALID_TABLE_ID;
memcpy(pOper->rowData, pTable->info.tableId, len); memcpy(pOper->rowData, pTable->info.tableId, len);
memset(pOper->rowData + len, 0, 1); memset(pOper->rowData + len, 0, 1);
...@@ -246,7 +246,7 @@ static int32_t mnodeChildTableActionDecode(SSdbOper *pOper) { ...@@ -246,7 +246,7 @@ static int32_t mnodeChildTableActionDecode(SSdbOper *pOper) {
if (pTable == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; if (pTable == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
int32_t len = strlen(pOper->rowData); int32_t len = strlen(pOper->rowData);
if (len >= TSDB_TABLE_ID_LEN) { if (len >= TSDB_TABLE_FNAME_LEN) {
free(pTable); free(pTable);
return TSDB_CODE_MND_INVALID_TABLE_ID; return TSDB_CODE_MND_INVALID_TABLE_ID;
} }
...@@ -348,7 +348,7 @@ static int32_t mnodeInitChildTables() { ...@@ -348,7 +348,7 @@ static int32_t mnodeInitChildTables() {
.tableId = SDB_TABLE_CTABLE, .tableId = SDB_TABLE_CTABLE,
.tableName = "ctables", .tableName = "ctables",
.hashSessions = TSDB_DEFAULT_CTABLES_HASH_SIZE, .hashSessions = TSDB_DEFAULT_CTABLES_HASH_SIZE,
.maxRowSize = sizeof(SChildTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_ID_LEN + TSDB_CQ_SQL_SIZE, .maxRowSize = sizeof(SChildTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_FNAME_LEN + TSDB_CQ_SQL_SIZE,
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
.keyType = SDB_KEY_VAR_STRING, .keyType = SDB_KEY_VAR_STRING,
.insertFp = mnodeChildTableActionInsert, .insertFp = mnodeChildTableActionInsert,
...@@ -387,7 +387,7 @@ static void mnodeAddTableIntoStable(SSuperTableObj *pStable, SChildTableObj *pCt ...@@ -387,7 +387,7 @@ static void mnodeAddTableIntoStable(SSuperTableObj *pStable, SChildTableObj *pCt
atomic_add_fetch_32(&pStable->numOfTables, 1); atomic_add_fetch_32(&pStable->numOfTables, 1);
if (pStable->vgHash == NULL) { if (pStable->vgHash == NULL) {
pStable->vgHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false); pStable->vgHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false);
} }
if (pStable->vgHash != NULL) { if (pStable->vgHash != NULL) {
...@@ -479,7 +479,7 @@ static int32_t mnodeSuperTableActionEncode(SSdbOper *pOper) { ...@@ -479,7 +479,7 @@ static int32_t mnodeSuperTableActionEncode(SSdbOper *pOper) {
assert(pOper->pObj != NULL && pOper->rowData != NULL); assert(pOper->pObj != NULL && pOper->rowData != NULL);
int32_t len = strlen(pStable->info.tableId); int32_t len = strlen(pStable->info.tableId);
if (len >= TSDB_TABLE_ID_LEN) len = TSDB_CODE_MND_INVALID_TABLE_ID; if (len >= TSDB_TABLE_FNAME_LEN) len = TSDB_CODE_MND_INVALID_TABLE_ID;
memcpy(pOper->rowData, pStable->info.tableId, len); memcpy(pOper->rowData, pStable->info.tableId, len);
memset(pOper->rowData + len, 0, 1); memset(pOper->rowData + len, 0, 1);
...@@ -503,7 +503,7 @@ static int32_t mnodeSuperTableActionDecode(SSdbOper *pOper) { ...@@ -503,7 +503,7 @@ static int32_t mnodeSuperTableActionDecode(SSdbOper *pOper) {
if (pStable == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; if (pStable == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
int32_t len = strlen(pOper->rowData); int32_t len = strlen(pOper->rowData);
if (len >= TSDB_TABLE_ID_LEN){ if (len >= TSDB_TABLE_FNAME_LEN){
free(pStable); free(pStable);
return TSDB_CODE_MND_INVALID_TABLE_ID; return TSDB_CODE_MND_INVALID_TABLE_ID;
} }
...@@ -539,7 +539,7 @@ static int32_t mnodeInitSuperTables() { ...@@ -539,7 +539,7 @@ static int32_t mnodeInitSuperTables() {
.tableId = SDB_TABLE_STABLE, .tableId = SDB_TABLE_STABLE,
.tableName = "stables", .tableName = "stables",
.hashSessions = TSDB_DEFAULT_STABLES_HASH_SIZE, .hashSessions = TSDB_DEFAULT_STABLES_HASH_SIZE,
.maxRowSize = sizeof(SSuperTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_ID_LEN, .maxRowSize = sizeof(SSuperTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_FNAME_LEN,
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
.keyType = SDB_KEY_VAR_STRING, .keyType = SDB_KEY_VAR_STRING,
.insertFp = mnodeSuperTableActionInsert, .insertFp = mnodeSuperTableActionInsert,
...@@ -751,7 +751,7 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) { ...@@ -751,7 +751,7 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) {
if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pDrop->tableId); if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pDrop->tableId);
if (pMsg->pTable == NULL) { if (pMsg->pTable == NULL) {
if (pDrop->igNotExists) { if (pDrop->igNotExists) {
mDebug("app:%p:%p, table:%s, table is not exist, think drop success", pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId); mDebug("app:%p:%p, table:%s, table is not exist, treat as success", pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} else { } else {
mError("app:%p:%p, table:%s, failed to drop table, table not exist", pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId); mError("app:%p:%p, table:%s, failed to drop table, table not exist", pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId);
...@@ -1464,7 +1464,7 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) { ...@@ -1464,7 +1464,7 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
// reserve space // reserve space
int32_t contLen = sizeof(SCMSTableVgroupRspMsg) + 32 * sizeof(SCMVgroupInfo) + sizeof(SVgroupsInfo); int32_t contLen = sizeof(SCMSTableVgroupRspMsg) + 32 * sizeof(SCMVgroupInfo) + sizeof(SVgroupsInfo);
for (int32_t i = 0; i < numOfTable; ++i) { for (int32_t i = 0; i < numOfTable; ++i) {
char *stableName = (char*)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_ID_LEN) * i; char *stableName = (char*)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN) * i;
SSuperTableObj *pTable = mnodeGetSuperTable(stableName); SSuperTableObj *pTable = mnodeGetSuperTable(stableName);
if (pTable != NULL && pTable->vgHash != NULL) { if (pTable != NULL && pTable->vgHash != NULL) {
contLen += (taosHashGetSize(pTable->vgHash) * sizeof(SCMVgroupInfo) + sizeof(SVgroupsInfo)); contLen += (taosHashGetSize(pTable->vgHash) * sizeof(SCMVgroupInfo) + sizeof(SVgroupsInfo));
...@@ -1481,7 +1481,7 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) { ...@@ -1481,7 +1481,7 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
char *msg = (char *)pRsp + sizeof(SCMSTableVgroupRspMsg); char *msg = (char *)pRsp + sizeof(SCMSTableVgroupRspMsg);
for (int32_t i = 0; i < numOfTable; ++i) { for (int32_t i = 0; i < numOfTable; ++i) {
char * stableName = (char *)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_ID_LEN)*i; char * stableName = (char *)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
SSuperTableObj *pTable = mnodeGetSuperTable(stableName); SSuperTableObj *pTable = mnodeGetSuperTable(stableName);
if (pTable == NULL) { if (pTable == NULL) {
mError("app:%p:%p, stable:%s, not exist while get stable vgroup info", pMsg->rpcMsg.ahandle, pMsg, stableName); mError("app:%p:%p, stable:%s, not exist while get stable vgroup info", pMsg->rpcMsg.ahandle, pMsg, stableName);
...@@ -1828,7 +1828,7 @@ static int32_t mnodeSendDropChildTableMsg(SMnodeMsg *pMsg, bool needReturn) { ...@@ -1828,7 +1828,7 @@ static int32_t mnodeSendDropChildTableMsg(SMnodeMsg *pMsg, bool needReturn) {
return TSDB_CODE_MND_OUT_OF_MEMORY; return TSDB_CODE_MND_OUT_OF_MEMORY;
} }
tstrncpy(pDrop->tableId, pTable->info.tableId, TSDB_TABLE_ID_LEN); tstrncpy(pDrop->tableId, pTable->info.tableId, TSDB_TABLE_FNAME_LEN);
pDrop->vgId = htonl(pTable->vgId); pDrop->vgId = htonl(pTable->vgId);
pDrop->contLen = htonl(sizeof(SMDDropTableMsg)); pDrop->contLen = htonl(sizeof(SMDDropTableMsg));
pDrop->sid = htonl(pTable->sid); pDrop->sid = htonl(pTable->sid);
...@@ -2079,7 +2079,7 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) { ...@@ -2079,7 +2079,7 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) {
pMeta->sid = htonl(pTable->sid); pMeta->sid = htonl(pTable->sid);
pMeta->precision = pDb->cfg.precision; pMeta->precision = pDb->cfg.precision;
pMeta->tableType = pTable->info.type; pMeta->tableType = pTable->info.type;
tstrncpy(pMeta->tableId, pTable->info.tableId, TSDB_TABLE_ID_LEN); tstrncpy(pMeta->tableId, pTable->info.tableId, TSDB_TABLE_FNAME_LEN);
if (pTable->info.type == TSDB_CHILD_TABLE) { if (pTable->info.type == TSDB_CHILD_TABLE) {
pMeta->sversion = htons(pTable->superTable->sversion); pMeta->sversion = htons(pTable->superTable->sversion);
...@@ -2448,7 +2448,7 @@ static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) { ...@@ -2448,7 +2448,7 @@ static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
pMultiMeta->numOfTables = 0; pMultiMeta->numOfTables = 0;
for (int32_t t = 0; t < pInfo->numOfTables; ++t) { for (int32_t t = 0; t < pInfo->numOfTables; ++t) {
char * tableId = (char *)(pInfo->tableIds + t * TSDB_TABLE_ID_LEN); char * tableId = (char *)(pInfo->tableIds + t * TSDB_TABLE_FNAME_LEN);
SChildTableObj *pTable = mnodeGetChildTable(tableId); SChildTableObj *pTable = mnodeGetChildTable(tableId);
if (pTable == NULL) continue; if (pTable == NULL) continue;
......
...@@ -167,8 +167,8 @@ bool httpInitContext(HttpContext *pContext) { ...@@ -167,8 +167,8 @@ bool httpInitContext(HttpContext *pContext) {
memset(pParser, 0, sizeof(HttpParser)); memset(pParser, 0, sizeof(HttpParser));
pParser->pCur = pParser->pLast = pParser->buffer; pParser->pCur = pParser->pLast = pParser->buffer;
httpDebug("context:%p, fd:%d, ip:%s, thread:%s, accessTimes:%d, parsed:%d", httpDebug("context:%p, fd:%d, ip:%s, accessTimes:%d, parsed:%d", pContext, pContext->fd, pContext->ipstr,
pContext, pContext->fd, pContext->ipstr, pContext->pThread->label, pContext->accessTimes, pContext->parsed); pContext->accessTimes, pContext->parsed);
return true; return true;
} }
......
...@@ -192,7 +192,7 @@ static void dnodeBuildMonitorSql(char *sql, int32_t cmd) { ...@@ -192,7 +192,7 @@ static void dnodeBuildMonitorSql(char *sql, int32_t cmd) {
snprintf(sql, SQL_LENGTH, snprintf(sql, SQL_LENGTH,
"create table if not exists %s.slowquery(ts timestamp, username " "create table if not exists %s.slowquery(ts timestamp, username "
"binary(%d), created_time timestamp, time bigint, sql binary(%d))", "binary(%d), created_time timestamp, time bigint, sql binary(%d))",
tsMonitorDbName, TSDB_TABLE_ID_LEN - 1, TSDB_SLOW_QUERY_SQL_LEN); tsMonitorDbName, TSDB_TABLE_FNAME_LEN - 1, TSDB_SLOW_QUERY_SQL_LEN);
} else if (cmd == MONITOR_CMD_CREATE_TB_LOG) { } else if (cmd == MONITOR_CMD_CREATE_TB_LOG) {
snprintf(sql, SQL_LENGTH, snprintf(sql, SQL_LENGTH,
"create table if not exists %s.log(ts timestamp, level tinyint, " "create table if not exists %s.log(ts timestamp, level tinyint, "
......
...@@ -48,7 +48,7 @@ typedef struct tQueryInfo { ...@@ -48,7 +48,7 @@ typedef struct tQueryInfo {
SSchema sch; // schema of tags SSchema sch; // schema of tags
char* q; char* q;
__compar_fn_t compare; // filter function __compar_fn_t compare; // filter function
void* param; // STSchema bool indexed; // indexed columns
} tQueryInfo; } tQueryInfo;
typedef struct SExprTraverseSupp { typedef struct SExprTraverseSupp {
......
...@@ -52,10 +52,10 @@ typedef struct SWindowStatus { ...@@ -52,10 +52,10 @@ typedef struct SWindowStatus {
typedef struct SWindowResult { typedef struct SWindowResult {
uint16_t numOfRows; // number of rows of current time window uint16_t numOfRows; // number of rows of current time window
SWindowStatus status; // this result status: closed or opened
SPosInfo pos; // Position of current result in disk-based output buffer SPosInfo pos; // Position of current result in disk-based output buffer
SResultInfo* resultInfo; // For each result column, there is a resultInfo SResultInfo* resultInfo; // For each result column, there is a resultInfo
STimeWindow window; // The time window that current result covers. STimeWindow window; // The time window that current result covers.
SWindowStatus status; // this result status: closed or opened
} SWindowResult; } SWindowResult;
/** /**
...@@ -122,6 +122,7 @@ typedef struct SQueryCostInfo { ...@@ -122,6 +122,7 @@ typedef struct SQueryCostInfo {
uint32_t discardBlocks; uint32_t discardBlocks;
uint64_t elapsedTime; uint64_t elapsedTime;
uint64_t computTime; uint64_t computTime;
uint64_t internalSupSize;
} SQueryCostInfo; } SQueryCostInfo;
typedef struct SQuery { typedef struct SQuery {
...@@ -184,10 +185,8 @@ enum { ...@@ -184,10 +185,8 @@ enum {
typedef struct SQInfo { typedef struct SQInfo {
void* signature; void* signature;
int32_t pointsInterpo; int32_t code; // error code to returned to client
int32_t code; // error code to returned to client pthread_t owner; // if it is in execution
// sem_t dataReady;
void* tsdb; void* tsdb;
int32_t vgId; int32_t vgId;
STableGroupInfo tableGroupInfo; // table id list < only includes the STable list> STableGroupInfo tableGroupInfo; // table id list < only includes the STable list>
......
...@@ -29,7 +29,7 @@ extern "C" { ...@@ -29,7 +29,7 @@ extern "C" {
#define MAX_TMPFILE_PATH_LENGTH PATH_MAX #define MAX_TMPFILE_PATH_LENGTH PATH_MAX
#define INITIAL_ALLOCATION_BUFFER_SIZE 64 #define INITIAL_ALLOCATION_BUFFER_SIZE 64
#define DEFAULT_PAGE_SIZE (4096L) // 16k larger than the SHistoInfo #define DEFAULT_PAGE_SIZE (1024L) // 16k larger than the SHistoInfo
typedef enum EXT_BUFFER_FLUSH_MODEL { typedef enum EXT_BUFFER_FLUSH_MODEL {
/* /*
......
...@@ -26,7 +26,12 @@ ...@@ -26,7 +26,12 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include "qSqlparser.h"
#include "tcmdtype.h"
#include "tstoken.h"
#include "ttokendef.h"
#include "tutil.h" #include "tutil.h"
#include "tvariant.h"
} }
%syntax_error { %syntax_error {
...@@ -254,7 +259,7 @@ alter_db_optr(Y) ::= alter_db_optr(Z) keep(X). { Y = Z; Y.keep = X; } ...@@ -254,7 +259,7 @@ alter_db_optr(Y) ::= alter_db_optr(Z) keep(X). { Y = Z; Y.keep = X; }
alter_db_optr(Y) ::= alter_db_optr(Z) blocks(X). { Y = Z; Y.numOfBlocks = strtol(X.z, NULL, 10); } alter_db_optr(Y) ::= alter_db_optr(Z) blocks(X). { Y = Z; Y.numOfBlocks = strtol(X.z, NULL, 10); }
alter_db_optr(Y) ::= alter_db_optr(Z) comp(X). { Y = Z; Y.compressionLevel = strtol(X.z, NULL, 10); } alter_db_optr(Y) ::= alter_db_optr(Z) comp(X). { Y = Z; Y.compressionLevel = strtol(X.z, NULL, 10); }
alter_db_optr(Y) ::= alter_db_optr(Z) wal(X). { Y = Z; Y.walLevel = strtol(X.z, NULL, 10); } alter_db_optr(Y) ::= alter_db_optr(Z) wal(X). { Y = Z; Y.walLevel = strtol(X.z, NULL, 10); }
alter_db_optr(Y) ::= alter_db_optr(Z) fsync(X). { Y = Z; Y.fsyncPeriod = strtod(X.z, NULL, 10); } alter_db_optr(Y) ::= alter_db_optr(Z) fsync(X). { Y = Z; Y.fsyncPeriod = strtol(X.z, NULL, 10); }
%type typename {TAOS_FIELD} %type typename {TAOS_FIELD}
typename(A) ::= ids(X). { typename(A) ::= ids(X). {
...@@ -422,8 +427,35 @@ as(X) ::= . { X.n = 0; } ...@@ -422,8 +427,35 @@ as(X) ::= . { X.n = 0; }
from(A) ::= FROM tablelist(X). {A = X;} from(A) ::= FROM tablelist(X). {A = X;}
%type tablelist {tVariantList*} %type tablelist {tVariantList*}
tablelist(A) ::= ids(X) cpxName(Y). { toTSDBType(X.type); X.n += Y.n; A = tVariantListAppendToken(NULL, &X, -1);} tablelist(A) ::= ids(X) cpxName(Y). {
tablelist(A) ::= tablelist(Y) COMMA ids(X) cpxName(Z). { toTSDBType(X.type); X.n += Z.n; A = tVariantListAppendToken(Y, &X, -1); } toTSDBType(X.type);
X.n += Y.n;
A = tVariantListAppendToken(NULL, &X, -1);
A = tVariantListAppendToken(A, &X, -1); // table alias name
}
tablelist(A) ::= ids(X) cpxName(Y) ids(Z). {
toTSDBType(X.type);
toTSDBType(Z.type);
X.n += Y.n;
A = tVariantListAppendToken(NULL, &X, -1);
A = tVariantListAppendToken(A, &Z, -1);
}
tablelist(A) ::= tablelist(Y) COMMA ids(X) cpxName(Z). {
toTSDBType(X.type);
X.n += Z.n;
A = tVariantListAppendToken(Y, &X, -1);
A = tVariantListAppendToken(A, &X, -1);
}
tablelist(A) ::= tablelist(Y) COMMA ids(X) cpxName(Z) ids(F). {
toTSDBType(X.type);
toTSDBType(F.type);
X.n += Z.n;
A = tVariantListAppendToken(Y, &X, -1);
A = tVariantListAppendToken(A, &F, -1);
}
// The value of interval should be the form of "number+[a,s,m,h,d,n,y]" or "now" // The value of interval should be the form of "number+[a,s,m,h,d,n,y]" or "now"
%type tmvar {SSQLToken} %type tmvar {SSQLToken}
......
...@@ -427,8 +427,9 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr ...@@ -427,8 +427,9 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr
if (ret != 0) { if (ret != 0) {
break; break;
} }
taosArrayPush(result, SL_GET_NODE_DATA(pNode)); STableKeyInfo info = {.pTable = *(void**)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
} }
} else if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL) { // greater equal } else if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL) { // greater equal
bool comp = true; bool comp = true;
...@@ -445,7 +446,8 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr ...@@ -445,7 +446,8 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr
if (ret == 0 && optr == TSDB_RELATION_GREATER) { if (ret == 0 && optr == TSDB_RELATION_GREATER) {
continue; continue;
} else { } else {
taosArrayPush(result, SL_GET_NODE_DATA(pNode)); STableKeyInfo info = {.pTable = *(void**)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
comp = false; comp = false;
} }
} }
...@@ -458,8 +460,9 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr ...@@ -458,8 +460,9 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr
if (comp) { if (comp) {
continue; continue;
} }
taosArrayPush(result, SL_GET_NODE_DATA(pNode)); STableKeyInfo info = {.pTable = *(void**)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
} }
tSkipListDestroyIter(iter); tSkipListDestroyIter(iter);
...@@ -472,8 +475,9 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr ...@@ -472,8 +475,9 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr
if (comp) { if (comp) {
continue; continue;
} }
taosArrayPush(result, SL_GET_NODE_DATA(pNode)); STableKeyInfo info = {.pTable = *(void**)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
} }
} else { } else {
...@@ -496,12 +500,14 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr ...@@ -496,12 +500,14 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr
if (ret == 0 && optr == TSDB_RELATION_LESS) { if (ret == 0 && optr == TSDB_RELATION_LESS) {
continue; continue;
} else { } else {
taosArrayPush(result, SL_GET_NODE_DATA(pNode)); STableKeyInfo info = {.pTable = *(void**)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(result, &info);
comp = false; // no need to compare anymore comp = false; // no need to compare anymore
} }
} }
} }
} }
free(cond.start); free(cond.start);
free(cond.end); free(cond.end);
tSkipListDestroyIter(iter); tSkipListDestroyIter(iter);
...@@ -689,7 +695,8 @@ static void tQueryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, ...@@ -689,7 +695,8 @@ static void tQueryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo,
} }
if (addToResult) { if (addToResult) {
taosArrayPush(res, pData); STableKeyInfo info = {.pTable = *(void**)pData, .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(res, &info);
} }
} }
...@@ -716,7 +723,7 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S ...@@ -716,7 +723,7 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S
} }
tQueryInfo *pQueryInfo = pExpr->_node.info; tQueryInfo *pQueryInfo = pExpr->_node.info;
if (pQueryInfo->sch.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX && pQueryInfo->optr != TSDB_RELATION_LIKE) { if (pQueryInfo->indexed && pQueryInfo->optr != TSDB_RELATION_LIKE) {
tQueryIndexColumn(pSkipList, pQueryInfo, result); tQueryIndexColumn(pSkipList, pQueryInfo, result);
} else { } else {
tQueryIndexlessColumn(pSkipList, pQueryInfo, result, param->nodeFilterFn); tQueryIndexlessColumn(pSkipList, pQueryInfo, result, param->nodeFilterFn);
......
...@@ -130,6 +130,9 @@ static void finalizeQueryResult(SQueryRuntimeEnv *pRuntimeEnv); ...@@ -130,6 +130,9 @@ static void finalizeQueryResult(SQueryRuntimeEnv *pRuntimeEnv);
(tw)->ekey = (tw)->skey + ((_q)->intervalTime - 1); \ (tw)->ekey = (tw)->skey + ((_q)->intervalTime - 1); \
} while (0) } while (0)
#define SET_STABLE_QUERY_OVER(_q) ((_q)->tableIndex = (_q)->tableqinfoGroupInfo.numOfTables)
#define IS_STASBLE_QUERY_OVER(_q) ((_q)->tableIndex >= (_q)->tableqinfoGroupInfo.numOfTables)
// todo move to utility // todo move to utility
static int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *group); static int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *group);
...@@ -400,8 +403,16 @@ static SWindowResult *doSetTimeWindowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWin ...@@ -400,8 +403,16 @@ static SWindowResult *doSetTimeWindowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWin
// more than the capacity, reallocate the resources // more than the capacity, reallocate the resources
if (pWindowResInfo->size >= pWindowResInfo->capacity) { if (pWindowResInfo->size >= pWindowResInfo->capacity) {
int64_t newCap = (int64_t)(pWindowResInfo->capacity * 1.5f); int64_t newCap = 0;
if (pWindowResInfo->capacity > 10000) {
newCap = pWindowResInfo->capacity * 1.25;
} else {
newCap = pWindowResInfo->capacity * 1.5;
}
char *t = realloc(pWindowResInfo->pResult, newCap * sizeof(SWindowResult)); char *t = realloc(pWindowResInfo->pResult, newCap * sizeof(SWindowResult));
pRuntimeEnv->summary.internalSupSize += (newCap - pWindowResInfo->capacity) * sizeof(SWindowResult);
if (t == NULL) { if (t == NULL) {
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
} }
...@@ -411,6 +422,8 @@ static SWindowResult *doSetTimeWindowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWin ...@@ -411,6 +422,8 @@ static SWindowResult *doSetTimeWindowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWin
int32_t inc = (int32_t)newCap - pWindowResInfo->capacity; int32_t inc = (int32_t)newCap - pWindowResInfo->capacity;
memset(&pWindowResInfo->pResult[pWindowResInfo->capacity], 0, sizeof(SWindowResult) * inc); memset(&pWindowResInfo->pResult[pWindowResInfo->capacity], 0, sizeof(SWindowResult) * inc);
pRuntimeEnv->summary.internalSupSize += (pQuery->numOfOutput * sizeof(SResultInfo) + pRuntimeEnv->interBufSize) * inc;
for (int32_t i = pWindowResInfo->capacity; i < newCap; ++i) { for (int32_t i = pWindowResInfo->capacity; i < newCap; ++i) {
createQueryResultInfo(pQuery, &pWindowResInfo->pResult[i], pRuntimeEnv->stableQuery, pRuntimeEnv->interBufSize); createQueryResultInfo(pQuery, &pWindowResInfo->pResult[i], pRuntimeEnv->stableQuery, pRuntimeEnv->interBufSize);
} }
...@@ -1823,10 +1836,14 @@ static void doExchangeTimeWindow(SQInfo* pQInfo) { ...@@ -1823,10 +1836,14 @@ static void doExchangeTimeWindow(SQInfo* pQInfo) {
for(int32_t i = 0; i < t; ++i) { for(int32_t i = 0; i < t; ++i) {
SArray* p1 = GET_TABLEGROUP(pQInfo, i); SArray* p1 = GET_TABLEGROUP(pQInfo, i);
SArray* tableKeyGroup = taosArrayGetP(pQInfo->tableGroupInfo.pGroupList, i);
size_t len = taosArrayGetSize(p1); size_t len = taosArrayGetSize(p1);
for(int32_t j = 0; j < len; ++j) { for(int32_t j = 0; j < len; ++j) {
STableQueryInfo* pTableQueryInfo = (STableQueryInfo*) taosArrayGetP(p1, j); STableQueryInfo* pTableQueryInfo = (STableQueryInfo*) taosArrayGetP(p1, j);
SWAP(pTableQueryInfo->win.skey, pTableQueryInfo->win.ekey, TSKEY); SWAP(pTableQueryInfo->win.skey, pTableQueryInfo->win.ekey, TSKEY);
STableKeyInfo* pInfo = taosArrayGet(tableKeyGroup, j);
pInfo->lastKey = pTableQueryInfo->win.skey;
} }
} }
} }
...@@ -2225,7 +2242,7 @@ static void ensureOutputBufferSimple(SQueryRuntimeEnv* pRuntimeEnv, int32_t capa ...@@ -2225,7 +2242,7 @@ static void ensureOutputBufferSimple(SQueryRuntimeEnv* pRuntimeEnv, int32_t capa
static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pBlockInfo) { static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pBlockInfo) {
// in case of prj/diff query, ensure the output buffer is sufficient to accommodate the results of current block // in case of prj/diff query, ensure the output buffer is sufficient to accommodate the results of current block
SQuery* pQuery = pRuntimeEnv->pQuery; SQuery* pQuery = pRuntimeEnv->pQuery;
if (!QUERY_IS_INTERVAL_QUERY(pQuery) && !pRuntimeEnv->groupbyNormalCol && !isFixedOutputQuery(pRuntimeEnv)) { if (!QUERY_IS_INTERVAL_QUERY(pQuery) && !pRuntimeEnv->groupbyNormalCol && !isFixedOutputQuery(pRuntimeEnv) && !isTSCompQuery(pQuery)) {
SResultRec *pRec = &pQuery->rec; SResultRec *pRec = &pQuery->rec;
if (pQuery->rec.capacity - pQuery->rec.rows < pBlockInfo->rows) { if (pQuery->rec.capacity - pQuery->rec.rows < pBlockInfo->rows) {
...@@ -2662,6 +2679,10 @@ int32_t mergeIntoGroupResult(SQInfo *pQInfo) { ...@@ -2662,6 +2679,10 @@ int32_t mergeIntoGroupResult(SQInfo *pQInfo) {
qDebug("QInfo:%p no result in group %d, continue", pQInfo, pQInfo->groupIndex - 1); qDebug("QInfo:%p no result in group %d, continue", pQInfo, pQInfo->groupIndex - 1);
} }
if (pQInfo->groupIndex == numOfGroups && pQInfo->offset == pQInfo->numOfGroupResultPages) {
SET_STABLE_QUERY_OVER(pQInfo);
}
qDebug("QInfo:%p merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "ms", pQInfo, qDebug("QInfo:%p merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "ms", pQInfo,
pQInfo->groupIndex - 1, numOfGroups, taosGetTimestampMs() - st); pQInfo->groupIndex - 1, numOfGroups, taosGetTimestampMs() - st);
...@@ -2680,7 +2701,7 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) { ...@@ -2680,7 +2701,7 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
// check if all results has been sent to client // check if all results has been sent to client
int32_t numOfGroup = (int32_t)(GET_NUM_OF_TABLEGROUP(pQInfo)); int32_t numOfGroup = (int32_t)(GET_NUM_OF_TABLEGROUP(pQInfo));
if (pQInfo->numOfGroupResultPages == 0 && pQInfo->groupIndex == numOfGroup) { if (pQInfo->numOfGroupResultPages == 0 && pQInfo->groupIndex == numOfGroup) {
pQInfo->tableIndex = (int32_t)pQInfo->tableqinfoGroupInfo.numOfTables; // set query completed SET_STABLE_QUERY_OVER(pQInfo);
return; return;
} }
} }
...@@ -2704,8 +2725,7 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) { ...@@ -2704,8 +2725,7 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
memcpy(pDest + offset * bytes, pData->data + pRuntimeEnv->offset[i] * pData->num, bytes * pData->num); memcpy(pDest + offset * bytes, pData->data + pRuntimeEnv->offset[i] * pData->num, bytes * pData->num);
} }
// rows += pData->num; offset += pData->num;
offset += (int32_t)pData->num;
} }
assert(pQuery->rec.rows == 0); assert(pQuery->rec.rows == 0);
...@@ -2790,14 +2810,20 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) { ...@@ -2790,14 +2810,20 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
setWindowResultInfo(pResultInfo, pQuery, pRuntimeEnv->stableQuery, buf); setWindowResultInfo(pResultInfo, pQuery, pRuntimeEnv->stableQuery, buf);
resetMergeResultBuf(pQuery, pRuntimeEnv->pCtx, pResultInfo); resetMergeResultBuf(pQuery, pRuntimeEnv->pCtx, pResultInfo);
// todo add windowRes iterator
int64_t lastTimestamp = -1; int64_t lastTimestamp = -1;
int64_t startt = taosGetTimestampMs(); int64_t startt = taosGetTimestampMs();
while (1) { while (1) {
if (IS_QUERY_KILLED(pQInfo)) {
qDebug("QInfo:%p it is already killed, abort", pQInfo);
longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
}
int32_t pos = pTree->pNode[0].index; int32_t pos = pTree->pNode[0].index;
SWindowResInfo *pWindowResInfo = &pTableList[pos]->windowResInfo; SWindowResInfo *pWindowResInfo = &pTableList[pos]->windowResInfo;
SWindowResult * pWindowRes = getWindowResult(pWindowResInfo, cs.position[pos]); SWindowResult *pWindowRes = getWindowResult(pWindowResInfo, cs.position[pos]);
tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pWindowRes->pos.pageId); tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pWindowRes->pos.pageId);
char *b = getPosInResultPage(pRuntimeEnv, PRIMARYKEY_TIMESTAMP_COL_INDEX, pWindowRes, page); char *b = getPosInResultPage(pRuntimeEnv, PRIMARYKEY_TIMESTAMP_COL_INDEX, pWindowRes, page);
...@@ -2834,6 +2860,9 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) { ...@@ -2834,6 +2860,9 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
lastTimestamp = ts; lastTimestamp = ts;
// move to the next element of current entry
int32_t currentPageId = pWindowRes->pos.pageId;
cs.position[pos] += 1; cs.position[pos] += 1;
if (cs.position[pos] >= pWindowResInfo->size) { if (cs.position[pos] >= pWindowResInfo->size) {
cs.position[pos] = -1; cs.position[pos] = -1;
...@@ -2842,6 +2871,12 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) { ...@@ -2842,6 +2871,12 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
if (--numOfTables == 0) { if (--numOfTables == 0) {
break; break;
} }
} else {
// current page is not needed anymore
SWindowResult *pNextWindowRes = getWindowResult(pWindowResInfo, cs.position[pos]);
if (pNextWindowRes->pos.pageId != currentPageId) {
releaseResBufPage(pRuntimeEnv->pResultBuf, page);
}
} }
} }
...@@ -2935,7 +2970,7 @@ static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo * ...@@ -2935,7 +2970,7 @@ static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo *
return; return;
} }
// order has change already! // order has changed already
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order);
// TODO validate the assertion // TODO validate the assertion
...@@ -2944,9 +2979,13 @@ static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo * ...@@ -2944,9 +2979,13 @@ static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo *
// } else { // } else {
// assert(pTableQueryInfo->win.ekey <= pTableQueryInfo->lastKey + step); // assert(pTableQueryInfo->win.ekey <= pTableQueryInfo->lastKey + step);
// } // }
pTableQueryInfo->win.ekey = pTableQueryInfo->lastKey + step; if (pTableQueryInfo->lastKey == pTableQueryInfo->win.skey) {
// do nothing, no results
} else {
pTableQueryInfo->win.ekey = pTableQueryInfo->lastKey + step;
}
SWAP(pTableQueryInfo->win.skey, pTableQueryInfo->win.ekey, TSKEY); SWAP(pTableQueryInfo->win.skey, pTableQueryInfo->win.ekey, TSKEY);
pTableQueryInfo->lastKey = pTableQueryInfo->win.skey; pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
...@@ -3008,16 +3047,26 @@ void disableFuncInReverseScan(SQInfo *pQInfo) { ...@@ -3008,16 +3047,26 @@ void disableFuncInReverseScan(SQInfo *pQInfo) {
} }
} }
} }
}
int32_t numOfGroups = (int32_t)(GET_NUM_OF_TABLEGROUP(pQInfo));
static void setupQueryRangeForReverseScan(SQInfo* pQInfo) {
SQuery* pQuery = pQInfo->runtimeEnv.pQuery;
int32_t numOfGroups = GET_NUM_OF_TABLEGROUP(pQInfo);
for(int32_t i = 0; i < numOfGroups; ++i) { for(int32_t i = 0; i < numOfGroups; ++i) {
SArray *group = GET_TABLEGROUP(pQInfo, i); SArray *group = GET_TABLEGROUP(pQInfo, i);
SArray *tableKeyGroup = taosArrayGetP(pQInfo->tableGroupInfo.pGroupList, i);
size_t t = taosArrayGetSize(group); size_t t = taosArrayGetSize(group);
for (int32_t j = 0; j < t; ++j) { for (int32_t j = 0; j < t; ++j) {
STableQueryInfo *pCheckInfo = taosArrayGetP(group, j); STableQueryInfo *pCheckInfo = taosArrayGetP(group, j);
updateTableQueryInfoForReverseScan(pQuery, pCheckInfo); updateTableQueryInfoForReverseScan(pQuery, pCheckInfo);
// update the last key in tableKeyInfo list
STableKeyInfo *pTableKeyInfo = taosArrayGet(tableKeyGroup, j);
pTableKeyInfo->lastKey = pCheckInfo->lastKey;
assert(pCheckInfo->pTable == pTableKeyInfo->pTable);
} }
} }
} }
...@@ -3266,20 +3315,20 @@ static void setEnvBeforeReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatusI ...@@ -3266,20 +3315,20 @@ static void setEnvBeforeReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatusI
TIME_WINDOW_COPY(cond.twindow, pQuery->window); TIME_WINDOW_COPY(cond.twindow, pQuery->window);
setQueryStatus(pQuery, QUERY_NOT_COMPLETED);
switchCtxOrder(pRuntimeEnv);
disableFuncInReverseScan(pQInfo);
setupQueryRangeForReverseScan(pQInfo);
// clean unused handle // clean unused handle
if (pRuntimeEnv->pSecQueryHandle != NULL) { if (pRuntimeEnv->pSecQueryHandle != NULL) {
tsdbCleanupQueryHandle(pRuntimeEnv->pSecQueryHandle); tsdbCleanupQueryHandle(pRuntimeEnv->pSecQueryHandle);
} }
// add ref for table
pRuntimeEnv->pSecQueryHandle = tsdbQueryTables(pQInfo->tsdb, &cond, &pQInfo->tableGroupInfo, pQInfo); pRuntimeEnv->pSecQueryHandle = tsdbQueryTables(pQInfo->tsdb, &cond, &pQInfo->tableGroupInfo, pQInfo);
if (pRuntimeEnv->pSecQueryHandle == NULL) { if (pRuntimeEnv->pSecQueryHandle == NULL) {
longjmp(pRuntimeEnv->env, terrno); longjmp(pRuntimeEnv->env, terrno);
} }
setQueryStatus(pQuery, QUERY_NOT_COMPLETED);
switchCtxOrder(pRuntimeEnv);
disableFuncInReverseScan(pQInfo);
} }
static void clearEnvAfterReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatusInfo *pStatus) { static void clearEnvAfterReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatusInfo *pStatus) {
...@@ -3304,6 +3353,13 @@ static void clearEnvAfterReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatus ...@@ -3304,6 +3353,13 @@ static void clearEnvAfterReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatus
pQuery->window = pTableQueryInfo->win; pQuery->window = pTableQueryInfo->win;
} }
static void restoreTimeWindow(STableGroupInfo* pTableGroupInfo, STsdbQueryCond* pCond) {
assert(pTableGroupInfo->numOfTables == 1);
SArray* pTableKeyGroup = taosArrayGetP(pTableGroupInfo->pGroupList, 0);
STableKeyInfo* pKeyInfo = taosArrayGet(pTableKeyGroup, 0);
pKeyInfo->lastKey = pCond->twindow.skey;
}
void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) { void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
SQInfo *pQInfo = (SQInfo *) GET_QINFO_ADDR(pRuntimeEnv); SQInfo *pQInfo = (SQInfo *) GET_QINFO_ADDR(pRuntimeEnv);
SQuery *pQuery = pRuntimeEnv->pQuery; SQuery *pQuery = pRuntimeEnv->pQuery;
...@@ -3352,6 +3408,7 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) { ...@@ -3352,6 +3408,7 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
tsdbCleanupQueryHandle(pRuntimeEnv->pSecQueryHandle); tsdbCleanupQueryHandle(pRuntimeEnv->pSecQueryHandle);
} }
restoreTimeWindow(&pQInfo->tableGroupInfo, &cond);
pRuntimeEnv->pSecQueryHandle = tsdbQueryTables(pQInfo->tsdb, &cond, &pQInfo->tableGroupInfo, pQInfo); pRuntimeEnv->pSecQueryHandle = tsdbQueryTables(pQInfo->tsdb, &cond, &pQInfo->tableGroupInfo, pQInfo);
if (pRuntimeEnv->pSecQueryHandle == NULL) { if (pRuntimeEnv->pSecQueryHandle == NULL) {
longjmp(pRuntimeEnv->env, terrno); longjmp(pRuntimeEnv->env, terrno);
...@@ -3800,7 +3857,7 @@ static void stableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBloc ...@@ -3800,7 +3857,7 @@ static void stableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBloc
} }
} }
bool queryHasRemainResults(SQueryRuntimeEnv* pRuntimeEnv) { bool queryHasRemainResForTableQuery(SQueryRuntimeEnv* pRuntimeEnv) {
SQuery *pQuery = pRuntimeEnv->pQuery; SQuery *pQuery = pRuntimeEnv->pQuery;
SFillInfo *pFillInfo = pRuntimeEnv->pFillInfo; SFillInfo *pFillInfo = pRuntimeEnv->pFillInfo;
...@@ -3809,8 +3866,7 @@ bool queryHasRemainResults(SQueryRuntimeEnv* pRuntimeEnv) { ...@@ -3809,8 +3866,7 @@ bool queryHasRemainResults(SQueryRuntimeEnv* pRuntimeEnv) {
} }
if (pQuery->fillType != TSDB_FILL_NONE && !isPointInterpoQuery(pQuery)) { if (pQuery->fillType != TSDB_FILL_NONE && !isPointInterpoQuery(pQuery)) {
// There are results not returned to client yet, so filling operation applied to the remain result is required // There are results not returned to client yet, so filling applied to the remain result is required firstly.
// in the first place.
int32_t remain = taosNumOfRemainRows(pFillInfo); int32_t remain = taosNumOfRemainRows(pFillInfo);
if (remain > 0) { if (remain > 0) {
return true; return true;
...@@ -3864,14 +3920,14 @@ static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data ...@@ -3864,14 +3920,14 @@ static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data
data += sizeof(STableIdInfo); data += sizeof(STableIdInfo);
} }
// all data returned, set query over // Check if query is completed or not for stable query or normal table query respectively.
if (Q_STATUS_EQUAL(pQuery->status, QUERY_COMPLETED)) { if (Q_STATUS_EQUAL(pQuery->status, QUERY_COMPLETED)) {
if (pQInfo->runtimeEnv.stableQuery) { if (pQInfo->runtimeEnv.stableQuery) {
if (pQInfo->tableIndex >= pQInfo->tableqinfoGroupInfo.numOfTables) { if (IS_STASBLE_QUERY_OVER(pQInfo)) {
setQueryStatus(pQuery, QUERY_OVER); setQueryStatus(pQuery, QUERY_OVER);
} }
} else { } else {
if (!queryHasRemainResults(&pQInfo->runtimeEnv)) { if (!queryHasRemainResForTableQuery(&pQInfo->runtimeEnv)) {
setQueryStatus(pQuery, QUERY_OVER); setQueryStatus(pQuery, QUERY_OVER);
} }
} }
...@@ -3917,7 +3973,7 @@ int32_t doFillGapsInResults(SQueryRuntimeEnv* pRuntimeEnv, tFilePage **pDst, int ...@@ -3917,7 +3973,7 @@ int32_t doFillGapsInResults(SQueryRuntimeEnv* pRuntimeEnv, tFilePage **pDst, int
ret = 0; ret = 0;
} }
if (!queryHasRemainResults(pRuntimeEnv)) { if (!queryHasRemainResForTableQuery(pRuntimeEnv)) {
return ret; return ret;
} }
} }
...@@ -3931,6 +3987,8 @@ static void queryCostStatis(SQInfo *pQInfo) { ...@@ -3931,6 +3987,8 @@ static void queryCostStatis(SQInfo *pQInfo) {
" load data block:%d, total rows:%"PRId64 ", check rows:%"PRId64, " load data block:%d, total rows:%"PRId64 ", check rows:%"PRId64,
pQInfo, pSummary->elapsedTime, pSummary->totalBlocks, pSummary->loadBlockStatis, pQInfo, pSummary->elapsedTime, pSummary->totalBlocks, pSummary->loadBlockStatis,
pSummary->loadBlocks, pSummary->totalRows, pSummary->totalCheckedRows); pSummary->loadBlocks, pSummary->totalRows, pSummary->totalCheckedRows);
qDebug("QInfo:%p :cost summary: internal size:%"PRId64, pQInfo, pSummary->internalSupSize);
} }
static void updateOffsetVal(SQueryRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) { static void updateOffsetVal(SQueryRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) {
...@@ -4425,9 +4483,11 @@ static bool multiTableMultioutputHelper(SQInfo *pQInfo, int32_t index) { ...@@ -4425,9 +4483,11 @@ static bool multiTableMultioutputHelper(SQInfo *pQInfo, int32_t index) {
// todo refactor // todo refactor
SArray *g1 = taosArrayInit(1, POINTER_BYTES); SArray *g1 = taosArrayInit(1, POINTER_BYTES);
SArray *tx = taosArrayInit(1, POINTER_BYTES); SArray *tx = taosArrayInit(1, sizeof(STableKeyInfo));
STableKeyInfo info = {.pTable = pCheckInfo->pTable, .lastKey = pCheckInfo->lastKey};
taosArrayPush(tx, &info);
taosArrayPush(tx, &pCheckInfo->pTable);
taosArrayPush(g1, &tx); taosArrayPush(g1, &tx);
STableGroupInfo gp = {.numOfTables = 1, .pGroupList = g1}; STableGroupInfo gp = {.numOfTables = 1, .pGroupList = g1};
...@@ -4579,7 +4639,9 @@ static void sequentialTableProcess(SQInfo *pQInfo) { ...@@ -4579,7 +4639,9 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
pRuntimeEnv->pQueryHandle = NULL; pRuntimeEnv->pQueryHandle = NULL;
} }
// no need to update the lastkey for each table
pRuntimeEnv->pQueryHandle = tsdbQueryTables(pQInfo->tsdb, &cond, &gp, pQInfo); pRuntimeEnv->pQueryHandle = tsdbQueryTables(pQInfo->tsdb, &cond, &gp, pQInfo);
taosArrayDestroy(g1); taosArrayDestroy(g1);
taosArrayDestroy(tx); taosArrayDestroy(tx);
if (pRuntimeEnv->pQueryHandle == NULL) { if (pRuntimeEnv->pQueryHandle == NULL) {
...@@ -4680,7 +4742,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) { ...@@ -4680,7 +4742,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
// the limitation of output result is reached, set the query completed // the limitation of output result is reached, set the query completed
if (limitResults(pRuntimeEnv)) { if (limitResults(pRuntimeEnv)) {
pQInfo->tableIndex = (int32_t)pQInfo->tableqinfoGroupInfo.numOfTables; SET_STABLE_QUERY_OVER(pQInfo);
break; break;
} }
...@@ -4705,8 +4767,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) { ...@@ -4705,8 +4767,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
taosArrayPush(pQInfo->arrTableIdInfo, &tidInfo); taosArrayPush(pQInfo->arrTableIdInfo, &tidInfo);
// if the buffer is full or group by each table, we need to jump out of the loop // if the buffer is full or group by each table, we need to jump out of the loop
if (Q_STATUS_EQUAL(pQuery->status, QUERY_RESBUF_FULL) /*|| if (Q_STATUS_EQUAL(pQuery->status, QUERY_RESBUF_FULL)) {
isGroupbyEachTable(pQuery->pGroupbyExpr, pSupporter->pSidSet)*/) {
break; break;
} }
...@@ -4770,7 +4831,7 @@ static void doSaveContext(SQInfo *pQInfo) { ...@@ -4770,7 +4831,7 @@ static void doSaveContext(SQInfo *pQInfo) {
.colList = pQuery->colList, .colList = pQuery->colList,
.numOfCols = pQuery->numOfCols, .numOfCols = pQuery->numOfCols,
}; };
TIME_WINDOW_COPY(cond.twindow, pQuery->window); TIME_WINDOW_COPY(cond.twindow, pQuery->window);
// clean unused handle // clean unused handle
...@@ -4778,15 +4839,16 @@ static void doSaveContext(SQInfo *pQInfo) { ...@@ -4778,15 +4839,16 @@ static void doSaveContext(SQInfo *pQInfo) {
tsdbCleanupQueryHandle(pRuntimeEnv->pSecQueryHandle); tsdbCleanupQueryHandle(pRuntimeEnv->pSecQueryHandle);
} }
setQueryStatus(pQuery, QUERY_NOT_COMPLETED);
switchCtxOrder(pRuntimeEnv);
disableFuncInReverseScan(pQInfo);
setupQueryRangeForReverseScan(pQInfo);
pRuntimeEnv->prevGroupId = INT32_MIN; pRuntimeEnv->prevGroupId = INT32_MIN;
pRuntimeEnv->pSecQueryHandle = tsdbQueryTables(pQInfo->tsdb, &cond, &pQInfo->tableGroupInfo, pQInfo); pRuntimeEnv->pSecQueryHandle = tsdbQueryTables(pQInfo->tsdb, &cond, &pQInfo->tableGroupInfo, pQInfo);
if (pRuntimeEnv->pSecQueryHandle == NULL) { if (pRuntimeEnv->pSecQueryHandle == NULL) {
longjmp(pRuntimeEnv->env, terrno); longjmp(pRuntimeEnv->env, terrno);
} }
setQueryStatus(pQuery, QUERY_NOT_COMPLETED);
switchCtxOrder(pRuntimeEnv);
disableFuncInReverseScan(pQInfo);
} }
static void doRestoreContext(SQInfo *pQInfo) { static void doRestoreContext(SQInfo *pQInfo) {
...@@ -5070,15 +5132,13 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) { ...@@ -5070,15 +5132,13 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
copyFromWindowResToSData(pQInfo, &pRuntimeEnv->windowResInfo); copyFromWindowResToSData(pQInfo, &pRuntimeEnv->windowResInfo);
clearFirstNTimeWindow(pRuntimeEnv, pQInfo->groupIndex); clearFirstNTimeWindow(pRuntimeEnv, pQInfo->groupIndex);
} }
pQInfo->pointsInterpo += numOfFilled;
} }
static void tableQueryImpl(SQInfo *pQInfo) { static void tableQueryImpl(SQInfo *pQInfo) {
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
SQuery * pQuery = pRuntimeEnv->pQuery; SQuery * pQuery = pRuntimeEnv->pQuery;
if (queryHasRemainResults(pRuntimeEnv)) { if (queryHasRemainResForTableQuery(pRuntimeEnv)) {
if (pQuery->fillType != TSDB_FILL_NONE) { if (pQuery->fillType != TSDB_FILL_NONE) {
/* /*
...@@ -5859,7 +5919,7 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList, ...@@ -5859,7 +5919,7 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
pQInfo->tableqinfoGroupInfo.pGroupList = taosArrayInit(numOfGroups, POINTER_BYTES); pQInfo->tableqinfoGroupInfo.pGroupList = taosArrayInit(numOfGroups, POINTER_BYTES);
pQInfo->tableqinfoGroupInfo.numOfTables = pTableGroupInfo->numOfTables; pQInfo->tableqinfoGroupInfo.numOfTables = pTableGroupInfo->numOfTables;
pQInfo->tableqinfoGroupInfo.map = taosHashInit(pTableGroupInfo->numOfTables, pQInfo->tableqinfoGroupInfo.map = taosHashInit(pTableGroupInfo->numOfTables,
taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false); taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false);
} }
int tableIndex = 0; int tableIndex = 0;
...@@ -5880,8 +5940,8 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList, ...@@ -5880,8 +5940,8 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
} }
for(int32_t j = 0; j < s; ++j) { for(int32_t j = 0; j < s; ++j) {
void* pTable = taosArrayGetP(pa, j); STableKeyInfo* info = taosArrayGet(pa, j);
STableId* id = TSDB_TABLEID(pTable); STableId* id = TSDB_TABLEID(info->pTable);
STableIdInfo* pTableId = taosArraySearch(pTableIdList, id, compareTableIdInfo); STableIdInfo* pTableId = taosArraySearch(pTableIdList, id, compareTableIdInfo);
if (pTableId != NULL ) { if (pTableId != NULL ) {
...@@ -5891,10 +5951,11 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList, ...@@ -5891,10 +5951,11 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
} }
void* buf = (char*)pQInfo->pBuf + index * sizeof(STableQueryInfo); void* buf = (char*)pQInfo->pBuf + index * sizeof(STableQueryInfo);
STableQueryInfo* item = createTableQueryInfo(&pQInfo->runtimeEnv, pTable, window, buf); STableQueryInfo* item = createTableQueryInfo(&pQInfo->runtimeEnv, info->pTable, window, buf);
if (item == NULL) { if (item == NULL) {
goto _cleanup; goto _cleanup;
} }
item->groupIndex = i; item->groupIndex = i;
taosArrayPush(p1, &item); taosArrayPush(p1, &item);
taosHashPut(pQInfo->tableqinfoGroupInfo.map, &id->tid, sizeof(id->tid), &item, POINTER_BYTES); taosHashPut(pQInfo->tableqinfoGroupInfo.map, &id->tid, sizeof(id->tid), &item, POINTER_BYTES);
...@@ -5923,6 +5984,7 @@ _cleanup_query: ...@@ -5923,6 +5984,7 @@ _cleanup_query:
taosArrayDestroy(pGroupbyExpr->columnInfo); taosArrayDestroy(pGroupbyExpr->columnInfo);
free(pGroupbyExpr); free(pGroupbyExpr);
} }
taosTFree(pTagCols); taosTFree(pTagCols);
for (int32_t i = 0; i < numOfOutput; ++i) { for (int32_t i = 0; i < numOfOutput; ++i) {
SExprInfo* pExprInfo = &pExprs[i]; SExprInfo* pExprInfo = &pExprs[i];
...@@ -5930,6 +5992,7 @@ _cleanup_query: ...@@ -5930,6 +5992,7 @@ _cleanup_query:
tExprTreeDestroy(&pExprInfo->pExpr, NULL); tExprTreeDestroy(&pExprInfo->pExpr, NULL);
} }
} }
taosTFree(pExprs); taosTFree(pExprs);
_cleanup: _cleanup:
...@@ -6011,8 +6074,6 @@ static void freeQInfo(SQInfo *pQInfo) { ...@@ -6011,8 +6074,6 @@ static void freeQInfo(SQInfo *pQInfo) {
} }
SQuery *pQuery = pQInfo->runtimeEnv.pQuery; SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
setQueryKilled(pQInfo);
qDebug("QInfo:%p start to free QInfo", pQInfo); qDebug("QInfo:%p start to free QInfo", pQInfo);
for (int32_t col = 0; col < pQuery->numOfOutput; ++col) { for (int32_t col = 0; col < pQuery->numOfOutput; ++col) {
taosTFree(pQuery->sdata[col]); taosTFree(pQuery->sdata[col]);
...@@ -6217,7 +6278,7 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi ...@@ -6217,7 +6278,7 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
STableIdInfo *id = taosArrayGet(pTableIdList, 0); STableIdInfo *id = taosArrayGet(pTableIdList, 0);
qDebug("qmsg:%p query normal table, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid); qDebug("qmsg:%p query normal table, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid);
if ((code = tsdbGetOneTableGroup(tsdb, id->uid, &tableGroupInfo)) != TSDB_CODE_SUCCESS) { if ((code = tsdbGetOneTableGroup(tsdb, id->uid, pQueryMsg->window.skey, &tableGroupInfo)) != TSDB_CODE_SUCCESS) {
goto _over; goto _over;
} }
} else if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY|TSDB_QUERY_TYPE_STABLE_QUERY)) { } else if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY|TSDB_QUERY_TYPE_STABLE_QUERY)) {
...@@ -6234,8 +6295,9 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi ...@@ -6234,8 +6295,9 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi
} }
qDebug("qmsg:%p query stable, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid); qDebug("qmsg:%p query stable, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid);
code = tsdbQuerySTableByTagCond(tsdb, id->uid, tagCond, pQueryMsg->tagCondLen, pQueryMsg->tagNameRelType, tbnameCond, &tableGroupInfo, pGroupColIndex, code = tsdbQuerySTableByTagCond(tsdb, id->uid, pQueryMsg->window.skey, tagCond, pQueryMsg->tagCondLen,
numOfGroupByCols); pQueryMsg->tagNameRelType, tbnameCond, &tableGroupInfo, pGroupColIndex, numOfGroupByCols);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
qError("qmsg:%p failed to query stable, reason: %s", pQueryMsg, tstrerror(code)); qError("qmsg:%p failed to query stable, reason: %s", pQueryMsg, tstrerror(code));
goto _over; goto _over;
...@@ -6315,14 +6377,22 @@ static bool doBuildResCheck(SQInfo* pQInfo) { ...@@ -6315,14 +6377,22 @@ static bool doBuildResCheck(SQInfo* pQInfo) {
pthread_mutex_unlock(&pQInfo->lock); pthread_mutex_unlock(&pQInfo->lock);
// clear qhandle owner
assert(pQInfo->owner == pthread_self());
pQInfo->owner = 0;
return buildRes; return buildRes;
} }
bool qTableQuery(qinfo_t qinfo) { bool qTableQuery(qinfo_t qinfo) {
SQInfo *pQInfo = (SQInfo *)qinfo; SQInfo *pQInfo = (SQInfo *)qinfo;
assert(pQInfo && pQInfo->signature == pQInfo);
int64_t threadId = pthread_self();
if (pQInfo == NULL || pQInfo->signature != pQInfo) { int64_t curOwner = 0;
qDebug("QInfo:%p has been freed, no need to execute", pQInfo); if ((curOwner = atomic_val_compare_exchange_64(&pQInfo->owner, 0, threadId)) != 0) {
qError("QInfo:%p qhandle is now executed by thread:%p", pQInfo, (void*) curOwner);
pQInfo->code = TSDB_CODE_QRY_IN_EXEC;
return false; return false;
} }
...@@ -6377,6 +6447,7 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex ...@@ -6377,6 +6447,7 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex
return TSDB_CODE_QRY_INVALID_QHANDLE; return TSDB_CODE_QRY_INVALID_QHANDLE;
} }
*buildRes = false;
SQuery *pQuery = pQInfo->runtimeEnv.pQuery; SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
if (IS_QUERY_KILLED(pQInfo)) { if (IS_QUERY_KILLED(pQInfo)) {
qDebug("QInfo:%p query is killed, code:%d", pQInfo, pQInfo->code); qDebug("QInfo:%p query is killed, code:%d", pQInfo, pQInfo->code);
...@@ -6400,34 +6471,6 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex ...@@ -6400,34 +6471,6 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex
return code; return code;
} }
bool qHasMoreResultsToRetrieve(qinfo_t qinfo) {
SQInfo *pQInfo = (SQInfo *)qinfo;
if (!isValidQInfo(pQInfo) || pQInfo->code != TSDB_CODE_SUCCESS) {
qDebug("QInfo:%p invalid qhandle or error occurs, abort query, code:%x", pQInfo, pQInfo->code);
return false;
}
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
bool ret = false;
if (Q_STATUS_EQUAL(pQuery->status, QUERY_OVER)) {
ret = false;
} else if (Q_STATUS_EQUAL(pQuery->status, QUERY_RESBUF_FULL)) {
ret = true;
} else if (Q_STATUS_EQUAL(pQuery->status, QUERY_COMPLETED)) {
ret = true;
} else {
assert(0);
}
if (ret) {
qDebug("QInfo:%p has more results waits for client retrieve", pQInfo);
}
return ret;
}
int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *contLen, bool* continueExec) { int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *contLen, bool* continueExec) {
SQInfo *pQInfo = (SQInfo *)qinfo; SQInfo *pQInfo = (SQInfo *)qinfo;
...@@ -6455,11 +6498,11 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co ...@@ -6455,11 +6498,11 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co
int32_t code = pQInfo->code; int32_t code = pQInfo->code;
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
(*pRsp)->offset = htobe64(pQuery->limit.offset); (*pRsp)->offset = htobe64(pQuery->limit.offset);
(*pRsp)->useconds = htobe64(pRuntimeEnv->summary.elapsedTime); (*pRsp)->useconds = htobe64(pRuntimeEnv->summary.elapsedTime);
} else { } else {
(*pRsp)->useconds = 0; (*pRsp)->offset = 0;
(*pRsp)->offset = 0; (*pRsp)->useconds = htobe64(pRuntimeEnv->summary.elapsedTime);
} }
(*pRsp)->precision = htons(pQuery->precision); (*pRsp)->precision = htons(pQuery->precision);
...@@ -6471,22 +6514,30 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co ...@@ -6471,22 +6514,30 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co
} }
pQInfo->rspContext = NULL; pQInfo->rspContext = NULL;
pQInfo->dataReady = QUERY_RESULT_NOT_READY; pQInfo->dataReady = QUERY_RESULT_NOT_READY;
if (IS_QUERY_KILLED(pQInfo) || Q_STATUS_EQUAL(pQuery->status, QUERY_OVER)) { if (IS_QUERY_KILLED(pQInfo) || Q_STATUS_EQUAL(pQuery->status, QUERY_OVER)) {
*continueExec = false;
(*pRsp)->completed = 1; // notify no more result to client (*pRsp)->completed = 1; // notify no more result to client
} } else {
if (qHasMoreResultsToRetrieve(pQInfo)) {
*continueExec = true; *continueExec = true;
} else { // failed to dump result, free qhandle immediately qDebug("QInfo:%p has more results waits for client retrieve", pQInfo);
*continueExec = false;
qKillQuery(pQInfo);
} }
return code; return code;
} }
int32_t qQueryCompleted(qinfo_t qinfo) {
SQInfo *pQInfo = (SQInfo *)qinfo;
if (pQInfo == NULL || !isValidQInfo(pQInfo)) {
return TSDB_CODE_QRY_INVALID_QHANDLE;
}
SQuery* pQuery = pQInfo->runtimeEnv.pQuery;
return IS_QUERY_KILLED(pQInfo) || Q_STATUS_EQUAL(pQuery->status, QUERY_OVER);
}
int32_t qKillQuery(qinfo_t qinfo) { int32_t qKillQuery(qinfo_t qinfo) {
SQInfo *pQInfo = (SQInfo *)qinfo; SQInfo *pQInfo = (SQInfo *)qinfo;
...@@ -6495,6 +6546,13 @@ int32_t qKillQuery(qinfo_t qinfo) { ...@@ -6495,6 +6546,13 @@ int32_t qKillQuery(qinfo_t qinfo) {
} }
setQueryKilled(pQInfo); setQueryKilled(pQInfo);
// Wait for the query executing thread being stopped/
// Once the query is stopped, the owner of qHandle will be cleared immediately.
while(pQInfo->owner != 0) {
taosMsleep(100);
}
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -6589,7 +6647,7 @@ static void buildTagQueryResult(SQInfo* pQInfo) { ...@@ -6589,7 +6647,7 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
*(int64_t*) pQuery->sdata[0]->data = num; *(int64_t*) pQuery->sdata[0]->data = num;
count = 1; count = 1;
pQInfo->tableIndex = (int32_t)num; //set query completed SET_STABLE_QUERY_OVER(pQInfo);
qDebug("QInfo:%p create count(tbname) query, res:%d rows:1", pQInfo, count); qDebug("QInfo:%p create count(tbname) query, res:%d rows:1", pQInfo, count);
} else { // return only the tags|table name etc. } else { // return only the tags|table name etc.
count = 0; count = 0;
...@@ -6661,7 +6719,7 @@ void freeqinfoFn(void *qhandle) { ...@@ -6661,7 +6719,7 @@ void freeqinfoFn(void *qhandle) {
} }
void* qOpenQueryMgmt(int32_t vgId) { void* qOpenQueryMgmt(int32_t vgId) {
const int32_t REFRESH_HANDLE_INTERVAL = 30; // every 30 seconds, refresh handle pool const int32_t REFRESH_HANDLE_INTERVAL = 60; // every 30 seconds, refresh handle pool
char cacheName[128] = {0}; char cacheName[128] = {0};
sprintf(cacheName, "qhandle_%d", vgId); sprintf(cacheName, "qhandle_%d", vgId);
...@@ -6691,9 +6749,9 @@ void qQueryMgmtNotifyClosed(void* pQMgmt) { ...@@ -6691,9 +6749,9 @@ void qQueryMgmtNotifyClosed(void* pQMgmt) {
SQueryMgmt* pQueryMgmt = pQMgmt; SQueryMgmt* pQueryMgmt = pQMgmt;
qDebug("vgId:%d, set querymgmt closed, wait for all queries cancelled", pQueryMgmt->vgId); qDebug("vgId:%d, set querymgmt closed, wait for all queries cancelled", pQueryMgmt->vgId);
pthread_mutex_lock(&pQueryMgmt->lock); // pthread_mutex_lock(&pQueryMgmt->lock);
pQueryMgmt->closed = true; pQueryMgmt->closed = true;
pthread_mutex_unlock(&pQueryMgmt->lock); // pthread_mutex_unlock(&pQueryMgmt->lock);
taosCacheRefresh(pQueryMgmt->qinfoPool, queryMgmtKillQueryFn); taosCacheRefresh(pQueryMgmt->qinfoPool, queryMgmtKillQueryFn);
} }
...@@ -6723,7 +6781,7 @@ void** qRegisterQInfo(void* pMgmt, uint64_t qInfo) { ...@@ -6723,7 +6781,7 @@ void** qRegisterQInfo(void* pMgmt, uint64_t qInfo) {
return NULL; return NULL;
} }
const int32_t DEFAULT_QHANDLE_LIFE_SPAN = tsShellActivityTimer * 2; const int32_t DEFAULT_QHANDLE_LIFE_SPAN = tsShellActivityTimer * 2 * 1000;
SQueryMgmt *pQueryMgmt = pMgmt; SQueryMgmt *pQueryMgmt = pMgmt;
if (pQueryMgmt->qinfoPool == NULL) { if (pQueryMgmt->qinfoPool == NULL) {
...@@ -6731,16 +6789,16 @@ void** qRegisterQInfo(void* pMgmt, uint64_t qInfo) { ...@@ -6731,16 +6789,16 @@ void** qRegisterQInfo(void* pMgmt, uint64_t qInfo) {
return NULL; return NULL;
} }
pthread_mutex_lock(&pQueryMgmt->lock); // pthread_mutex_lock(&pQueryMgmt->lock);
if (pQueryMgmt->closed) { if (pQueryMgmt->closed) {
pthread_mutex_unlock(&pQueryMgmt->lock); // pthread_mutex_unlock(&pQueryMgmt->lock);
qError("QInfo:%p failed to add qhandle into cache, since qMgmt is colsing", (void *)qInfo); qError("QInfo:%p failed to add qhandle into cache, since qMgmt is colsing", (void *)qInfo);
return NULL; return NULL;
} else { } else {
uint64_t handleVal = (uint64_t) qInfo; uint64_t handleVal = (uint64_t) qInfo;
void** handle = taosCachePut(pQueryMgmt->qinfoPool, &handleVal, sizeof(int64_t), &qInfo, POINTER_BYTES, DEFAULT_QHANDLE_LIFE_SPAN); void** handle = taosCachePut(pQueryMgmt->qinfoPool, &handleVal, sizeof(int64_t), &qInfo, POINTER_BYTES, DEFAULT_QHANDLE_LIFE_SPAN);
pthread_mutex_unlock(&pQueryMgmt->lock); // pthread_mutex_unlock(&pQueryMgmt->lock);
return handle; return handle;
} }
...@@ -6763,7 +6821,6 @@ void** qAcquireQInfo(void* pMgmt, uint64_t key) { ...@@ -6763,7 +6821,6 @@ void** qAcquireQInfo(void* pMgmt, uint64_t key) {
void** qReleaseQInfo(void* pMgmt, void* pQInfo, bool freeHandle) { void** qReleaseQInfo(void* pMgmt, void* pQInfo, bool freeHandle) {
SQueryMgmt *pQueryMgmt = pMgmt; SQueryMgmt *pQueryMgmt = pMgmt;
if (pQueryMgmt->qinfoPool == NULL) { if (pQueryMgmt->qinfoPool == NULL) {
return NULL; return NULL;
} }
......
...@@ -12,15 +12,14 @@ ...@@ -12,15 +12,14 @@
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "qExtbuffer.h"
#include "os.h" #include "os.h"
#include "qExtbuffer.h"
#include "queryLog.h" #include "queryLog.h"
#include "taos.h" #include "taos.h"
#include "taosdef.h" #include "taosdef.h"
#include "taosmsg.h" #include "taosmsg.h"
#include "tsqlfunction.h" #include "tsqlfunction.h"
#include "tulog.h" #include "tulog.h"
#include "tutil.h"
#define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \ #define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \
(data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes) (data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes)
......
...@@ -6,7 +6,8 @@ ...@@ -6,7 +6,8 @@
#include "queryLog.h" #include "queryLog.h"
#include "taoserror.h" #include "taoserror.h"
#define GET_DATA_PAYLOAD(_p) ((tFilePage*)(((char*)(_p)->pData) + POINTER_BYTES)) #define GET_DATA_PAYLOAD(_p) ((_p)->pData + POINTER_BYTES)
#define NO_IN_MEM_AVAILABLE_PAGES(_b) (listNEles((_b)->lruList) >= (_b)->inMemPages)
int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t rowSize, int32_t pagesize, int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t rowSize, int32_t pagesize,
int32_t inMemBufSize, const void* handle) { int32_t inMemBufSize, const void* handle) {
...@@ -25,7 +26,7 @@ int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t ro ...@@ -25,7 +26,7 @@ int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t ro
pResBuf->comp = true; pResBuf->comp = true;
pResBuf->file = NULL; pResBuf->file = NULL;
pResBuf->handle = handle; pResBuf->handle = handle;
pResBuf->fileSize = 0; pResBuf->fileSize = 0;
// at least more than 2 pages must be in memory // at least more than 2 pages must be in memory
assert(inMemBufSize >= pagesize * 2); assert(inMemBufSize >= pagesize * 2);
...@@ -34,9 +35,9 @@ int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t ro ...@@ -34,9 +35,9 @@ int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t ro
pResBuf->lruList = tdListNew(POINTER_BYTES); pResBuf->lruList = tdListNew(POINTER_BYTES);
// init id hash table // init id hash table
pResBuf->groupSet = taosHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false); pResBuf->groupSet = taosHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false);
pResBuf->assistBuf = malloc(pResBuf->pageSize + 2); // EXTRA BYTES pResBuf->assistBuf = malloc(pResBuf->pageSize + 2); // EXTRA BYTES
pResBuf->all = taosHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false); pResBuf->all = taosHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false);
char path[PATH_MAX] = {0}; char path[PATH_MAX] = {0};
taosGetTmpfilePath("qbuf", path); taosGetTmpfilePath("qbuf", path);
...@@ -186,8 +187,6 @@ static char* loadPageFromDisk(SDiskbasedResultBuf* pResultBuf, SPageInfo* pg) { ...@@ -186,8 +187,6 @@ static char* loadPageFromDisk(SDiskbasedResultBuf* pResultBuf, SPageInfo* pg) {
return (char*)GET_DATA_PAYLOAD(pg); return (char*)GET_DATA_PAYLOAD(pg);
} }
#define NO_AVAILABLE_PAGES(_b) ((_b)->numOfPages >= (_b)->inMemPages)
static SIDList addNewGroup(SDiskbasedResultBuf* pResultBuf, int32_t groupId) { static SIDList addNewGroup(SDiskbasedResultBuf* pResultBuf, int32_t groupId) {
assert(taosHashGet(pResultBuf->groupSet, (const char*) &groupId, sizeof(int32_t)) == NULL); assert(taosHashGet(pResultBuf->groupSet, (const char*) &groupId, sizeof(int32_t)) == NULL);
...@@ -211,11 +210,12 @@ static SPageInfo* registerPage(SDiskbasedResultBuf* pResultBuf, int32_t groupId, ...@@ -211,11 +210,12 @@ static SPageInfo* registerPage(SDiskbasedResultBuf* pResultBuf, int32_t groupId,
pResultBuf->numOfPages += 1; pResultBuf->numOfPages += 1;
SPageInfo* ppi = malloc(sizeof(SPageInfo));//{ .info = PAGE_INFO_INITIALIZER, .pageId = pageId, .pn = NULL}; SPageInfo* ppi = malloc(sizeof(SPageInfo));//{ .info = PAGE_INFO_INITIALIZER, .pageId = pageId, .pn = NULL};
ppi->info = PAGE_INFO_INITIALIZER;
ppi->pageId = pageId; ppi->pageId = pageId;
ppi->pData = NULL; ppi->pData = NULL;
ppi->pn = NULL; ppi->info = PAGE_INFO_INITIALIZER;
ppi->used = true; ppi->used = true;
ppi->pn = NULL;
return *(SPageInfo**) taosArrayPush(list, &ppi); return *(SPageInfo**) taosArrayPush(list, &ppi);
} }
...@@ -246,7 +246,9 @@ static char* evicOneDataPage(SDiskbasedResultBuf* pResultBuf) { ...@@ -246,7 +246,9 @@ static char* evicOneDataPage(SDiskbasedResultBuf* pResultBuf) {
// all pages are referenced by user, try to allocate new space // all pages are referenced by user, try to allocate new space
if (pn == NULL) { if (pn == NULL) {
int32_t prev = pResultBuf->inMemPages; int32_t prev = pResultBuf->inMemPages;
pResultBuf->inMemPages = (int32_t)(pResultBuf->inMemPages * 1.5f);
// increase by 50% of previous mem pages
pResultBuf->inMemPages = pResultBuf->inMemPages * 1.5f;
qWarn("%p in memory buf page not sufficient, expand from %d to %d, page size:%d", pResultBuf, prev, qWarn("%p in memory buf page not sufficient, expand from %d to %d, page size:%d", pResultBuf, prev,
pResultBuf->inMemPages, pResultBuf->pageSize); pResultBuf->inMemPages, pResultBuf->pageSize);
...@@ -281,7 +283,7 @@ tFilePage* getNewDataBuf(SDiskbasedResultBuf* pResultBuf, int32_t groupId, int32 ...@@ -281,7 +283,7 @@ tFilePage* getNewDataBuf(SDiskbasedResultBuf* pResultBuf, int32_t groupId, int32
pResultBuf->statis.getPages += 1; pResultBuf->statis.getPages += 1;
char* availablePage = NULL; char* availablePage = NULL;
if (NO_AVAILABLE_PAGES(pResultBuf)) { if (NO_IN_MEM_AVAILABLE_PAGES(pResultBuf)) {
availablePage = evicOneDataPage(pResultBuf); availablePage = evicOneDataPage(pResultBuf);
} }
...@@ -340,7 +342,7 @@ tFilePage* getResBufPage(SDiskbasedResultBuf* pResultBuf, int32_t id) { ...@@ -340,7 +342,7 @@ tFilePage* getResBufPage(SDiskbasedResultBuf* pResultBuf, int32_t id) {
assert((*pi)->pData == NULL && (*pi)->pn == NULL && (*pi)->info.length >= 0 && (*pi)->info.offset >= 0); assert((*pi)->pData == NULL && (*pi)->pn == NULL && (*pi)->info.length >= 0 && (*pi)->info.offset >= 0);
char* availablePage = NULL; char* availablePage = NULL;
if (NO_AVAILABLE_PAGES(pResultBuf)) { if (NO_IN_MEM_AVAILABLE_PAGES(pResultBuf)) {
availablePage = evicOneDataPage(pResultBuf); availablePage = evicOneDataPage(pResultBuf);
} }
...@@ -353,6 +355,8 @@ tFilePage* getResBufPage(SDiskbasedResultBuf* pResultBuf, int32_t id) { ...@@ -353,6 +355,8 @@ tFilePage* getResBufPage(SDiskbasedResultBuf* pResultBuf, int32_t id) {
((void**)((*pi)->pData))[0] = (*pi); ((void**)((*pi)->pData))[0] = (*pi);
lruListPushFront(pResultBuf->lruList, *pi); lruListPushFront(pResultBuf->lruList, *pi);
(*pi)->used = true;
loadPageFromDisk(pResultBuf, *pi); loadPageFromDisk(pResultBuf, *pi);
return GET_DATA_PAYLOAD(*pi); return GET_DATA_PAYLOAD(*pi);
} }
...@@ -396,12 +400,13 @@ void destroyResultBuf(SDiskbasedResultBuf* pResultBuf) { ...@@ -396,12 +400,13 @@ void destroyResultBuf(SDiskbasedResultBuf* pResultBuf) {
} }
if (pResultBuf->file != NULL) { if (pResultBuf->file != NULL) {
qDebug("QInfo:%p disk-based output buffer closed, total:%" PRId64 " bytes, file size:%"PRId64" bytes", qDebug("QInfo:%p res output buffer closed, total:%" PRId64 " bytes, inmem size:%dbytes, file size:%"PRId64" bytes",
pResultBuf->handle, pResultBuf->totalBufSize, pResultBuf->fileSize); pResultBuf->handle, pResultBuf->totalBufSize, listNEles(pResultBuf->lruList) * pResultBuf->pageSize,
pResultBuf->fileSize);
fclose(pResultBuf->file); fclose(pResultBuf->file);
} else { } else {
qDebug("QInfo:%p disk-based output buffer closed, total:%" PRId64 " bytes, no file created", pResultBuf->handle, qDebug("QInfo:%p res output buffer closed, total:%" PRId64 " bytes, no file created", pResultBuf->handle,
pResultBuf->totalBufSize); pResultBuf->totalBufSize);
} }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
// All the keywords of the SQL language are stored in a hash table // All the keywords of the SQL language are stored in a hash table
typedef struct SKeyword { typedef struct SKeyword {
const char* name; // The keyword name const char* name; // The keyword name
uint16_t type; // type uint16_t type; // type
uint8_t len; // length uint8_t len; // length
} SKeyword; } SKeyword;
...@@ -257,7 +257,7 @@ static void* KeywordHashTable = NULL; ...@@ -257,7 +257,7 @@ static void* KeywordHashTable = NULL;
static void doInitKeywordsTable(void) { static void doInitKeywordsTable(void) {
int numOfEntries = tListLen(keywordTable); int numOfEntries = tListLen(keywordTable);
KeywordHashTable = taosHashInit(numOfEntries, MurmurHash3_32, false); KeywordHashTable = taosHashInit(numOfEntries, MurmurHash3_32, true, false);
for (int32_t i = 0; i < numOfEntries; i++) { for (int32_t i = 0; i < numOfEntries; i++) {
keywordTable[i].len = (uint8_t)strlen(keywordTable[i].name); keywordTable[i].len = (uint8_t)strlen(keywordTable[i].name);
void* ptr = &keywordTable[i]; void* ptr = &keywordTable[i];
......
...@@ -72,6 +72,7 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) { ...@@ -72,6 +72,7 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) {
// invalid file // invalid file
if (header.magic != TS_COMP_FILE_MAGIC) { if (header.magic != TS_COMP_FILE_MAGIC) {
tsBufDestroy(pTSBuf);
return NULL; return NULL;
} }
......
...@@ -37,7 +37,7 @@ int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRun ...@@ -37,7 +37,7 @@ int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRun
pWindowResInfo->type = type; pWindowResInfo->type = type;
_hash_fn_t fn = taosGetDefaultHashFunction(type); _hash_fn_t fn = taosGetDefaultHashFunction(type);
pWindowResInfo->hashList = taosHashInit(threshold, fn, false); pWindowResInfo->hashList = taosHashInit(threshold, fn, true, false);
if (pWindowResInfo->hashList == NULL) { if (pWindowResInfo->hashList == NULL) {
return TSDB_CODE_QRY_OUT_OF_MEMORY; return TSDB_CODE_QRY_OUT_OF_MEMORY;
} }
...@@ -46,12 +46,17 @@ int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRun ...@@ -46,12 +46,17 @@ int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRun
pWindowResInfo->size = 0; pWindowResInfo->size = 0;
pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL; pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL;
pRuntimeEnv->summary.internalSupSize += sizeof(SWindowResult) * threshold;
// use the pointer arraylist // use the pointer arraylist
pWindowResInfo->pResult = calloc(threshold, sizeof(SWindowResult)); pWindowResInfo->pResult = calloc(threshold, sizeof(SWindowResult));
if (pWindowResInfo->pResult == NULL) { if (pWindowResInfo->pResult == NULL) {
return TSDB_CODE_QRY_OUT_OF_MEMORY; return TSDB_CODE_QRY_OUT_OF_MEMORY;
} }
pRuntimeEnv->summary.internalSupSize += sizeof(SWindowResult) * threshold;
pRuntimeEnv->summary.internalSupSize += (pRuntimeEnv->pQuery->numOfOutput * sizeof(SResultInfo) + pRuntimeEnv->interBufSize) * pWindowResInfo->capacity;
for (int32_t i = 0; i < pWindowResInfo->capacity; ++i) { for (int32_t i = 0; i < pWindowResInfo->capacity; ++i) {
int32_t code = createQueryResultInfo(pRuntimeEnv->pQuery, &pWindowResInfo->pResult[i], pRuntimeEnv->stableQuery, pRuntimeEnv->interBufSize); int32_t code = createQueryResultInfo(pRuntimeEnv->pQuery, &pWindowResInfo->pResult[i], pRuntimeEnv->stableQuery, pRuntimeEnv->interBufSize);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
...@@ -104,7 +109,7 @@ void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowR ...@@ -104,7 +109,7 @@ void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowR
pWindowResInfo->size = 0; pWindowResInfo->size = 0;
_hash_fn_t fn = taosGetDefaultHashFunction(pWindowResInfo->type); _hash_fn_t fn = taosGetDefaultHashFunction(pWindowResInfo->type);
pWindowResInfo->hashList = taosHashInit(pWindowResInfo->capacity, fn, false); pWindowResInfo->hashList = taosHashInit(pWindowResInfo->capacity, fn, true, false);
pWindowResInfo->startTime = TSKEY_INITIAL_VAL; pWindowResInfo->startTime = TSKEY_INITIAL_VAL;
pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL; pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL;
......
...@@ -126,17 +126,17 @@ typedef union { ...@@ -126,17 +126,17 @@ typedef union {
#define ParseARG_FETCH SSqlInfo* pInfo = yypParser->pInfo #define ParseARG_FETCH SSqlInfo* pInfo = yypParser->pInfo
#define ParseARG_STORE yypParser->pInfo = pInfo #define ParseARG_STORE yypParser->pInfo = pInfo
#define YYFALLBACK 1 #define YYFALLBACK 1
#define YYNSTATE 243 #define YYNSTATE 245
#define YYNRULE 226 #define YYNRULE 228
#define YYNTOKEN 207 #define YYNTOKEN 207
#define YY_MAX_SHIFT 242 #define YY_MAX_SHIFT 244
#define YY_MIN_SHIFTREDUCE 405 #define YY_MIN_SHIFTREDUCE 407
#define YY_MAX_SHIFTREDUCE 630 #define YY_MAX_SHIFTREDUCE 634
#define YY_ERROR_ACTION 631 #define YY_ERROR_ACTION 635
#define YY_ACCEPT_ACTION 632 #define YY_ACCEPT_ACTION 636
#define YY_NO_ACTION 633 #define YY_NO_ACTION 637
#define YY_MIN_REDUCE 634 #define YY_MIN_REDUCE 638
#define YY_MAX_REDUCE 859 #define YY_MAX_REDUCE 865
/************* End control #defines *******************************************/ /************* End control #defines *******************************************/
/* Define the yytestcase() macro to be a no-op if is not already defined /* Define the yytestcase() macro to be a no-op if is not already defined
...@@ -202,64 +202,64 @@ typedef union { ...@@ -202,64 +202,64 @@ typedef union {
** yy_default[] Default action for each state. ** yy_default[] Default action for each state.
** **
*********** Begin parsing tables **********************************************/ *********** Begin parsing tables **********************************************/
#define YY_ACTTAB_COUNT (552) #define YY_ACTTAB_COUNT (554)
static const YYACTIONTYPE yy_action[] = { static const YYACTIONTYPE yy_action[] = {
/* 0 */ 103, 446, 135, 673, 632, 242, 126, 515, 135, 447, /* 0 */ 105, 448, 137, 677, 636, 244, 128, 517, 137, 449,
/* 10 */ 135, 158, 847, 41, 43, 11, 35, 36, 846, 157, /* 10 */ 137, 160, 853, 41, 43, 11, 35, 36, 852, 159,
/* 20 */ 847, 29, 134, 446, 197, 39, 37, 40, 38, 155, /* 20 */ 853, 29, 136, 448, 199, 39, 37, 40, 38, 157,
/* 30 */ 103, 447, 139, 34, 33, 217, 216, 32, 31, 30, /* 30 */ 105, 449, 141, 34, 33, 219, 218, 32, 31, 30,
/* 40 */ 41, 43, 767, 35, 36, 32, 31, 30, 29, 756, /* 40 */ 41, 43, 771, 35, 36, 32, 31, 30, 29, 760,
/* 50 */ 446, 197, 39, 37, 40, 38, 182, 802, 447, 192, /* 50 */ 448, 199, 39, 37, 40, 38, 184, 808, 449, 194,
/* 60 */ 34, 33, 21, 21, 32, 31, 30, 406, 407, 408, /* 60 */ 34, 33, 21, 21, 32, 31, 30, 408, 409, 410,
/* 70 */ 409, 410, 411, 412, 413, 414, 415, 416, 417, 241, /* 70 */ 411, 412, 413, 414, 415, 416, 417, 418, 419, 243,
/* 80 */ 41, 43, 228, 35, 36, 194, 843, 58, 29, 21, /* 80 */ 41, 43, 230, 35, 36, 196, 849, 60, 29, 21,
/* 90 */ 842, 197, 39, 37, 40, 38, 166, 167, 753, 753, /* 90 */ 848, 199, 39, 37, 40, 38, 168, 169, 757, 757,
/* 100 */ 34, 33, 168, 56, 32, 31, 30, 778, 841, 16, /* 100 */ 34, 33, 170, 56, 32, 31, 30, 782, 847, 16,
/* 110 */ 235, 208, 234, 233, 207, 206, 205, 232, 204, 231, /* 110 */ 237, 210, 236, 235, 209, 208, 207, 234, 206, 233,
/* 120 */ 230, 229, 203, 215, 151, 753, 732, 586, 719, 720, /* 120 */ 232, 231, 205, 217, 153, 757, 736, 590, 723, 724,
/* 130 */ 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, /* 130 */ 725, 726, 727, 728, 729, 730, 731, 732, 733, 734,
/* 140 */ 731, 43, 8, 35, 36, 61, 113, 21, 29, 153, /* 140 */ 735, 43, 8, 35, 36, 63, 115, 21, 29, 155,
/* 150 */ 240, 197, 39, 37, 40, 38, 239, 238, 95, 775, /* 150 */ 242, 199, 39, 37, 40, 38, 241, 240, 97, 779,
/* 160 */ 34, 33, 165, 99, 32, 31, 30, 169, 35, 36, /* 160 */ 34, 33, 167, 101, 32, 31, 30, 171, 35, 36,
/* 170 */ 214, 213, 592, 29, 595, 103, 197, 39, 37, 40, /* 170 */ 216, 215, 596, 29, 599, 105, 199, 39, 37, 40,
/* 180 */ 38, 220, 756, 753, 236, 34, 33, 175, 12, 32, /* 180 */ 38, 222, 760, 757, 238, 34, 33, 177, 12, 32,
/* 190 */ 31, 30, 162, 599, 179, 178, 590, 767, 593, 103, /* 190 */ 31, 30, 164, 603, 181, 180, 594, 771, 597, 105,
/* 200 */ 596, 161, 162, 599, 756, 17, 590, 148, 593, 152, /* 200 */ 600, 163, 164, 603, 760, 17, 594, 150, 597, 154,
/* 210 */ 596, 154, 26, 88, 87, 142, 185, 567, 568, 16, /* 210 */ 600, 156, 26, 90, 89, 144, 187, 571, 572, 16,
/* 220 */ 235, 147, 234, 233, 159, 160, 219, 232, 196, 231, /* 220 */ 237, 149, 236, 235, 161, 162, 221, 234, 198, 233,
/* 230 */ 230, 229, 801, 76, 159, 160, 162, 599, 547, 228, /* 230 */ 232, 231, 807, 78, 161, 162, 164, 603, 549, 230,
/* 240 */ 590, 3, 593, 17, 596, 74, 78, 83, 86, 77, /* 240 */ 594, 3, 597, 17, 600, 76, 80, 85, 88, 79,
/* 250 */ 26, 39, 37, 40, 38, 80, 59, 754, 21, 34, /* 250 */ 26, 39, 37, 40, 38, 82, 61, 758, 21, 34,
/* 260 */ 33, 544, 60, 32, 31, 30, 18, 140, 159, 160, /* 260 */ 33, 546, 62, 32, 31, 30, 18, 142, 161, 162,
/* 270 */ 181, 737, 539, 736, 27, 734, 735, 150, 682, 184, /* 270 */ 183, 741, 541, 740, 27, 738, 739, 152, 686, 186,
/* 280 */ 738, 126, 740, 741, 739, 674, 531, 141, 126, 528, /* 280 */ 742, 128, 744, 745, 743, 678, 533, 143, 128, 530,
/* 290 */ 42, 529, 558, 530, 752, 591, 46, 594, 34, 33, /* 290 */ 42, 531, 562, 532, 756, 595, 46, 598, 34, 33,
/* 300 */ 42, 598, 32, 31, 30, 116, 117, 68, 64, 67, /* 300 */ 42, 602, 32, 31, 30, 118, 119, 70, 66, 69,
/* 310 */ 588, 598, 143, 50, 73, 72, 597, 170, 171, 130, /* 310 */ 592, 602, 145, 50, 75, 74, 601, 172, 173, 132,
/* 320 */ 128, 91, 90, 89, 98, 47, 597, 144, 559, 616, /* 320 */ 130, 93, 92, 91, 100, 47, 601, 146, 563, 620,
/* 330 */ 51, 26, 14, 13, 42, 145, 600, 521, 520, 201, /* 330 */ 51, 26, 14, 13, 42, 147, 604, 523, 522, 203,
/* 340 */ 13, 46, 22, 22, 48, 598, 589, 10, 9, 535, /* 340 */ 13, 46, 22, 22, 48, 602, 593, 10, 9, 537,
/* 350 */ 533, 536, 534, 85, 84, 146, 137, 133, 856, 138, /* 350 */ 535, 538, 536, 87, 86, 148, 139, 135, 862, 140,
/* 360 */ 597, 136, 755, 812, 811, 163, 808, 807, 164, 777, /* 360 */ 601, 138, 759, 818, 817, 165, 814, 813, 166, 781,
/* 370 */ 747, 218, 794, 100, 793, 769, 114, 115, 26, 684, /* 370 */ 751, 220, 800, 786, 788, 773, 102, 799, 26, 116,
/* 380 */ 112, 202, 131, 183, 24, 211, 681, 212, 855, 532, /* 380 */ 114, 117, 688, 185, 204, 133, 24, 213, 685, 534,
/* 390 */ 70, 854, 93, 852, 118, 702, 554, 25, 23, 132, /* 390 */ 214, 861, 95, 72, 860, 858, 558, 120, 706, 25,
/* 400 */ 671, 79, 52, 186, 669, 81, 82, 667, 666, 172, /* 400 */ 23, 134, 52, 188, 675, 81, 673, 83, 84, 671,
/* 410 */ 127, 664, 190, 663, 662, 661, 660, 652, 129, 658, /* 410 */ 670, 174, 192, 129, 668, 667, 666, 665, 664, 656,
/* 420 */ 49, 656, 654, 766, 781, 782, 795, 104, 195, 44, /* 420 */ 49, 131, 662, 660, 658, 770, 57, 58, 801, 44,
/* 430 */ 193, 191, 189, 187, 210, 105, 75, 28, 221, 199, /* 430 */ 197, 195, 193, 191, 189, 28, 106, 212, 77, 223,
/* 440 */ 222, 223, 53, 225, 224, 149, 226, 62, 65, 703, /* 440 */ 224, 225, 226, 201, 53, 227, 228, 229, 239, 64,
/* 450 */ 227, 237, 630, 173, 174, 629, 177, 665, 628, 119, /* 450 */ 67, 634, 151, 175, 176, 633, 178, 179, 632, 669,
/* 460 */ 176, 92, 121, 125, 120, 751, 122, 123, 659, 124, /* 460 */ 186, 625, 94, 96, 123, 127, 2, 122, 707, 755,
/* 470 */ 108, 106, 107, 109, 110, 111, 94, 1, 2, 621, /* 470 */ 121, 124, 125, 111, 107, 108, 126, 109, 110, 112,
/* 480 */ 180, 184, 541, 55, 57, 555, 101, 156, 188, 198, /* 480 */ 663, 113, 182, 1, 543, 55, 59, 559, 103, 158,
/* 490 */ 19, 63, 5, 560, 102, 4, 6, 601, 20, 15, /* 490 */ 564, 5, 190, 104, 6, 65, 490, 605, 4, 19,
/* 500 */ 7, 488, 484, 200, 482, 481, 480, 477, 450, 209, /* 500 */ 20, 15, 200, 7, 202, 486, 484, 483, 482, 479,
/* 510 */ 66, 45, 22, 69, 71, 517, 516, 514, 471, 54, /* 510 */ 452, 211, 68, 45, 22, 71, 73, 519, 518, 516,
/* 520 */ 469, 461, 467, 463, 465, 459, 457, 487, 486, 485, /* 520 */ 54, 473, 471, 463, 469, 465, 467, 461, 459, 489,
/* 530 */ 483, 479, 478, 476, 46, 448, 421, 419, 634, 633, /* 530 */ 488, 487, 485, 481, 480, 478, 46, 450, 423, 421,
/* 540 */ 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, /* 540 */ 638, 637, 637, 637, 637, 637, 637, 637, 637, 637,
/* 550 */ 96, 97, /* 550 */ 637, 637, 98, 99,
}; };
static const YYCODETYPE yy_lookahead[] = { static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 211, 1, 262, 215, 208, 209, 218, 5, 262, 9, /* 0 */ 211, 1, 262, 215, 208, 209, 218, 5, 262, 9,
...@@ -299,25 +299,25 @@ static const YYCODETYPE yy_lookahead[] = { ...@@ -299,25 +299,25 @@ static const YYCODETYPE yy_lookahead[] = {
/* 340 */ 104, 104, 104, 104, 123, 110, 37, 129, 130, 5, /* 340 */ 104, 104, 104, 104, 123, 110, 37, 129, 130, 5,
/* 350 */ 5, 7, 7, 72, 73, 262, 262, 262, 248, 262, /* 350 */ 5, 7, 7, 72, 73, 262, 262, 262, 248, 262,
/* 360 */ 125, 262, 248, 243, 243, 243, 243, 243, 243, 211, /* 360 */ 125, 262, 248, 243, 243, 243, 243, 243, 243, 211,
/* 370 */ 244, 243, 269, 211, 269, 246, 211, 211, 106, 211, /* 370 */ 244, 243, 269, 211, 211, 246, 211, 269, 106, 211,
/* 380 */ 250, 211, 211, 246, 211, 211, 211, 211, 211, 105, /* 380 */ 250, 211, 211, 246, 211, 211, 211, 211, 211, 105,
/* 390 */ 211, 211, 59, 211, 211, 211, 110, 211, 211, 211, /* 390 */ 211, 211, 59, 211, 211, 211, 110, 211, 211, 211,
/* 400 */ 211, 211, 120, 265, 211, 211, 211, 211, 211, 211, /* 400 */ 211, 211, 120, 265, 211, 211, 211, 211, 211, 211,
/* 410 */ 211, 211, 265, 211, 211, 211, 211, 211, 211, 211, /* 410 */ 211, 211, 265, 211, 211, 211, 211, 211, 211, 211,
/* 420 */ 122, 211, 211, 259, 212, 212, 212, 258, 114, 119, /* 420 */ 122, 211, 211, 211, 211, 259, 212, 212, 212, 119,
/* 430 */ 118, 113, 112, 111, 75, 257, 84, 124, 83, 212, /* 430 */ 114, 118, 113, 112, 111, 124, 258, 75, 84, 83,
/* 440 */ 49, 80, 212, 53, 82, 212, 81, 216, 216, 226, /* 440 */ 49, 80, 82, 212, 212, 53, 81, 79, 75, 216,
/* 450 */ 79, 75, 5, 136, 5, 5, 5, 212, 5, 225, /* 450 */ 216, 5, 212, 136, 5, 5, 136, 5, 5, 212,
/* 460 */ 136, 213, 220, 219, 224, 246, 223, 221, 212, 222, /* 460 */ 107, 87, 213, 213, 220, 219, 214, 224, 226, 246,
/* 470 */ 254, 256, 255, 253, 252, 251, 213, 217, 214, 87, /* 470 */ 225, 223, 221, 253, 257, 256, 222, 255, 254, 252,
/* 480 */ 127, 107, 100, 108, 104, 100, 99, 1, 99, 101, /* 480 */ 212, 251, 127, 217, 100, 108, 104, 100, 99, 1,
/* 490 */ 104, 72, 115, 100, 99, 99, 115, 100, 104, 99, /* 490 */ 100, 115, 99, 99, 115, 72, 9, 100, 99, 104,
/* 500 */ 99, 9, 5, 101, 5, 5, 5, 5, 76, 15, /* 500 */ 104, 99, 101, 99, 101, 5, 5, 5, 5, 5,
/* 510 */ 72, 16, 104, 130, 130, 5, 5, 100, 5, 99, /* 510 */ 76, 15, 72, 16, 104, 130, 130, 5, 5, 100,
/* 520 */ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, /* 520 */ 99, 5, 5, 5, 5, 5, 5, 5, 5, 5,
/* 530 */ 5, 5, 5, 5, 104, 76, 59, 58, 0, 273, /* 530 */ 5, 5, 5, 5, 5, 5, 104, 76, 59, 58,
/* 540 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, /* 540 */ 0, 273, 273, 273, 273, 273, 273, 273, 273, 273,
/* 550 */ 21, 21, 273, 273, 273, 273, 273, 273, 273, 273, /* 550 */ 273, 273, 21, 21, 273, 273, 273, 273, 273, 273,
/* 560 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, /* 560 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273,
/* 570 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, /* 570 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273,
/* 580 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, /* 580 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273,
...@@ -337,83 +337,84 @@ static const YYCODETYPE yy_lookahead[] = { ...@@ -337,83 +337,84 @@ static const YYCODETYPE yy_lookahead[] = {
/* 720 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, /* 720 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273,
/* 730 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, /* 730 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273,
/* 740 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, /* 740 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273,
/* 750 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, /* 750 */ 273, 273, 273, 273, 273, 273, 273, 273, 273, 273,
/* 760 */ 273,
}; };
#define YY_SHIFT_COUNT (242) #define YY_SHIFT_COUNT (244)
#define YY_SHIFT_MIN (0) #define YY_SHIFT_MIN (0)
#define YY_SHIFT_MAX (538) #define YY_SHIFT_MAX (540)
static const unsigned short int yy_shift_ofst[] = { static const unsigned short int yy_shift_ofst[] = {
/* 0 */ 144, 24, 134, 191, 235, 49, 49, 49, 49, 49, /* 0 */ 144, 24, 134, 191, 235, 49, 49, 49, 49, 49,
/* 10 */ 49, 0, 22, 235, 284, 284, 284, 106, 49, 49, /* 10 */ 49, 0, 22, 235, 284, 284, 284, 106, 49, 49,
/* 20 */ 49, 49, 49, 161, 4, 4, 552, 201, 235, 235, /* 20 */ 49, 49, 49, 161, 4, 4, 554, 201, 235, 235,
/* 30 */ 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, /* 30 */ 235, 235, 235, 235, 235, 235, 235, 235, 235, 235,
/* 40 */ 235, 235, 235, 235, 235, 284, 284, 2, 2, 2, /* 40 */ 235, 235, 235, 235, 235, 284, 284, 2, 2, 2,
/* 50 */ 2, 2, 2, 43, 2, 225, 49, 49, 101, 101, /* 50 */ 2, 2, 2, 43, 2, 225, 49, 49, 49, 49,
/* 60 */ 157, 49, 49, 49, 49, 49, 49, 49, 49, 49, /* 60 */ 101, 101, 157, 49, 49, 49, 49, 49, 49, 49,
/* 70 */ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, /* 70 */ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
/* 80 */ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, /* 80 */ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
/* 90 */ 49, 49, 49, 49, 49, 49, 49, 49, 272, 333, /* 90 */ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
/* 100 */ 333, 286, 286, 333, 282, 298, 310, 314, 312, 318, /* 100 */ 272, 333, 333, 286, 286, 333, 282, 298, 310, 316,
/* 110 */ 320, 322, 313, 272, 333, 333, 359, 359, 333, 352, /* 110 */ 313, 319, 321, 323, 311, 272, 333, 333, 362, 362,
/* 120 */ 355, 391, 361, 362, 390, 365, 371, 333, 376, 333, /* 120 */ 333, 354, 356, 391, 361, 360, 392, 365, 368, 333,
/* 130 */ 376, 552, 552, 27, 67, 67, 67, 127, 152, 226, /* 130 */ 373, 333, 373, 554, 554, 27, 67, 67, 67, 127,
/* 140 */ 226, 226, 181, 265, 265, 265, 265, 241, 255, 39, /* 140 */ 152, 226, 226, 226, 181, 265, 265, 265, 265, 241,
/* 150 */ 60, 8, 8, 96, 172, 192, 228, 229, 236, 167, /* 150 */ 255, 39, 60, 8, 8, 96, 172, 192, 228, 229,
/* 160 */ 290, 309, 142, 221, 209, 237, 238, 239, 185, 218, /* 160 */ 236, 167, 290, 309, 142, 221, 209, 237, 238, 239,
/* 170 */ 344, 345, 281, 447, 317, 449, 450, 324, 451, 453, /* 170 */ 185, 218, 344, 345, 281, 446, 317, 449, 450, 320,
/* 180 */ 392, 353, 374, 382, 375, 380, 385, 387, 486, 389, /* 180 */ 452, 453, 374, 355, 353, 384, 377, 382, 387, 389,
/* 190 */ 393, 395, 386, 377, 394, 381, 397, 396, 400, 388, /* 190 */ 488, 393, 390, 394, 395, 376, 396, 379, 397, 399,
/* 200 */ 401, 402, 419, 492, 497, 499, 500, 501, 502, 432, /* 200 */ 402, 401, 404, 403, 423, 487, 500, 501, 502, 503,
/* 210 */ 494, 438, 495, 383, 384, 408, 510, 511, 417, 420, /* 210 */ 504, 434, 496, 440, 497, 385, 386, 410, 512, 513,
/* 220 */ 408, 513, 515, 516, 517, 518, 519, 520, 521, 522, /* 220 */ 419, 421, 410, 516, 517, 518, 519, 520, 521, 522,
/* 230 */ 523, 524, 525, 526, 527, 528, 430, 459, 529, 530, /* 230 */ 523, 524, 525, 526, 527, 528, 529, 530, 432, 461,
/* 240 */ 477, 479, 538, /* 240 */ 531, 532, 479, 481, 540,
}; };
#define YY_REDUCE_COUNT (132) #define YY_REDUCE_COUNT (134)
#define YY_REDUCE_MIN (-260) #define YY_REDUCE_MIN (-260)
#define YY_REDUCE_MAX (264) #define YY_REDUCE_MAX (268)
static const short yy_reduce_ofst[] = { static const short yy_reduce_ofst[] = {
/* 0 */ -204, -101, 44, -260, -252, -211, -181, -149, -148, -122, /* 0 */ -204, -101, 44, -260, -252, -211, -181, -149, -148, -122,
/* 10 */ -64, -104, -61, -254, -199, -66, -44, -49, -48, -36, /* 10 */ -64, -104, -61, -254, -199, -66, -44, -49, -48, -36,
/* 20 */ -12, 15, 47, -212, 63, 70, 13, -247, -240, -230, /* 20 */ -12, 15, 47, -212, 63, 70, 13, -247, -240, -230,
/* 30 */ -176, -172, -154, -138, -53, 5, 25, 50, 65, 73, /* 30 */ -176, -172, -154, -138, -53, 5, 25, 50, 65, 73,
/* 40 */ 93, 94, 95, 97, 99, 110, 114, 120, 121, 122, /* 40 */ 93, 94, 95, 97, 99, 110, 114, 120, 121, 122,
/* 50 */ 123, 124, 125, 126, 128, 129, 158, 162, 103, 105, /* 50 */ 123, 124, 125, 126, 128, 129, 158, 162, 163, 165,
/* 60 */ 130, 165, 166, 168, 170, 171, 173, 174, 175, 176, /* 60 */ 103, 108, 130, 168, 170, 171, 173, 174, 175, 176,
/* 70 */ 177, 179, 180, 182, 183, 184, 186, 187, 188, 189, /* 70 */ 177, 179, 180, 182, 183, 184, 186, 187, 188, 189,
/* 80 */ 190, 193, 194, 195, 196, 197, 198, 199, 200, 202, /* 80 */ 190, 193, 194, 195, 196, 197, 198, 199, 200, 202,
/* 90 */ 203, 204, 205, 206, 207, 208, 210, 211, 137, 212, /* 90 */ 203, 204, 205, 206, 207, 208, 210, 211, 212, 213,
/* 100 */ 213, 138, 147, 214, 164, 169, 178, 215, 217, 216, /* 100 */ 137, 214, 215, 138, 147, 216, 166, 178, 217, 219,
/* 110 */ 220, 222, 224, 219, 227, 230, 231, 232, 233, 223, /* 110 */ 222, 224, 220, 227, 230, 223, 231, 232, 233, 234,
/* 120 */ 234, 240, 242, 243, 246, 247, 244, 245, 248, 256, /* 120 */ 240, 242, 245, 243, 244, 248, 251, 254, 246, 247,
/* 130 */ 263, 260, 264, /* 130 */ 249, 268, 250, 266, 252,
}; };
static const YYACTIONTYPE yy_default[] = { static const YYACTIONTYPE yy_default[] = {
/* 0 */ 631, 683, 672, 849, 849, 631, 631, 631, 631, 631, /* 0 */ 635, 687, 676, 855, 855, 635, 635, 635, 635, 635,
/* 10 */ 631, 779, 649, 849, 631, 631, 631, 631, 631, 631, /* 10 */ 635, 783, 653, 855, 635, 635, 635, 635, 635, 635,
/* 20 */ 631, 631, 631, 685, 685, 685, 774, 631, 631, 631, /* 20 */ 635, 635, 635, 689, 689, 689, 778, 635, 635, 635,
/* 30 */ 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, /* 30 */ 635, 635, 635, 635, 635, 635, 635, 635, 635, 635,
/* 40 */ 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, /* 40 */ 635, 635, 635, 635, 635, 635, 635, 635, 635, 635,
/* 50 */ 631, 631, 631, 631, 631, 631, 631, 631, 798, 798, /* 50 */ 635, 635, 635, 635, 635, 635, 635, 785, 787, 635,
/* 60 */ 772, 631, 631, 631, 631, 631, 631, 631, 631, 631, /* 60 */ 804, 804, 776, 635, 635, 635, 635, 635, 635, 635,
/* 70 */ 631, 631, 631, 631, 631, 631, 631, 631, 631, 670, /* 70 */ 635, 635, 635, 635, 635, 635, 635, 635, 635, 635,
/* 80 */ 631, 668, 631, 631, 631, 631, 631, 631, 631, 631, /* 80 */ 635, 674, 635, 672, 635, 635, 635, 635, 635, 635,
/* 90 */ 631, 631, 631, 631, 631, 657, 631, 631, 631, 651, /* 90 */ 635, 635, 635, 635, 635, 635, 635, 661, 635, 635,
/* 100 */ 651, 631, 631, 651, 805, 809, 803, 791, 799, 790, /* 100 */ 635, 655, 655, 635, 635, 655, 811, 815, 809, 797,
/* 110 */ 786, 785, 813, 631, 651, 651, 680, 680, 651, 701, /* 110 */ 805, 796, 792, 791, 819, 635, 655, 655, 684, 684,
/* 120 */ 699, 697, 689, 695, 691, 693, 687, 651, 678, 651, /* 120 */ 655, 705, 703, 701, 693, 699, 695, 697, 691, 655,
/* 130 */ 678, 718, 733, 631, 814, 848, 804, 832, 831, 844, /* 130 */ 682, 655, 682, 722, 737, 635, 820, 854, 810, 838,
/* 140 */ 838, 837, 631, 836, 835, 834, 833, 631, 631, 631, /* 140 */ 837, 850, 844, 843, 635, 842, 841, 840, 839, 635,
/* 150 */ 631, 840, 839, 631, 631, 631, 631, 631, 631, 631, /* 150 */ 635, 635, 635, 846, 845, 635, 635, 635, 635, 635,
/* 160 */ 631, 631, 816, 810, 806, 631, 631, 631, 631, 631, /* 160 */ 635, 635, 635, 635, 822, 816, 812, 635, 635, 635,
/* 170 */ 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, /* 170 */ 635, 635, 635, 635, 635, 635, 635, 635, 635, 635,
/* 180 */ 631, 631, 771, 631, 631, 780, 631, 631, 631, 631, /* 180 */ 635, 635, 635, 635, 775, 635, 635, 784, 635, 635,
/* 190 */ 631, 631, 800, 631, 792, 631, 631, 631, 631, 631, /* 190 */ 635, 635, 635, 635, 806, 635, 798, 635, 635, 635,
/* 200 */ 631, 748, 631, 631, 631, 631, 631, 631, 631, 631, /* 200 */ 635, 635, 635, 752, 635, 635, 635, 635, 635, 635,
/* 210 */ 631, 631, 631, 631, 631, 853, 631, 631, 631, 742, /* 210 */ 635, 635, 635, 635, 635, 635, 635, 859, 635, 635,
/* 220 */ 851, 631, 631, 631, 631, 631, 631, 631, 631, 631, /* 220 */ 635, 746, 857, 635, 635, 635, 635, 635, 635, 635,
/* 230 */ 631, 631, 631, 631, 631, 631, 704, 631, 655, 653, /* 230 */ 635, 635, 635, 635, 635, 635, 635, 635, 708, 635,
/* 240 */ 631, 647, 631, /* 240 */ 659, 657, 635, 651, 635,
}; };
/********** End of lemon-generated parsing tables *****************************/ /********** End of lemon-generated parsing tables *****************************/
...@@ -1154,84 +1155,86 @@ static const char *const yyRuleName[] = { ...@@ -1154,84 +1155,86 @@ static const char *const yyRuleName[] = {
/* 145 */ "as ::=", /* 145 */ "as ::=",
/* 146 */ "from ::= FROM tablelist", /* 146 */ "from ::= FROM tablelist",
/* 147 */ "tablelist ::= ids cpxName", /* 147 */ "tablelist ::= ids cpxName",
/* 148 */ "tablelist ::= tablelist COMMA ids cpxName", /* 148 */ "tablelist ::= ids cpxName ids",
/* 149 */ "tmvar ::= VARIABLE", /* 149 */ "tablelist ::= tablelist COMMA ids cpxName",
/* 150 */ "interval_opt ::= INTERVAL LP tmvar RP", /* 150 */ "tablelist ::= tablelist COMMA ids cpxName ids",
/* 151 */ "interval_opt ::=", /* 151 */ "tmvar ::= VARIABLE",
/* 152 */ "fill_opt ::=", /* 152 */ "interval_opt ::= INTERVAL LP tmvar RP",
/* 153 */ "fill_opt ::= FILL LP ID COMMA tagitemlist RP", /* 153 */ "interval_opt ::=",
/* 154 */ "fill_opt ::= FILL LP ID RP", /* 154 */ "fill_opt ::=",
/* 155 */ "sliding_opt ::= SLIDING LP tmvar RP", /* 155 */ "fill_opt ::= FILL LP ID COMMA tagitemlist RP",
/* 156 */ "sliding_opt ::=", /* 156 */ "fill_opt ::= FILL LP ID RP",
/* 157 */ "orderby_opt ::=", /* 157 */ "sliding_opt ::= SLIDING LP tmvar RP",
/* 158 */ "orderby_opt ::= ORDER BY sortlist", /* 158 */ "sliding_opt ::=",
/* 159 */ "sortlist ::= sortlist COMMA item sortorder", /* 159 */ "orderby_opt ::=",
/* 160 */ "sortlist ::= item sortorder", /* 160 */ "orderby_opt ::= ORDER BY sortlist",
/* 161 */ "item ::= ids cpxName", /* 161 */ "sortlist ::= sortlist COMMA item sortorder",
/* 162 */ "sortorder ::= ASC", /* 162 */ "sortlist ::= item sortorder",
/* 163 */ "sortorder ::= DESC", /* 163 */ "item ::= ids cpxName",
/* 164 */ "sortorder ::=", /* 164 */ "sortorder ::= ASC",
/* 165 */ "groupby_opt ::=", /* 165 */ "sortorder ::= DESC",
/* 166 */ "groupby_opt ::= GROUP BY grouplist", /* 166 */ "sortorder ::=",
/* 167 */ "grouplist ::= grouplist COMMA item", /* 167 */ "groupby_opt ::=",
/* 168 */ "grouplist ::= item", /* 168 */ "groupby_opt ::= GROUP BY grouplist",
/* 169 */ "having_opt ::=", /* 169 */ "grouplist ::= grouplist COMMA item",
/* 170 */ "having_opt ::= HAVING expr", /* 170 */ "grouplist ::= item",
/* 171 */ "limit_opt ::=", /* 171 */ "having_opt ::=",
/* 172 */ "limit_opt ::= LIMIT signed", /* 172 */ "having_opt ::= HAVING expr",
/* 173 */ "limit_opt ::= LIMIT signed OFFSET signed", /* 173 */ "limit_opt ::=",
/* 174 */ "limit_opt ::= LIMIT signed COMMA signed", /* 174 */ "limit_opt ::= LIMIT signed",
/* 175 */ "slimit_opt ::=", /* 175 */ "limit_opt ::= LIMIT signed OFFSET signed",
/* 176 */ "slimit_opt ::= SLIMIT signed", /* 176 */ "limit_opt ::= LIMIT signed COMMA signed",
/* 177 */ "slimit_opt ::= SLIMIT signed SOFFSET signed", /* 177 */ "slimit_opt ::=",
/* 178 */ "slimit_opt ::= SLIMIT signed COMMA signed", /* 178 */ "slimit_opt ::= SLIMIT signed",
/* 179 */ "where_opt ::=", /* 179 */ "slimit_opt ::= SLIMIT signed SOFFSET signed",
/* 180 */ "where_opt ::= WHERE expr", /* 180 */ "slimit_opt ::= SLIMIT signed COMMA signed",
/* 181 */ "expr ::= LP expr RP", /* 181 */ "where_opt ::=",
/* 182 */ "expr ::= ID", /* 182 */ "where_opt ::= WHERE expr",
/* 183 */ "expr ::= ID DOT ID", /* 183 */ "expr ::= LP expr RP",
/* 184 */ "expr ::= ID DOT STAR", /* 184 */ "expr ::= ID",
/* 185 */ "expr ::= INTEGER", /* 185 */ "expr ::= ID DOT ID",
/* 186 */ "expr ::= MINUS INTEGER", /* 186 */ "expr ::= ID DOT STAR",
/* 187 */ "expr ::= PLUS INTEGER", /* 187 */ "expr ::= INTEGER",
/* 188 */ "expr ::= FLOAT", /* 188 */ "expr ::= MINUS INTEGER",
/* 189 */ "expr ::= MINUS FLOAT", /* 189 */ "expr ::= PLUS INTEGER",
/* 190 */ "expr ::= PLUS FLOAT", /* 190 */ "expr ::= FLOAT",
/* 191 */ "expr ::= STRING", /* 191 */ "expr ::= MINUS FLOAT",
/* 192 */ "expr ::= NOW", /* 192 */ "expr ::= PLUS FLOAT",
/* 193 */ "expr ::= VARIABLE", /* 193 */ "expr ::= STRING",
/* 194 */ "expr ::= BOOL", /* 194 */ "expr ::= NOW",
/* 195 */ "expr ::= ID LP exprlist RP", /* 195 */ "expr ::= VARIABLE",
/* 196 */ "expr ::= ID LP STAR RP", /* 196 */ "expr ::= BOOL",
/* 197 */ "expr ::= expr AND expr", /* 197 */ "expr ::= ID LP exprlist RP",
/* 198 */ "expr ::= expr OR expr", /* 198 */ "expr ::= ID LP STAR RP",
/* 199 */ "expr ::= expr LT expr", /* 199 */ "expr ::= expr AND expr",
/* 200 */ "expr ::= expr GT expr", /* 200 */ "expr ::= expr OR expr",
/* 201 */ "expr ::= expr LE expr", /* 201 */ "expr ::= expr LT expr",
/* 202 */ "expr ::= expr GE expr", /* 202 */ "expr ::= expr GT expr",
/* 203 */ "expr ::= expr NE expr", /* 203 */ "expr ::= expr LE expr",
/* 204 */ "expr ::= expr EQ expr", /* 204 */ "expr ::= expr GE expr",
/* 205 */ "expr ::= expr PLUS expr", /* 205 */ "expr ::= expr NE expr",
/* 206 */ "expr ::= expr MINUS expr", /* 206 */ "expr ::= expr EQ expr",
/* 207 */ "expr ::= expr STAR expr", /* 207 */ "expr ::= expr PLUS expr",
/* 208 */ "expr ::= expr SLASH expr", /* 208 */ "expr ::= expr MINUS expr",
/* 209 */ "expr ::= expr REM expr", /* 209 */ "expr ::= expr STAR expr",
/* 210 */ "expr ::= expr LIKE expr", /* 210 */ "expr ::= expr SLASH expr",
/* 211 */ "expr ::= expr IN LP exprlist RP", /* 211 */ "expr ::= expr REM expr",
/* 212 */ "exprlist ::= exprlist COMMA expritem", /* 212 */ "expr ::= expr LIKE expr",
/* 213 */ "exprlist ::= expritem", /* 213 */ "expr ::= expr IN LP exprlist RP",
/* 214 */ "expritem ::= expr", /* 214 */ "exprlist ::= exprlist COMMA expritem",
/* 215 */ "expritem ::=", /* 215 */ "exprlist ::= expritem",
/* 216 */ "cmd ::= RESET QUERY CACHE", /* 216 */ "expritem ::= expr",
/* 217 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", /* 217 */ "expritem ::=",
/* 218 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", /* 218 */ "cmd ::= RESET QUERY CACHE",
/* 219 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", /* 219 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist",
/* 220 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", /* 220 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids",
/* 221 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", /* 221 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist",
/* 222 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", /* 222 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids",
/* 223 */ "cmd ::= KILL CONNECTION INTEGER", /* 223 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids",
/* 224 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", /* 224 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem",
/* 225 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER", /* 225 */ "cmd ::= KILL CONNECTION INTEGER",
/* 226 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER",
/* 227 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER",
}; };
#endif /* NDEBUG */ #endif /* NDEBUG */
...@@ -1837,84 +1840,86 @@ static const struct { ...@@ -1837,84 +1840,86 @@ static const struct {
{ 263, 0 }, /* (145) as ::= */ { 263, 0 }, /* (145) as ::= */
{ 250, -2 }, /* (146) from ::= FROM tablelist */ { 250, -2 }, /* (146) from ::= FROM tablelist */
{ 264, -2 }, /* (147) tablelist ::= ids cpxName */ { 264, -2 }, /* (147) tablelist ::= ids cpxName */
{ 264, -4 }, /* (148) tablelist ::= tablelist COMMA ids cpxName */ { 264, -3 }, /* (148) tablelist ::= ids cpxName ids */
{ 265, -1 }, /* (149) tmvar ::= VARIABLE */ { 264, -4 }, /* (149) tablelist ::= tablelist COMMA ids cpxName */
{ 252, -4 }, /* (150) interval_opt ::= INTERVAL LP tmvar RP */ { 264, -5 }, /* (150) tablelist ::= tablelist COMMA ids cpxName ids */
{ 252, 0 }, /* (151) interval_opt ::= */ { 265, -1 }, /* (151) tmvar ::= VARIABLE */
{ 253, 0 }, /* (152) fill_opt ::= */ { 252, -4 }, /* (152) interval_opt ::= INTERVAL LP tmvar RP */
{ 253, -6 }, /* (153) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ { 252, 0 }, /* (153) interval_opt ::= */
{ 253, -4 }, /* (154) fill_opt ::= FILL LP ID RP */ { 253, 0 }, /* (154) fill_opt ::= */
{ 254, -4 }, /* (155) sliding_opt ::= SLIDING LP tmvar RP */ { 253, -6 }, /* (155) fill_opt ::= FILL LP ID COMMA tagitemlist RP */
{ 254, 0 }, /* (156) sliding_opt ::= */ { 253, -4 }, /* (156) fill_opt ::= FILL LP ID RP */
{ 256, 0 }, /* (157) orderby_opt ::= */ { 254, -4 }, /* (157) sliding_opt ::= SLIDING LP tmvar RP */
{ 256, -3 }, /* (158) orderby_opt ::= ORDER BY sortlist */ { 254, 0 }, /* (158) sliding_opt ::= */
{ 266, -4 }, /* (159) sortlist ::= sortlist COMMA item sortorder */ { 256, 0 }, /* (159) orderby_opt ::= */
{ 266, -2 }, /* (160) sortlist ::= item sortorder */ { 256, -3 }, /* (160) orderby_opt ::= ORDER BY sortlist */
{ 268, -2 }, /* (161) item ::= ids cpxName */ { 266, -4 }, /* (161) sortlist ::= sortlist COMMA item sortorder */
{ 269, -1 }, /* (162) sortorder ::= ASC */ { 266, -2 }, /* (162) sortlist ::= item sortorder */
{ 269, -1 }, /* (163) sortorder ::= DESC */ { 268, -2 }, /* (163) item ::= ids cpxName */
{ 269, 0 }, /* (164) sortorder ::= */ { 269, -1 }, /* (164) sortorder ::= ASC */
{ 255, 0 }, /* (165) groupby_opt ::= */ { 269, -1 }, /* (165) sortorder ::= DESC */
{ 255, -3 }, /* (166) groupby_opt ::= GROUP BY grouplist */ { 269, 0 }, /* (166) sortorder ::= */
{ 270, -3 }, /* (167) grouplist ::= grouplist COMMA item */ { 255, 0 }, /* (167) groupby_opt ::= */
{ 270, -1 }, /* (168) grouplist ::= item */ { 255, -3 }, /* (168) groupby_opt ::= GROUP BY grouplist */
{ 257, 0 }, /* (169) having_opt ::= */ { 270, -3 }, /* (169) grouplist ::= grouplist COMMA item */
{ 257, -2 }, /* (170) having_opt ::= HAVING expr */ { 270, -1 }, /* (170) grouplist ::= item */
{ 259, 0 }, /* (171) limit_opt ::= */ { 257, 0 }, /* (171) having_opt ::= */
{ 259, -2 }, /* (172) limit_opt ::= LIMIT signed */ { 257, -2 }, /* (172) having_opt ::= HAVING expr */
{ 259, -4 }, /* (173) limit_opt ::= LIMIT signed OFFSET signed */ { 259, 0 }, /* (173) limit_opt ::= */
{ 259, -4 }, /* (174) limit_opt ::= LIMIT signed COMMA signed */ { 259, -2 }, /* (174) limit_opt ::= LIMIT signed */
{ 258, 0 }, /* (175) slimit_opt ::= */ { 259, -4 }, /* (175) limit_opt ::= LIMIT signed OFFSET signed */
{ 258, -2 }, /* (176) slimit_opt ::= SLIMIT signed */ { 259, -4 }, /* (176) limit_opt ::= LIMIT signed COMMA signed */
{ 258, -4 }, /* (177) slimit_opt ::= SLIMIT signed SOFFSET signed */ { 258, 0 }, /* (177) slimit_opt ::= */
{ 258, -4 }, /* (178) slimit_opt ::= SLIMIT signed COMMA signed */ { 258, -2 }, /* (178) slimit_opt ::= SLIMIT signed */
{ 251, 0 }, /* (179) where_opt ::= */ { 258, -4 }, /* (179) slimit_opt ::= SLIMIT signed SOFFSET signed */
{ 251, -2 }, /* (180) where_opt ::= WHERE expr */ { 258, -4 }, /* (180) slimit_opt ::= SLIMIT signed COMMA signed */
{ 262, -3 }, /* (181) expr ::= LP expr RP */ { 251, 0 }, /* (181) where_opt ::= */
{ 262, -1 }, /* (182) expr ::= ID */ { 251, -2 }, /* (182) where_opt ::= WHERE expr */
{ 262, -3 }, /* (183) expr ::= ID DOT ID */ { 262, -3 }, /* (183) expr ::= LP expr RP */
{ 262, -3 }, /* (184) expr ::= ID DOT STAR */ { 262, -1 }, /* (184) expr ::= ID */
{ 262, -1 }, /* (185) expr ::= INTEGER */ { 262, -3 }, /* (185) expr ::= ID DOT ID */
{ 262, -2 }, /* (186) expr ::= MINUS INTEGER */ { 262, -3 }, /* (186) expr ::= ID DOT STAR */
{ 262, -2 }, /* (187) expr ::= PLUS INTEGER */ { 262, -1 }, /* (187) expr ::= INTEGER */
{ 262, -1 }, /* (188) expr ::= FLOAT */ { 262, -2 }, /* (188) expr ::= MINUS INTEGER */
{ 262, -2 }, /* (189) expr ::= MINUS FLOAT */ { 262, -2 }, /* (189) expr ::= PLUS INTEGER */
{ 262, -2 }, /* (190) expr ::= PLUS FLOAT */ { 262, -1 }, /* (190) expr ::= FLOAT */
{ 262, -1 }, /* (191) expr ::= STRING */ { 262, -2 }, /* (191) expr ::= MINUS FLOAT */
{ 262, -1 }, /* (192) expr ::= NOW */ { 262, -2 }, /* (192) expr ::= PLUS FLOAT */
{ 262, -1 }, /* (193) expr ::= VARIABLE */ { 262, -1 }, /* (193) expr ::= STRING */
{ 262, -1 }, /* (194) expr ::= BOOL */ { 262, -1 }, /* (194) expr ::= NOW */
{ 262, -4 }, /* (195) expr ::= ID LP exprlist RP */ { 262, -1 }, /* (195) expr ::= VARIABLE */
{ 262, -4 }, /* (196) expr ::= ID LP STAR RP */ { 262, -1 }, /* (196) expr ::= BOOL */
{ 262, -3 }, /* (197) expr ::= expr AND expr */ { 262, -4 }, /* (197) expr ::= ID LP exprlist RP */
{ 262, -3 }, /* (198) expr ::= expr OR expr */ { 262, -4 }, /* (198) expr ::= ID LP STAR RP */
{ 262, -3 }, /* (199) expr ::= expr LT expr */ { 262, -3 }, /* (199) expr ::= expr AND expr */
{ 262, -3 }, /* (200) expr ::= expr GT expr */ { 262, -3 }, /* (200) expr ::= expr OR expr */
{ 262, -3 }, /* (201) expr ::= expr LE expr */ { 262, -3 }, /* (201) expr ::= expr LT expr */
{ 262, -3 }, /* (202) expr ::= expr GE expr */ { 262, -3 }, /* (202) expr ::= expr GT expr */
{ 262, -3 }, /* (203) expr ::= expr NE expr */ { 262, -3 }, /* (203) expr ::= expr LE expr */
{ 262, -3 }, /* (204) expr ::= expr EQ expr */ { 262, -3 }, /* (204) expr ::= expr GE expr */
{ 262, -3 }, /* (205) expr ::= expr PLUS expr */ { 262, -3 }, /* (205) expr ::= expr NE expr */
{ 262, -3 }, /* (206) expr ::= expr MINUS expr */ { 262, -3 }, /* (206) expr ::= expr EQ expr */
{ 262, -3 }, /* (207) expr ::= expr STAR expr */ { 262, -3 }, /* (207) expr ::= expr PLUS expr */
{ 262, -3 }, /* (208) expr ::= expr SLASH expr */ { 262, -3 }, /* (208) expr ::= expr MINUS expr */
{ 262, -3 }, /* (209) expr ::= expr REM expr */ { 262, -3 }, /* (209) expr ::= expr STAR expr */
{ 262, -3 }, /* (210) expr ::= expr LIKE expr */ { 262, -3 }, /* (210) expr ::= expr SLASH expr */
{ 262, -5 }, /* (211) expr ::= expr IN LP exprlist RP */ { 262, -3 }, /* (211) expr ::= expr REM expr */
{ 271, -3 }, /* (212) exprlist ::= exprlist COMMA expritem */ { 262, -3 }, /* (212) expr ::= expr LIKE expr */
{ 271, -1 }, /* (213) exprlist ::= expritem */ { 262, -5 }, /* (213) expr ::= expr IN LP exprlist RP */
{ 272, -1 }, /* (214) expritem ::= expr */ { 271, -3 }, /* (214) exprlist ::= exprlist COMMA expritem */
{ 272, 0 }, /* (215) expritem ::= */ { 271, -1 }, /* (215) exprlist ::= expritem */
{ 209, -3 }, /* (216) cmd ::= RESET QUERY CACHE */ { 272, -1 }, /* (216) expritem ::= expr */
{ 209, -7 }, /* (217) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ { 272, 0 }, /* (217) expritem ::= */
{ 209, -7 }, /* (218) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ { 209, -3 }, /* (218) cmd ::= RESET QUERY CACHE */
{ 209, -7 }, /* (219) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ { 209, -7 }, /* (219) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */
{ 209, -7 }, /* (220) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ { 209, -7 }, /* (220) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */
{ 209, -8 }, /* (221) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ { 209, -7 }, /* (221) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */
{ 209, -9 }, /* (222) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ { 209, -7 }, /* (222) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */
{ 209, -3 }, /* (223) cmd ::= KILL CONNECTION INTEGER */ { 209, -8 }, /* (223) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */
{ 209, -5 }, /* (224) cmd ::= KILL STREAM INTEGER COLON INTEGER */ { 209, -9 }, /* (224) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */
{ 209, -5 }, /* (225) cmd ::= KILL QUERY INTEGER COLON INTEGER */ { 209, -3 }, /* (225) cmd ::= KILL CONNECTION INTEGER */
{ 209, -5 }, /* (226) cmd ::= KILL STREAM INTEGER COLON INTEGER */
{ 209, -5 }, /* (227) cmd ::= KILL QUERY INTEGER COLON INTEGER */
}; };
static void yy_accept(yyParser*); /* Forward Declaration */ static void yy_accept(yyParser*); /* Forward Declaration */
...@@ -2465,29 +2470,59 @@ static void yy_reduce( ...@@ -2465,29 +2470,59 @@ static void yy_reduce(
{yymsp[-1].minor.yy498 = yymsp[0].minor.yy498;} {yymsp[-1].minor.yy498 = yymsp[0].minor.yy498;}
break; break;
case 147: /* tablelist ::= ids cpxName */ case 147: /* tablelist ::= ids cpxName */
{ toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yylhsminor.yy498 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1);} {
toTSDBType(yymsp[-1].minor.yy0.type);
yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n;
yylhsminor.yy498 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1);
yylhsminor.yy498 = tVariantListAppendToken(yylhsminor.yy498, &yymsp[-1].minor.yy0, -1); // table alias name
}
yymsp[-1].minor.yy498 = yylhsminor.yy498; yymsp[-1].minor.yy498 = yylhsminor.yy498;
break; break;
case 148: /* tablelist ::= tablelist COMMA ids cpxName */ case 148: /* tablelist ::= ids cpxName ids */
{ toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yylhsminor.yy498 = tVariantListAppendToken(yymsp[-3].minor.yy498, &yymsp[-1].minor.yy0, -1); } {
toTSDBType(yymsp[-2].minor.yy0.type);
toTSDBType(yymsp[0].minor.yy0.type);
yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n;
yylhsminor.yy498 = tVariantListAppendToken(NULL, &yymsp[-2].minor.yy0, -1);
yylhsminor.yy498 = tVariantListAppendToken(yylhsminor.yy498, &yymsp[0].minor.yy0, -1);
}
yymsp[-2].minor.yy498 = yylhsminor.yy498;
break;
case 149: /* tablelist ::= tablelist COMMA ids cpxName */
{
toTSDBType(yymsp[-1].minor.yy0.type);
yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n;
yylhsminor.yy498 = tVariantListAppendToken(yymsp[-3].minor.yy498, &yymsp[-1].minor.yy0, -1);
yylhsminor.yy498 = tVariantListAppendToken(yylhsminor.yy498, &yymsp[-1].minor.yy0, -1);
}
yymsp[-3].minor.yy498 = yylhsminor.yy498; yymsp[-3].minor.yy498 = yylhsminor.yy498;
break; break;
case 149: /* tmvar ::= VARIABLE */ case 150: /* tablelist ::= tablelist COMMA ids cpxName ids */
{
toTSDBType(yymsp[-2].minor.yy0.type);
toTSDBType(yymsp[0].minor.yy0.type);
yymsp[-2].minor.yy0.n += yymsp[-1].minor.yy0.n;
yylhsminor.yy498 = tVariantListAppendToken(yymsp[-4].minor.yy498, &yymsp[-2].minor.yy0, -1);
yylhsminor.yy498 = tVariantListAppendToken(yylhsminor.yy498, &yymsp[0].minor.yy0, -1);
}
yymsp[-4].minor.yy498 = yylhsminor.yy498;
break;
case 151: /* tmvar ::= VARIABLE */
{yylhsminor.yy0 = yymsp[0].minor.yy0;} {yylhsminor.yy0 = yymsp[0].minor.yy0;}
yymsp[0].minor.yy0 = yylhsminor.yy0; yymsp[0].minor.yy0 = yylhsminor.yy0;
break; break;
case 150: /* interval_opt ::= INTERVAL LP tmvar RP */ case 152: /* interval_opt ::= INTERVAL LP tmvar RP */
case 155: /* sliding_opt ::= SLIDING LP tmvar RP */ yytestcase(yyruleno==155); case 157: /* sliding_opt ::= SLIDING LP tmvar RP */ yytestcase(yyruleno==157);
{yymsp[-3].minor.yy0 = yymsp[-1].minor.yy0; } {yymsp[-3].minor.yy0 = yymsp[-1].minor.yy0; }
break; break;
case 151: /* interval_opt ::= */ case 153: /* interval_opt ::= */
case 156: /* sliding_opt ::= */ yytestcase(yyruleno==156); case 158: /* sliding_opt ::= */ yytestcase(yyruleno==158);
{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = NULL; yymsp[1].minor.yy0.type = 0; } {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = NULL; yymsp[1].minor.yy0.type = 0; }
break; break;
case 152: /* fill_opt ::= */ case 154: /* fill_opt ::= */
{yymsp[1].minor.yy498 = 0; } {yymsp[1].minor.yy498 = 0; }
break; break;
case 153: /* fill_opt ::= FILL LP ID COMMA tagitemlist RP */ case 155: /* fill_opt ::= FILL LP ID COMMA tagitemlist RP */
{ {
tVariant A = {0}; tVariant A = {0};
toTSDBType(yymsp[-3].minor.yy0.type); toTSDBType(yymsp[-3].minor.yy0.type);
...@@ -2497,33 +2532,33 @@ static void yy_reduce( ...@@ -2497,33 +2532,33 @@ static void yy_reduce(
yymsp[-5].minor.yy498 = yymsp[-1].minor.yy498; yymsp[-5].minor.yy498 = yymsp[-1].minor.yy498;
} }
break; break;
case 154: /* fill_opt ::= FILL LP ID RP */ case 156: /* fill_opt ::= FILL LP ID RP */
{ {
toTSDBType(yymsp[-1].minor.yy0.type); toTSDBType(yymsp[-1].minor.yy0.type);
yymsp[-3].minor.yy498 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); yymsp[-3].minor.yy498 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1);
} }
break; break;
case 157: /* orderby_opt ::= */ case 159: /* orderby_opt ::= */
case 165: /* groupby_opt ::= */ yytestcase(yyruleno==165); case 167: /* groupby_opt ::= */ yytestcase(yyruleno==167);
{yymsp[1].minor.yy498 = 0;} {yymsp[1].minor.yy498 = 0;}
break; break;
case 158: /* orderby_opt ::= ORDER BY sortlist */ case 160: /* orderby_opt ::= ORDER BY sortlist */
case 166: /* groupby_opt ::= GROUP BY grouplist */ yytestcase(yyruleno==166); case 168: /* groupby_opt ::= GROUP BY grouplist */ yytestcase(yyruleno==168);
{yymsp[-2].minor.yy498 = yymsp[0].minor.yy498;} {yymsp[-2].minor.yy498 = yymsp[0].minor.yy498;}
break; break;
case 159: /* sortlist ::= sortlist COMMA item sortorder */ case 161: /* sortlist ::= sortlist COMMA item sortorder */
{ {
yylhsminor.yy498 = tVariantListAppend(yymsp[-3].minor.yy498, &yymsp[-1].minor.yy134, yymsp[0].minor.yy46); yylhsminor.yy498 = tVariantListAppend(yymsp[-3].minor.yy498, &yymsp[-1].minor.yy134, yymsp[0].minor.yy46);
} }
yymsp[-3].minor.yy498 = yylhsminor.yy498; yymsp[-3].minor.yy498 = yylhsminor.yy498;
break; break;
case 160: /* sortlist ::= item sortorder */ case 162: /* sortlist ::= item sortorder */
{ {
yylhsminor.yy498 = tVariantListAppend(NULL, &yymsp[-1].minor.yy134, yymsp[0].minor.yy46); yylhsminor.yy498 = tVariantListAppend(NULL, &yymsp[-1].minor.yy134, yymsp[0].minor.yy46);
} }
yymsp[-1].minor.yy498 = yylhsminor.yy498; yymsp[-1].minor.yy498 = yylhsminor.yy498;
break; break;
case 161: /* item ::= ids cpxName */ case 163: /* item ::= ids cpxName */
{ {
toTSDBType(yymsp[-1].minor.yy0.type); toTSDBType(yymsp[-1].minor.yy0.type);
yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n;
...@@ -2532,196 +2567,196 @@ static void yy_reduce( ...@@ -2532,196 +2567,196 @@ static void yy_reduce(
} }
yymsp[-1].minor.yy134 = yylhsminor.yy134; yymsp[-1].minor.yy134 = yylhsminor.yy134;
break; break;
case 162: /* sortorder ::= ASC */ case 164: /* sortorder ::= ASC */
{yymsp[0].minor.yy46 = TSDB_ORDER_ASC; } {yymsp[0].minor.yy46 = TSDB_ORDER_ASC; }
break; break;
case 163: /* sortorder ::= DESC */ case 165: /* sortorder ::= DESC */
{yymsp[0].minor.yy46 = TSDB_ORDER_DESC;} {yymsp[0].minor.yy46 = TSDB_ORDER_DESC;}
break; break;
case 164: /* sortorder ::= */ case 166: /* sortorder ::= */
{yymsp[1].minor.yy46 = TSDB_ORDER_ASC;} {yymsp[1].minor.yy46 = TSDB_ORDER_ASC;}
break; break;
case 167: /* grouplist ::= grouplist COMMA item */ case 169: /* grouplist ::= grouplist COMMA item */
{ {
yylhsminor.yy498 = tVariantListAppend(yymsp[-2].minor.yy498, &yymsp[0].minor.yy134, -1); yylhsminor.yy498 = tVariantListAppend(yymsp[-2].minor.yy498, &yymsp[0].minor.yy134, -1);
} }
yymsp[-2].minor.yy498 = yylhsminor.yy498; yymsp[-2].minor.yy498 = yylhsminor.yy498;
break; break;
case 168: /* grouplist ::= item */ case 170: /* grouplist ::= item */
{ {
yylhsminor.yy498 = tVariantListAppend(NULL, &yymsp[0].minor.yy134, -1); yylhsminor.yy498 = tVariantListAppend(NULL, &yymsp[0].minor.yy134, -1);
} }
yymsp[0].minor.yy498 = yylhsminor.yy498; yymsp[0].minor.yy498 = yylhsminor.yy498;
break; break;
case 169: /* having_opt ::= */ case 171: /* having_opt ::= */
case 179: /* where_opt ::= */ yytestcase(yyruleno==179); case 181: /* where_opt ::= */ yytestcase(yyruleno==181);
case 215: /* expritem ::= */ yytestcase(yyruleno==215); case 217: /* expritem ::= */ yytestcase(yyruleno==217);
{yymsp[1].minor.yy64 = 0;} {yymsp[1].minor.yy64 = 0;}
break; break;
case 170: /* having_opt ::= HAVING expr */ case 172: /* having_opt ::= HAVING expr */
case 180: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==180); case 182: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==182);
{yymsp[-1].minor.yy64 = yymsp[0].minor.yy64;} {yymsp[-1].minor.yy64 = yymsp[0].minor.yy64;}
break; break;
case 171: /* limit_opt ::= */ case 173: /* limit_opt ::= */
case 175: /* slimit_opt ::= */ yytestcase(yyruleno==175); case 177: /* slimit_opt ::= */ yytestcase(yyruleno==177);
{yymsp[1].minor.yy216.limit = -1; yymsp[1].minor.yy216.offset = 0;} {yymsp[1].minor.yy216.limit = -1; yymsp[1].minor.yy216.offset = 0;}
break; break;
case 172: /* limit_opt ::= LIMIT signed */ case 174: /* limit_opt ::= LIMIT signed */
case 176: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==176); case 178: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==178);
{yymsp[-1].minor.yy216.limit = yymsp[0].minor.yy207; yymsp[-1].minor.yy216.offset = 0;} {yymsp[-1].minor.yy216.limit = yymsp[0].minor.yy207; yymsp[-1].minor.yy216.offset = 0;}
break; break;
case 173: /* limit_opt ::= LIMIT signed OFFSET signed */ case 175: /* limit_opt ::= LIMIT signed OFFSET signed */
case 177: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ yytestcase(yyruleno==177); case 179: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ yytestcase(yyruleno==179);
{yymsp[-3].minor.yy216.limit = yymsp[-2].minor.yy207; yymsp[-3].minor.yy216.offset = yymsp[0].minor.yy207;} {yymsp[-3].minor.yy216.limit = yymsp[-2].minor.yy207; yymsp[-3].minor.yy216.offset = yymsp[0].minor.yy207;}
break; break;
case 174: /* limit_opt ::= LIMIT signed COMMA signed */ case 176: /* limit_opt ::= LIMIT signed COMMA signed */
case 178: /* slimit_opt ::= SLIMIT signed COMMA signed */ yytestcase(yyruleno==178); case 180: /* slimit_opt ::= SLIMIT signed COMMA signed */ yytestcase(yyruleno==180);
{yymsp[-3].minor.yy216.limit = yymsp[0].minor.yy207; yymsp[-3].minor.yy216.offset = yymsp[-2].minor.yy207;} {yymsp[-3].minor.yy216.limit = yymsp[0].minor.yy207; yymsp[-3].minor.yy216.offset = yymsp[-2].minor.yy207;}
break; break;
case 181: /* expr ::= LP expr RP */ case 183: /* expr ::= LP expr RP */
{yymsp[-2].minor.yy64 = yymsp[-1].minor.yy64; } {yymsp[-2].minor.yy64 = yymsp[-1].minor.yy64; }
break; break;
case 182: /* expr ::= ID */ case 184: /* expr ::= ID */
{yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_ID);} {yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_ID);}
yymsp[0].minor.yy64 = yylhsminor.yy64; yymsp[0].minor.yy64 = yylhsminor.yy64;
break; break;
case 183: /* expr ::= ID DOT ID */ case 185: /* expr ::= ID DOT ID */
{yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[-2].minor.yy0, TK_ID);} {yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[-2].minor.yy0, TK_ID);}
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 184: /* expr ::= ID DOT STAR */ case 186: /* expr ::= ID DOT STAR */
{yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[-2].minor.yy0, TK_ALL);} {yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[-2].minor.yy0, TK_ALL);}
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 185: /* expr ::= INTEGER */ case 187: /* expr ::= INTEGER */
{yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_INTEGER);} {yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_INTEGER);}
yymsp[0].minor.yy64 = yylhsminor.yy64; yymsp[0].minor.yy64 = yylhsminor.yy64;
break; break;
case 186: /* expr ::= MINUS INTEGER */ case 188: /* expr ::= MINUS INTEGER */
case 187: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==187); case 189: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==189);
{yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[-1].minor.yy0, TK_INTEGER);} {yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[-1].minor.yy0, TK_INTEGER);}
yymsp[-1].minor.yy64 = yylhsminor.yy64; yymsp[-1].minor.yy64 = yylhsminor.yy64;
break; break;
case 188: /* expr ::= FLOAT */ case 190: /* expr ::= FLOAT */
{yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_FLOAT);} {yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_FLOAT);}
yymsp[0].minor.yy64 = yylhsminor.yy64; yymsp[0].minor.yy64 = yylhsminor.yy64;
break; break;
case 189: /* expr ::= MINUS FLOAT */ case 191: /* expr ::= MINUS FLOAT */
case 190: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==190); case 192: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==192);
{yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[-1].minor.yy0, TK_FLOAT);} {yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[-1].minor.yy0, TK_FLOAT);}
yymsp[-1].minor.yy64 = yylhsminor.yy64; yymsp[-1].minor.yy64 = yylhsminor.yy64;
break; break;
case 191: /* expr ::= STRING */ case 193: /* expr ::= STRING */
{yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_STRING);} {yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_STRING);}
yymsp[0].minor.yy64 = yylhsminor.yy64; yymsp[0].minor.yy64 = yylhsminor.yy64;
break; break;
case 192: /* expr ::= NOW */ case 194: /* expr ::= NOW */
{yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_NOW); } {yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_NOW); }
yymsp[0].minor.yy64 = yylhsminor.yy64; yymsp[0].minor.yy64 = yylhsminor.yy64;
break; break;
case 193: /* expr ::= VARIABLE */ case 195: /* expr ::= VARIABLE */
{yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_VARIABLE);} {yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_VARIABLE);}
yymsp[0].minor.yy64 = yylhsminor.yy64; yymsp[0].minor.yy64 = yylhsminor.yy64;
break; break;
case 194: /* expr ::= BOOL */ case 196: /* expr ::= BOOL */
{yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_BOOL);} {yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_BOOL);}
yymsp[0].minor.yy64 = yylhsminor.yy64; yymsp[0].minor.yy64 = yylhsminor.yy64;
break; break;
case 195: /* expr ::= ID LP exprlist RP */ case 197: /* expr ::= ID LP exprlist RP */
{ {
yylhsminor.yy64 = tSQLExprCreateFunction(yymsp[-1].minor.yy290, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); yylhsminor.yy64 = tSQLExprCreateFunction(yymsp[-1].minor.yy290, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type);
} }
yymsp[-3].minor.yy64 = yylhsminor.yy64; yymsp[-3].minor.yy64 = yylhsminor.yy64;
break; break;
case 196: /* expr ::= ID LP STAR RP */ case 198: /* expr ::= ID LP STAR RP */
{ {
yylhsminor.yy64 = tSQLExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); yylhsminor.yy64 = tSQLExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type);
} }
yymsp[-3].minor.yy64 = yylhsminor.yy64; yymsp[-3].minor.yy64 = yylhsminor.yy64;
break; break;
case 197: /* expr ::= expr AND expr */ case 199: /* expr ::= expr AND expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_AND);} {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_AND);}
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 198: /* expr ::= expr OR expr */ case 200: /* expr ::= expr OR expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_OR); } {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_OR); }
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 199: /* expr ::= expr LT expr */ case 201: /* expr ::= expr LT expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_LT);} {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_LT);}
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 200: /* expr ::= expr GT expr */ case 202: /* expr ::= expr GT expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_GT);} {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_GT);}
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 201: /* expr ::= expr LE expr */ case 203: /* expr ::= expr LE expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_LE);} {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_LE);}
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 202: /* expr ::= expr GE expr */ case 204: /* expr ::= expr GE expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_GE);} {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_GE);}
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 203: /* expr ::= expr NE expr */ case 205: /* expr ::= expr NE expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_NE);} {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_NE);}
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 204: /* expr ::= expr EQ expr */ case 206: /* expr ::= expr EQ expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_EQ);} {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_EQ);}
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 205: /* expr ::= expr PLUS expr */ case 207: /* expr ::= expr PLUS expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_PLUS); } {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_PLUS); }
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 206: /* expr ::= expr MINUS expr */ case 208: /* expr ::= expr MINUS expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_MINUS); } {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_MINUS); }
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 207: /* expr ::= expr STAR expr */ case 209: /* expr ::= expr STAR expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_STAR); } {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_STAR); }
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 208: /* expr ::= expr SLASH expr */ case 210: /* expr ::= expr SLASH expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_DIVIDE);} {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_DIVIDE);}
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 209: /* expr ::= expr REM expr */ case 211: /* expr ::= expr REM expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_REM); } {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_REM); }
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 210: /* expr ::= expr LIKE expr */ case 212: /* expr ::= expr LIKE expr */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_LIKE); } {yylhsminor.yy64 = tSQLExprCreate(yymsp[-2].minor.yy64, yymsp[0].minor.yy64, TK_LIKE); }
yymsp[-2].minor.yy64 = yylhsminor.yy64; yymsp[-2].minor.yy64 = yylhsminor.yy64;
break; break;
case 211: /* expr ::= expr IN LP exprlist RP */ case 213: /* expr ::= expr IN LP exprlist RP */
{yylhsminor.yy64 = tSQLExprCreate(yymsp[-4].minor.yy64, (tSQLExpr*)yymsp[-1].minor.yy290, TK_IN); } {yylhsminor.yy64 = tSQLExprCreate(yymsp[-4].minor.yy64, (tSQLExpr*)yymsp[-1].minor.yy290, TK_IN); }
yymsp[-4].minor.yy64 = yylhsminor.yy64; yymsp[-4].minor.yy64 = yylhsminor.yy64;
break; break;
case 212: /* exprlist ::= exprlist COMMA expritem */ case 214: /* exprlist ::= exprlist COMMA expritem */
{yylhsminor.yy290 = tSQLExprListAppend(yymsp[-2].minor.yy290,yymsp[0].minor.yy64,0);} {yylhsminor.yy290 = tSQLExprListAppend(yymsp[-2].minor.yy290,yymsp[0].minor.yy64,0);}
yymsp[-2].minor.yy290 = yylhsminor.yy290; yymsp[-2].minor.yy290 = yylhsminor.yy290;
break; break;
case 213: /* exprlist ::= expritem */ case 215: /* exprlist ::= expritem */
{yylhsminor.yy290 = tSQLExprListAppend(0,yymsp[0].minor.yy64,0);} {yylhsminor.yy290 = tSQLExprListAppend(0,yymsp[0].minor.yy64,0);}
yymsp[0].minor.yy290 = yylhsminor.yy290; yymsp[0].minor.yy290 = yylhsminor.yy290;
break; break;
case 214: /* expritem ::= expr */ case 216: /* expritem ::= expr */
{yylhsminor.yy64 = yymsp[0].minor.yy64;} {yylhsminor.yy64 = yymsp[0].minor.yy64;}
yymsp[0].minor.yy64 = yylhsminor.yy64; yymsp[0].minor.yy64 = yylhsminor.yy64;
break; break;
case 216: /* cmd ::= RESET QUERY CACHE */ case 218: /* cmd ::= RESET QUERY CACHE */
{ setDCLSQLElems(pInfo, TSDB_SQL_RESET_CACHE, 0);} { setDCLSQLElems(pInfo, TSDB_SQL_RESET_CACHE, 0);}
break; break;
case 217: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ case 219: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */
{ {
yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n;
SAlterTableSQL* pAlterTable = tAlterTableSQLElems(&yymsp[-4].minor.yy0, yymsp[0].minor.yy523, NULL, TSDB_ALTER_TABLE_ADD_COLUMN); SAlterTableSQL* pAlterTable = tAlterTableSQLElems(&yymsp[-4].minor.yy0, yymsp[0].minor.yy523, NULL, TSDB_ALTER_TABLE_ADD_COLUMN);
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
} }
break; break;
case 218: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ case 220: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */
{ {
yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n;
...@@ -2732,14 +2767,14 @@ static void yy_reduce( ...@@ -2732,14 +2767,14 @@ static void yy_reduce(
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
} }
break; break;
case 219: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ case 221: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */
{ {
yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n;
SAlterTableSQL* pAlterTable = tAlterTableSQLElems(&yymsp[-4].minor.yy0, yymsp[0].minor.yy523, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN); SAlterTableSQL* pAlterTable = tAlterTableSQLElems(&yymsp[-4].minor.yy0, yymsp[0].minor.yy523, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN);
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
} }
break; break;
case 220: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ case 222: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */
{ {
yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n;
...@@ -2750,7 +2785,7 @@ static void yy_reduce( ...@@ -2750,7 +2785,7 @@ static void yy_reduce(
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
} }
break; break;
case 221: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ case 223: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */
{ {
yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n;
...@@ -2764,7 +2799,7 @@ static void yy_reduce( ...@@ -2764,7 +2799,7 @@ static void yy_reduce(
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
} }
break; break;
case 222: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ case 224: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */
{ {
yymsp[-6].minor.yy0.n += yymsp[-5].minor.yy0.n; yymsp[-6].minor.yy0.n += yymsp[-5].minor.yy0.n;
...@@ -2776,13 +2811,13 @@ static void yy_reduce( ...@@ -2776,13 +2811,13 @@ static void yy_reduce(
setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); setSQLInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
} }
break; break;
case 223: /* cmd ::= KILL CONNECTION INTEGER */ case 225: /* cmd ::= KILL CONNECTION INTEGER */
{setKillSQL(pInfo, TSDB_SQL_KILL_CONNECTION, &yymsp[0].minor.yy0);} {setKillSQL(pInfo, TSDB_SQL_KILL_CONNECTION, &yymsp[0].minor.yy0);}
break; break;
case 224: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */ case 226: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */
{yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSQL(pInfo, TSDB_SQL_KILL_STREAM, &yymsp[-2].minor.yy0);} {yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSQL(pInfo, TSDB_SQL_KILL_STREAM, &yymsp[-2].minor.yy0);}
break; break;
case 225: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */ case 227: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */
{yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSQL(pInfo, TSDB_SQL_KILL_QUERY, &yymsp[-2].minor.yy0);} {yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSQL(pInfo, TSDB_SQL_KILL_QUERY, &yymsp[-2].minor.yy0);}
break; break;
default: default:
......
...@@ -130,7 +130,6 @@ void recyclePageTest() { ...@@ -130,7 +130,6 @@ void recyclePageTest() {
ASSERT_TRUE(t4 == pBufPage4); ASSERT_TRUE(t4 == pBufPage4);
ASSERT_TRUE(pageId == 4); ASSERT_TRUE(pageId == 4);
releaseResBufPage(pResultBuf, t4); releaseResBufPage(pResultBuf, t4);
releaseResBufPage(pResultBuf, t4);
tFilePage* pBufPage5 = getNewDataBuf(pResultBuf, groupId, &pageId); tFilePage* pBufPage5 = getNewDataBuf(pResultBuf, groupId, &pageId);
tFilePage* t5 = getResBufPage(pResultBuf, pageId); tFilePage* t5 = getResBufPage(pResultBuf, pageId);
......
...@@ -47,6 +47,8 @@ void simpleTest() { ...@@ -47,6 +47,8 @@ void simpleTest() {
EXPECT_EQ(pTSBuf->block.numOfElem, num); EXPECT_EQ(pTSBuf->block.numOfElem, num);
tsBufDestroy(pTSBuf); tsBufDestroy(pTSBuf);
free(list);
} }
// one large list of ts, the ts list need to be split into several small blocks // one large list of ts, the ts list need to be split into several small blocks
...@@ -71,6 +73,7 @@ void largeTSTest() { ...@@ -71,6 +73,7 @@ void largeTSTest() {
EXPECT_EQ(pTSBuf->block.numOfElem, num); EXPECT_EQ(pTSBuf->block.numOfElem, num);
tsBufDestroy(pTSBuf); tsBufDestroy(pTSBuf);
free(list);
} }
void multiTagsTest() { void multiTagsTest() {
...@@ -208,6 +211,8 @@ void loadDataTest() { ...@@ -208,6 +211,8 @@ void loadDataTest() {
int64_t e = taosGetTimestampUs(); int64_t e = taosGetTimestampUs();
printf("end:%" PRIu64 ", elapsed:%" PRIu64 ", total obj:%d\n", e, e - s, x); printf("end:%" PRIu64 ", elapsed:%" PRIu64 ", total obj:%d\n", e, e - s, x);
tsBufDestroy(pTSBuf);
tsBufDestroy(pNewBuf);
} }
void randomIncTsTest() {} void randomIncTsTest() {}
...@@ -338,6 +343,8 @@ void TSTraverse() { ...@@ -338,6 +343,8 @@ void TSTraverse() {
} }
} }
} }
tsBufDestroy(pTSBuf);
} }
void performanceTest() {} void performanceTest() {}
...@@ -352,9 +359,12 @@ void invalidFileTest() { ...@@ -352,9 +359,12 @@ void invalidFileTest() {
STSBuf* pNewBuf = tsBufCreateFromFile("/tmp/test", true); STSBuf* pNewBuf = tsBufCreateFromFile("/tmp/test", true);
EXPECT_TRUE(pNewBuf == NULL); EXPECT_TRUE(pNewBuf == NULL);
tsBufDestroy(pNewBuf);
pNewBuf = tsBufCreateFromFile("/tmp/911", true); pNewBuf = tsBufCreateFromFile("/tmp/911", true);
EXPECT_TRUE(pNewBuf == NULL); EXPECT_TRUE(pNewBuf == NULL);
tsBufDestroy(pNewBuf);
} }
void mergeDiffVnodeBufferTest() { void mergeDiffVnodeBufferTest() {
......
...@@ -260,7 +260,7 @@ void *rpcOpen(const SRpcInit *pInit) { ...@@ -260,7 +260,7 @@ void *rpcOpen(const SRpcInit *pInit) {
} }
if (pRpc->connType == TAOS_CONN_SERVER) { if (pRpc->connType == TAOS_CONN_SERVER) {
pRpc->hash = taosHashInit(pRpc->sessions, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true); pRpc->hash = taosHashInit(pRpc->sessions, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, true);
if (pRpc->hash == NULL) { if (pRpc->hash == NULL) {
tError("%s failed to init string hash", pRpc->label); tError("%s failed to init string hash", pRpc->label);
rpcClose(pRpc); rpcClose(pRpc);
......
...@@ -96,7 +96,7 @@ static void syncModuleInitFunc() { ...@@ -96,7 +96,7 @@ static void syncModuleInitFunc() {
return; return;
} }
vgIdHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true); vgIdHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, true);
if (vgIdHash == NULL) { if (vgIdHash == NULL) {
taosTmrCleanUp(syncTmrCtrl); taosTmrCleanUp(syncTmrCtrl);
taosCloseTcpThreadPool(tsTcpPool); taosCloseTcpThreadPool(tsTcpPool);
......
...@@ -443,7 +443,7 @@ STsdbMeta *tsdbNewMeta(STsdbCfg *pCfg) { ...@@ -443,7 +443,7 @@ STsdbMeta *tsdbNewMeta(STsdbCfg *pCfg) {
goto _err; goto _err;
} }
pMeta->uidMap = taosHashInit((size_t)(TSDB_INIT_NTABLES * 1.1), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false); pMeta->uidMap = taosHashInit((size_t)(TSDB_INIT_NTABLES * 1.1), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
if (pMeta->uidMap == NULL) { if (pMeta->uidMap == NULL) {
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
goto _err; goto _err;
......
...@@ -208,6 +208,7 @@ TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STab ...@@ -208,6 +208,7 @@ TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STab
if (pQueryHandle->statis == NULL) { if (pQueryHandle->statis == NULL) {
goto out_of_memory; goto out_of_memory;
} }
pQueryHandle->pColumns = taosArrayInit(numOfCols, sizeof(SColumnInfoData)); // todo: use list instead of array? pQueryHandle->pColumns = taosArrayInit(numOfCols, sizeof(SColumnInfoData)); // todo: use list instead of array?
if (pQueryHandle->pColumns == NULL) { if (pQueryHandle->pColumns == NULL) {
goto out_of_memory; goto out_of_memory;
...@@ -229,8 +230,9 @@ TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STab ...@@ -229,8 +230,9 @@ TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STab
if (pQueryHandle->pTableCheckInfo == NULL) { if (pQueryHandle->pTableCheckInfo == NULL) {
goto out_of_memory; goto out_of_memory;
} }
STsdbMeta* pMeta = tsdbGetMeta(tsdb); STsdbMeta* pMeta = tsdbGetMeta(tsdb);
assert(pMeta != NULL); assert(pMeta != NULL && sizeOfGroup >= 1 && pCond != NULL && pCond->numOfCols > 0);
for (int32_t i = 0; i < sizeOfGroup; ++i) { for (int32_t i = 0; i < sizeOfGroup; ++i) {
SArray* group = *(SArray**) taosArrayGet(groupList->pGroupList, i); SArray* group = *(SArray**) taosArrayGet(groupList->pGroupList, i);
...@@ -239,18 +241,26 @@ TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STab ...@@ -239,18 +241,26 @@ TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STab
assert(gsize > 0); assert(gsize > 0);
for (int32_t j = 0; j < gsize; ++j) { for (int32_t j = 0; j < gsize; ++j) {
STable* pTable = (STable*) taosArrayGetP(group, j); STableKeyInfo* pKeyInfo = (STableKeyInfo*) taosArrayGet(group, j);
STableCheckInfo info = { STableCheckInfo info = {
.lastKey = pQueryHandle->window.skey, .lastKey = pKeyInfo->lastKey,
//.tableId = pTable->tableId, .tableId = ((STable*)(pKeyInfo->pTable))->tableId,
.pTableObj = pTable, .pTableObj = pKeyInfo->pTable,
}; };
info.tableId = pTable->tableId;
assert(info.pTableObj != NULL && (info.pTableObj->type == TSDB_NORMAL_TABLE || assert(info.pTableObj != NULL && (info.pTableObj->type == TSDB_NORMAL_TABLE ||
info.pTableObj->type == TSDB_CHILD_TABLE || info.pTableObj->type == TSDB_STREAM_TABLE)); info.pTableObj->type == TSDB_CHILD_TABLE || info.pTableObj->type == TSDB_STREAM_TABLE));
info.tableId.tid = info.pTableObj->tableId.tid;
info.tableId.uid = info.pTableObj->tableId.uid;
if (ASCENDING_TRAVERSE(pQueryHandle->order)) {
assert(info.lastKey >= pQueryHandle->window.skey);
} else {
assert(info.lastKey <= pQueryHandle->window.skey);
}
taosArrayPush(pQueryHandle->pTableCheckInfo, &info); taosArrayPush(pQueryHandle->pTableCheckInfo, &info);
tsdbDebug("%p check table uid:%"PRId64", tid:%d from lastKey:%"PRId64" %p", pQueryHandle, info.tableId.uid, tsdbDebug("%p check table uid:%"PRId64", tid:%d from lastKey:%"PRId64" %p", pQueryHandle, info.tableId.uid,
info.tableId.tid, info.lastKey, qinfo); info.tableId.tid, info.lastKey, qinfo);
...@@ -326,17 +336,23 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh ...@@ -326,17 +336,23 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
assert(pCheckInfo->iter == NULL && pCheckInfo->iiter == NULL); assert(pCheckInfo->iter == NULL && pCheckInfo->iiter == NULL);
// TODO: add uid check STableData* pMem = NULL;
if (pHandle->mem && pCheckInfo->tableId.tid < pHandle->mem->maxTables && STableData* pIMem = NULL;
pHandle->mem->tData[pCheckInfo->tableId.tid] != NULL) {
pCheckInfo->iter = tSkipListCreateIterFromVal(pHandle->mem->tData[pCheckInfo->tableId.tid]->pData, if (pHandle->mem && pCheckInfo->tableId.tid < pHandle->mem->maxTables) {
(const char*)&pCheckInfo->lastKey, TSDB_DATA_TYPE_TIMESTAMP, order); pMem = pHandle->mem->tData[pCheckInfo->tableId.tid];
if (pMem != NULL && pMem->uid == pCheckInfo->tableId.uid) { // check uid
pCheckInfo->iter =
tSkipListCreateIterFromVal(pMem->pData, (const char*)&pCheckInfo->lastKey, TSDB_DATA_TYPE_TIMESTAMP, order);
}
} }
if (pHandle->imem && pCheckInfo->tableId.tid < pHandle->imem->maxTables && if (pHandle->imem && pCheckInfo->tableId.tid < pHandle->imem->maxTables) {
pHandle->imem->tData[pCheckInfo->tableId.tid] != NULL) { pIMem = pHandle->imem->tData[pCheckInfo->tableId.tid];
pCheckInfo->iiter = tSkipListCreateIterFromVal(pHandle->imem->tData[pCheckInfo->tableId.tid]->pData, if (pIMem != NULL && pIMem->uid == pCheckInfo->tableId.uid) { // check uid
(const char*)&pCheckInfo->lastKey, TSDB_DATA_TYPE_TIMESTAMP, order); pCheckInfo->iiter =
tSkipListCreateIterFromVal(pIMem->pData, (const char*)&pCheckInfo->lastKey, TSDB_DATA_TYPE_TIMESTAMP, order);
}
} }
// both iterators are NULL, no data in buffer right now // both iterators are NULL, no data in buffer right now
...@@ -356,8 +372,17 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh ...@@ -356,8 +372,17 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
SDataRow row = *(SDataRow *)SL_GET_NODE_DATA(node); SDataRow row = *(SDataRow *)SL_GET_NODE_DATA(node);
TSKEY key = dataRowKey(row); // first timestamp in buffer TSKEY key = dataRowKey(row); // first timestamp in buffer
tsdbDebug("%p uid:%" PRId64", tid:%d check data in mem from skey:%" PRId64 ", order:%d, %p", pHandle, tsdbDebug("%p uid:%" PRId64 ", tid:%d check data in mem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pHandle->qinfo); "-%" PRId64 ", lastKey:%" PRId64 ", %p",
pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pMem->keyFirst, pMem->keyLast,
pCheckInfo->lastKey, pHandle->qinfo);
if (ASCENDING_TRAVERSE(order)) {
assert(pCheckInfo->lastKey <= key);
} else {
assert(pCheckInfo->lastKey >= key);
}
} else { } else {
tsdbDebug("%p uid:%"PRId64", tid:%d no data in mem, %p", pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, tsdbDebug("%p uid:%"PRId64", tid:%d no data in mem, %p", pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid,
pHandle->qinfo); pHandle->qinfo);
...@@ -369,8 +394,16 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh ...@@ -369,8 +394,16 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
SDataRow row = *(SDataRow *)SL_GET_NODE_DATA(node); SDataRow row = *(SDataRow *)SL_GET_NODE_DATA(node);
TSKEY key = dataRowKey(row); // first timestamp in buffer TSKEY key = dataRowKey(row); // first timestamp in buffer
tsdbDebug("%p uid:%" PRId64", tid:%d check data in imem from skey:%" PRId64 ", order:%d, %p", pHandle, tsdbDebug("%p uid:%" PRId64 ", tid:%d check data in mem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64
pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pHandle->qinfo); "-%" PRId64 ", lastKey:%" PRId64 ", %p",
pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pIMem->keyFirst, pIMem->keyLast,
pCheckInfo->lastKey, pHandle->qinfo);
if (ASCENDING_TRAVERSE(order)) {
assert(pCheckInfo->lastKey <= key);
} else {
assert(pCheckInfo->lastKey >= key);
}
} else { } else {
tsdbDebug("%p uid:%"PRId64", tid:%d no data in imem, %p", pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, tsdbDebug("%p uid:%"PRId64", tid:%d no data in imem, %p", pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid,
pHandle->qinfo); pHandle->qinfo);
...@@ -2051,7 +2084,9 @@ static int32_t getAllTableList(STable* pSuperTable, SArray* list) { ...@@ -2051,7 +2084,9 @@ static int32_t getAllTableList(STable* pSuperTable, SArray* list) {
SSkipListNode* pNode = tSkipListIterGet(iter); SSkipListNode* pNode = tSkipListIterGet(iter);
STable** pTable = (STable**) SL_GET_NODE_DATA((SSkipListNode*) pNode); STable** pTable = (STable**) SL_GET_NODE_DATA((SSkipListNode*) pNode);
taosArrayPush(list, pTable);
STableKeyInfo info = {.pTable = *pTable, .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(list, &info);
} }
tSkipListDestroyIter(iter); tSkipListDestroyIter(iter);
...@@ -2089,7 +2124,7 @@ void filterPrepare(void* expr, void* param) { ...@@ -2089,7 +2124,7 @@ void filterPrepare(void* expr, void* param) {
pInfo->sch = *pSchema; pInfo->sch = *pSchema;
pInfo->optr = pExpr->_node.optr; pInfo->optr = pExpr->_node.optr;
pInfo->compare = getComparFunc(pSchema->type, pInfo->optr); pInfo->compare = getComparFunc(pSchema->type, pInfo->optr);
pInfo->param = pTSSchema; pInfo->indexed = pTSSchema->columns->colId == pInfo->sch.colId;
if (pInfo->optr == TSDB_RELATION_IN) { if (pInfo->optr == TSDB_RELATION_IN) {
pInfo->q = (char*) pCond->arr; pInfo->q = (char*) pCond->arr;
...@@ -2107,8 +2142,8 @@ typedef struct STableGroupSupporter { ...@@ -2107,8 +2142,8 @@ typedef struct STableGroupSupporter {
int32_t tableGroupComparFn(const void *p1, const void *p2, const void *param) { int32_t tableGroupComparFn(const void *p1, const void *p2, const void *param) {
STableGroupSupporter* pTableGroupSupp = (STableGroupSupporter*) param; STableGroupSupporter* pTableGroupSupp = (STableGroupSupporter*) param;
STable* pTable1 = *(STable**) p1; STable* pTable1 = ((STableKeyInfo*) p1)->pTable;
STable* pTable2 = *(STable**) p2; STable* pTable2 = ((STableKeyInfo*) p2)->pTable;
for (int32_t i = 0; i < pTableGroupSupp->numOfCols; ++i) { for (int32_t i = 0; i < pTableGroupSupp->numOfCols; ++i) {
SColIndex* pColIndex = &pTableGroupSupp->pCols[i]; SColIndex* pColIndex = &pTableGroupSupp->pCols[i];
...@@ -2158,12 +2193,14 @@ int32_t tableGroupComparFn(const void *p1, const void *p2, const void *param) { ...@@ -2158,12 +2193,14 @@ int32_t tableGroupComparFn(const void *p1, const void *p2, const void *param) {
return 0; return 0;
} }
void createTableGroupImpl(SArray* pGroups, SArray* pTableList, size_t numOfTables, STableGroupSupporter* pSupp, void createTableGroupImpl(SArray* pGroups, SArray* pTableList, size_t numOfTables, TSKEY skey, STableGroupSupporter* pSupp,
__ext_compar_fn_t compareFn) { __ext_compar_fn_t compareFn) {
STable* pTable = taosArrayGetP(pTableList, 0); STable* pTable = taosArrayGetP(pTableList, 0);
SArray* g = taosArrayInit(16, POINTER_BYTES); SArray* g = taosArrayInit(16, sizeof(STableKeyInfo));
taosArrayPush(g, &pTable);
STableKeyInfo info = {.pTable = pTable, .lastKey = skey};
taosArrayPush(g, &info);
tsdbRefTable(pTable); tsdbRefTable(pTable);
for (int32_t i = 1; i < numOfTables; ++i) { for (int32_t i = 1; i < numOfTables; ++i) {
...@@ -2177,18 +2214,21 @@ void createTableGroupImpl(SArray* pGroups, SArray* pTableList, size_t numOfTable ...@@ -2177,18 +2214,21 @@ void createTableGroupImpl(SArray* pGroups, SArray* pTableList, size_t numOfTable
assert((*p)->type == TSDB_CHILD_TABLE); assert((*p)->type == TSDB_CHILD_TABLE);
if (ret == 0) { if (ret == 0) {
taosArrayPush(g, p); STableKeyInfo info1 = {.pTable = *p, .lastKey = skey};
taosArrayPush(g, &info1);
} else { } else {
taosArrayPush(pGroups, &g); // current group is ended, start a new group taosArrayPush(pGroups, &g); // current group is ended, start a new group
g = taosArrayInit(16, POINTER_BYTES); g = taosArrayInit(16, sizeof(STableKeyInfo));
taosArrayPush(g, p);
STableKeyInfo info1 = {.pTable = *p, .lastKey = skey};
taosArrayPush(g, &info1);
} }
} }
taosArrayPush(pGroups, &g); taosArrayPush(pGroups, &g);
} }
SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pCols, int32_t numOfOrderCols) { SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pCols, int32_t numOfOrderCols, TSKEY skey) {
assert(pTableList != NULL); assert(pTableList != NULL);
SArray* pTableGroup = taosArrayInit(1, POINTER_BYTES); SArray* pTableGroup = taosArrayInit(1, POINTER_BYTES);
...@@ -2199,13 +2239,16 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC ...@@ -2199,13 +2239,16 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC
} }
if (numOfOrderCols == 0 || size == 1) { // no group by tags clause or only one table if (numOfOrderCols == 0 || size == 1) { // no group by tags clause or only one table
SArray* sa = taosArrayInit(size, POINTER_BYTES); SArray* sa = taosArrayInit(size, sizeof(STableKeyInfo));
for(int32_t i = 0; i < size; ++i) { for(int32_t i = 0; i < size; ++i) {
STable** pTable = taosArrayGet(pTableList, i); STableKeyInfo *pKeyInfo = taosArrayGet(pTableList, i);
assert((*pTable)->type == TSDB_CHILD_TABLE); assert(((STable*)pKeyInfo->pTable)->type == TSDB_CHILD_TABLE);
tsdbRefTable(pKeyInfo->pTable);
tsdbRefTable(*pTable); STableKeyInfo info = {.pTable = pKeyInfo->pTable, .lastKey = skey};
taosArrayPush(sa, pTable); taosArrayPush(sa, &info);
} }
taosArrayPush(pTableGroup, &sa); taosArrayPush(pTableGroup, &sa);
...@@ -2216,8 +2259,8 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC ...@@ -2216,8 +2259,8 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC
pSupp->pTagSchema = pTagSchema; pSupp->pTagSchema = pTagSchema;
pSupp->pCols = pCols; pSupp->pCols = pCols;
taosqsort(pTableList->pData, size, POINTER_BYTES, pSupp, tableGroupComparFn); taosqsort(pTableList->pData, size, sizeof(STableKeyInfo), pSupp, tableGroupComparFn);
createTableGroupImpl(pTableGroup, pTableList, size, pSupp, tableGroupComparFn); createTableGroupImpl(pTableGroup, pTableList, size, skey, pSupp, tableGroupComparFn);
taosTFree(pSupp); taosTFree(pSupp);
} }
...@@ -2290,7 +2333,7 @@ static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr) ...@@ -2290,7 +2333,7 @@ static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr)
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, const char* pTagCond, size_t len, int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, TSKEY skey, const char* pTagCond, size_t len,
int16_t tagNameRelType, const char* tbnameCond, STableGroupInfo* pGroupInfo, int16_t tagNameRelType, const char* tbnameCond, STableGroupInfo* pGroupInfo,
SColIndex* pColIndex, int32_t numOfCols) { SColIndex* pColIndex, int32_t numOfCols) {
if (tsdbRLockRepoMeta(tsdb) < 0) goto _error; if (tsdbRLockRepoMeta(tsdb) < 0) goto _error;
...@@ -2314,7 +2357,7 @@ int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, const char* pT ...@@ -2314,7 +2357,7 @@ int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, const char* pT
} }
//NOTE: not add ref count for super table //NOTE: not add ref count for super table
SArray* res = taosArrayInit(8, POINTER_BYTES); SArray* res = taosArrayInit(8, sizeof(STableKeyInfo));
STSchema* pTagSchema = tsdbGetTableTagSchema(pTable); STSchema* pTagSchema = tsdbGetTableTagSchema(pTable);
// no tags and tbname condition, all child tables of this stable are involved // no tags and tbname condition, all child tables of this stable are involved
...@@ -2326,7 +2369,7 @@ int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, const char* pT ...@@ -2326,7 +2369,7 @@ int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, const char* pT
} }
pGroupInfo->numOfTables = taosArrayGetSize(res); pGroupInfo->numOfTables = taosArrayGetSize(res);
pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols); pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols, skey);
tsdbDebug("%p no table name/tag condition, all tables belong to one group, numOfTables:%zu", tsdb, pGroupInfo->numOfTables); tsdbDebug("%p no table name/tag condition, all tables belong to one group, numOfTables:%zu", tsdb, pGroupInfo->numOfTables);
taosArrayDestroy(res); taosArrayDestroy(res);
...@@ -2369,7 +2412,7 @@ int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, const char* pT ...@@ -2369,7 +2412,7 @@ int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, const char* pT
doQueryTableList(pTable, res, expr); doQueryTableList(pTable, res, expr);
pGroupInfo->numOfTables = taosArrayGetSize(res); pGroupInfo->numOfTables = taosArrayGetSize(res);
pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols); pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols, skey);
tsdbDebug("%p stable tid:%d, uid:%"PRIu64" query, numOfTables:%zu, belong to %zu groups", tsdb, pTable->tableId.tid, tsdbDebug("%p stable tid:%d, uid:%"PRIu64" query, numOfTables:%zu, belong to %zu groups", tsdb, pTable->tableId.tid,
pTable->tableId.uid, pGroupInfo->numOfTables, taosArrayGetSize(pGroupInfo->pGroupList)); pTable->tableId.uid, pGroupInfo->numOfTables, taosArrayGetSize(pGroupInfo->pGroupList));
...@@ -2383,7 +2426,7 @@ int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, const char* pT ...@@ -2383,7 +2426,7 @@ int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, const char* pT
return terrno; return terrno;
} }
int32_t tsdbGetOneTableGroup(TSDB_REPO_T* tsdb, uint64_t uid, STableGroupInfo* pGroupInfo) { int32_t tsdbGetOneTableGroup(TSDB_REPO_T* tsdb, uint64_t uid, TSKEY startKey, STableGroupInfo* pGroupInfo) {
if (tsdbRLockRepoMeta(tsdb) < 0) goto _error; if (tsdbRLockRepoMeta(tsdb) < 0) goto _error;
STable* pTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), uid); STable* pTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), uid);
...@@ -2400,9 +2443,11 @@ int32_t tsdbGetOneTableGroup(TSDB_REPO_T* tsdb, uint64_t uid, STableGroupInfo* p ...@@ -2400,9 +2443,11 @@ int32_t tsdbGetOneTableGroup(TSDB_REPO_T* tsdb, uint64_t uid, STableGroupInfo* p
pGroupInfo->numOfTables = 1; pGroupInfo->numOfTables = 1;
pGroupInfo->pGroupList = taosArrayInit(1, POINTER_BYTES); pGroupInfo->pGroupList = taosArrayInit(1, POINTER_BYTES);
SArray* group = taosArrayInit(1, POINTER_BYTES); SArray* group = taosArrayInit(1, sizeof(STableKeyInfo));
STableKeyInfo info = {.pTable = pTable, .lastKey = startKey};
taosArrayPush(group, &info);
taosArrayPush(group, &pTable);
taosArrayPush(pGroupInfo->pGroupList, &group); taosArrayPush(pGroupInfo->pGroupList, &group);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
...@@ -2419,7 +2464,7 @@ int32_t tsdbGetTableGroupFromIdList(TSDB_REPO_T* tsdb, SArray* pTableIdList, STa ...@@ -2419,7 +2464,7 @@ int32_t tsdbGetTableGroupFromIdList(TSDB_REPO_T* tsdb, SArray* pTableIdList, STa
assert(pTableIdList != NULL); assert(pTableIdList != NULL);
size_t size = taosArrayGetSize(pTableIdList); size_t size = taosArrayGetSize(pTableIdList);
pGroupInfo->pGroupList = taosArrayInit(1, POINTER_BYTES); pGroupInfo->pGroupList = taosArrayInit(1, POINTER_BYTES);
SArray* group = taosArrayInit(1, POINTER_BYTES); SArray* group = taosArrayInit(1, sizeof(STableKeyInfo));
int32_t i = 0; int32_t i = 0;
for(; i < size; ++i) { for(; i < size; ++i) {
...@@ -2437,7 +2482,9 @@ int32_t tsdbGetTableGroupFromIdList(TSDB_REPO_T* tsdb, SArray* pTableIdList, STa ...@@ -2437,7 +2482,9 @@ int32_t tsdbGetTableGroupFromIdList(TSDB_REPO_T* tsdb, SArray* pTableIdList, STa
} }
tsdbRefTable(pTable); tsdbRefTable(pTable);
taosArrayPush(group, &pTable);
STableKeyInfo info = {.pTable = pTable, .lastKey = id->key};
taosArrayPush(group, &info);
} }
if (tsdbUnlockRepoMeta(tsdb) < 0) { if (tsdbUnlockRepoMeta(tsdb) < 0) {
......
...@@ -20,7 +20,9 @@ ...@@ -20,7 +20,9 @@
extern "C" { extern "C" {
#endif #endif
#include "tarray.h"
#include "hashfunc.h" #include "hashfunc.h"
#include "tlockfree.h"
#define HASH_MAX_CAPACITY (1024 * 1024 * 16) #define HASH_MAX_CAPACITY (1024 * 1024 * 16)
#define HASH_DEFAULT_LOAD_FACTOR (0.75) #define HASH_DEFAULT_LOAD_FACTOR (0.75)
...@@ -29,38 +31,45 @@ extern "C" { ...@@ -29,38 +31,45 @@ extern "C" {
typedef void (*_hash_free_fn_t)(void *param); typedef void (*_hash_free_fn_t)(void *param);
typedef struct SHashNode { typedef struct SHashNode {
char *key; char *key;
// union { // struct SHashNode *prev;
struct SHashNode * prev;
// struct SHashEntry *prev1;
// };
//
struct SHashNode *next; struct SHashNode *next;
uint32_t hashVal; // the hash value of key, if hashVal == HASH_VALUE_IN_TRASH, this node is moved to trash uint32_t hashVal; // the hash value of key, if hashVal == HASH_VALUE_IN_TRASH, this node is moved to trash
uint32_t keyLen; // length of the key uint32_t keyLen; // length of the key
char data[]; char *data;
} SHashNode; } SHashNode;
typedef enum SHashLockTypeE {
HASH_NO_LOCK = 0,
HASH_ENTRY_LOCK = 1,
} SHashLockTypeE;
typedef struct SHashEntry {
int32_t num; // number of elements in current entry
SRWLatch latch; // entry latch
SHashNode *next;
} SHashEntry;
typedef struct SHashObj { typedef struct SHashObj {
SHashNode **hashList; SHashEntry **hashList;
size_t capacity; // number of slots size_t capacity; // number of slots
size_t size; // number of elements in hash table size_t size; // number of elements in hash table
_hash_fn_t hashFp; // hash function _hash_fn_t hashFp; // hash function
_hash_free_fn_t freeFp; // hash node free callback function _hash_free_fn_t freeFp; // hash node free callback function
#if defined(LINUX) SRWLatch lock; // read-write spin lock
pthread_rwlock_t *lock; SHashLockTypeE type; // lock type
#else bool enableUpdate; // enable update
pthread_mutex_t *lock; SArray *pMemBlock; // memory block allocated for SHashEntry
#endif
} SHashObj; } SHashObj;
typedef struct SHashMutableIterator { typedef struct SHashMutableIterator {
SHashObj * pHashObj; SHashObj *pHashObj;
int32_t entryIndex; int32_t entryIndex;
SHashNode *pCur; SHashNode *pCur;
SHashNode *pNext; // current node can be deleted for mutable iterator, so keep the next one before return current SHashNode *pNext; // current node can be deleted for mutable iterator, so keep the next one before return current
int32_t num; // already check number of elements in hash table size_t numOfChecked; // already check number of elements in hash table
size_t numOfEntries; // number of entries while the iterator is created
} SHashMutableIterator; } SHashMutableIterator;
/** /**
...@@ -71,7 +80,7 @@ typedef struct SHashMutableIterator { ...@@ -71,7 +80,7 @@ typedef struct SHashMutableIterator {
* @param threadsafe thread safe or not * @param threadsafe thread safe or not
* @return * @return
*/ */
SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool threadsafe); SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTypeE type);
/** /**
* return the size of hash table * return the size of hash table
...@@ -101,13 +110,19 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da ...@@ -101,13 +110,19 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
*/ */
void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen); void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen);
void *taosHashGetCB(SHashObj *pHashObj, const void *key, size_t keyLen, void(*fp)(void*));
/** /**
* remove item with the specified key * remove item with the specified key
* @param pHashObj * @param pHashObj
* @param key * @param key
* @param keyLen * @param keyLen
*/ */
void taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen); int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen);
int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLen, void* data, size_t dsize);
int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), void *param);
/** /**
* clean up hash table * clean up hash table
...@@ -115,13 +130,6 @@ void taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen); ...@@ -115,13 +130,6 @@ void taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen);
*/ */
void taosHashCleanup(SHashObj *pHashObj); void taosHashCleanup(SHashObj *pHashObj);
/**
* Set the free callback function
* This function if set will be invoked right before freeing each hash node
* @param pHashObj
*/
void taosHashSetFreecb(SHashObj *pHashObj, _hash_free_fn_t freeFp);
/** /**
* *
* @param pHashObj * @param pHashObj
......
...@@ -121,7 +121,7 @@ void *taosCacheAcquireByKey(SCacheObj *pCacheObj, const void *key, size_t keyLen ...@@ -121,7 +121,7 @@ void *taosCacheAcquireByKey(SCacheObj *pCacheObj, const void *key, size_t keyLen
* @param expireTime new expire time of data * @param expireTime new expire time of data
* @return * @return
*/ */
void* taosCacheUpdateExpireTimeByName(SCacheObj *pCacheObj, void *key, size_t keyLen, uint64_t expireTime); //void* taosCacheUpdateExpireTimeByName(SCacheObj *pCacheObj, void *key, size_t keyLen, uint64_t expireTime);
/** /**
* Add one reference count for the exist data, and assign this data for a new owner. * Add one reference count for the exist data, and assign this data for a new owner.
......
...@@ -24,8 +24,6 @@ extern "C" { ...@@ -24,8 +24,6 @@ extern "C" {
#include "tutil.h" #include "tutil.h"
#include "ttokendef.h" #include "ttokendef.h"
#define TSQL_TBNAME "TBNAME" #define TSQL_TBNAME "TBNAME"
#define TSQL_TBNAME_L "tbname" #define TSQL_TBNAME_L "tbname"
......
...@@ -18,64 +18,52 @@ ...@@ -18,64 +18,52 @@
#include "tulog.h" #include "tulog.h"
#include "taosdef.h" #include "taosdef.h"
static FORCE_INLINE void __wr_lock(void *lock) { #define HASH_NEED_RESIZE(_h) ((_h)->size >= (_h)->capacity * HASH_DEFAULT_LOAD_FACTOR)
if (lock == NULL) {
#define DO_FREE_HASH_NODE(_n) \
do { \
taosTFree((_n)->data); \
taosTFree(_n); \
} while (0)
#define FREE_HASH_NODE(_h, _n) \
do { \
if ((_h)->freeFp) { \
(_h)->freeFp((_n)->data); \
} \
\
DO_FREE_HASH_NODE(_n); \
} while (0);
static FORCE_INLINE void __wr_lock(void *lock, int32_t type) {
if (type == HASH_NO_LOCK) {
return; return;
} }
taosWLockLatch(lock);
#if defined(LINUX)
pthread_rwlock_wrlock(lock);
#else
pthread_mutex_lock(lock);
#endif
} }
static FORCE_INLINE void __rd_lock(void *lock) { static FORCE_INLINE void __rd_lock(void *lock, int32_t type) {
if (lock == NULL) { if (type == HASH_NO_LOCK) {
return; return;
} }
#if defined(LINUX) taosRLockLatch(lock);
pthread_rwlock_rdlock(lock);
#else
pthread_mutex_lock(lock);
#endif
} }
static FORCE_INLINE void __unlock(void *lock) { static FORCE_INLINE void __rd_unlock(void *lock, int32_t type) {
if (lock == NULL) { if (type == HASH_NO_LOCK) {
return; return;
} }
#if defined(LINUX) taosRUnLockLatch(lock);
pthread_rwlock_unlock(lock);
#else
pthread_mutex_unlock(lock);
#endif
}
static FORCE_INLINE int32_t __lock_init(void *lock) {
if (lock == NULL) {
return 0;
}
#if defined(LINUX)
return pthread_rwlock_init(lock, NULL);
#else
return pthread_mutex_init(lock, NULL);
#endif
} }
static FORCE_INLINE void __lock_destroy(void *lock) { static FORCE_INLINE void __wr_unlock(void *lock, int32_t type) {
if (lock == NULL) { if (type == HASH_NO_LOCK) {
return; return;
} }
#if defined(LINUX) taosWUnLockLatch(lock);
pthread_rwlock_destroy(lock);
#else
pthread_mutex_destroy(lock);
#endif
} }
static FORCE_INLINE int32_t taosHashCapacity(int32_t length) { static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
...@@ -86,37 +74,17 @@ static FORCE_INLINE int32_t taosHashCapacity(int32_t length) { ...@@ -86,37 +74,17 @@ static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
return i; return i;
} }
/** static FORCE_INLINE SHashNode *doSearchInEntryList(SHashEntry *pe, const void *key, size_t keyLen, uint32_t hashVal) {
* Get SHashNode from hashlist, nodes from trash are not included. SHashNode *pNode = pe->next;
* @param pHashObj Cache objection
* @param key key for hash
* @param keyLen key length
* @param hashVal hash value by hash function
* @return
*/
FORCE_INLINE SHashNode *doGetNodeFromHashTable(SHashObj *pHashObj, const void *key, uint32_t keyLen, uint32_t *hashVal) {
uint32_t hash = (*pHashObj->hashFp)(key, keyLen);
int32_t slot = HASH_INDEX(hash, pHashObj->capacity);
SHashNode *pNode = pHashObj->hashList[slot];
while (pNode) { while (pNode) {
if ((pNode->keyLen == keyLen) && (memcmp(pNode->key, key, keyLen) == 0)) { if ((pNode->keyLen == keyLen) && (memcmp(pNode->key, key, keyLen) == 0)) {
assert(pNode->hashVal == hashVal);
break; break;
} }
pNode = pNode->next; pNode = pNode->next;
} }
if (pNode) {
assert(HASH_INDEX(pNode->hashVal, pHashObj->capacity) == slot);
}
// return the calculated hash value, to avoid calculating it again in other functions
if (hashVal != NULL) {
*hashVal = hash;
}
return pNode; return pNode;
} }
...@@ -147,7 +115,13 @@ static SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *p ...@@ -147,7 +115,13 @@ static SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *p
* @param dsize size of actual data * @param dsize size of actual data
* @return hash node * @return hash node
*/ */
static SHashNode *doUpdateHashNode(SHashNode *pNode, const void *key, size_t keyLen, const void *pData, size_t dsize); static FORCE_INLINE SHashNode *doUpdateHashNode(SHashNode *pNode, SHashNode *pNewNode) {
assert(pNode->keyLen == pNewNode->keyLen);
SWAP(pNode->key, pNewNode->key, void *);
SWAP(pNode->data, pNewNode->data, void *);
return pNewNode;
}
/** /**
* insert the hash node at the front of the linked list * insert the hash node at the front of the linked list
...@@ -155,7 +129,7 @@ static SHashNode *doUpdateHashNode(SHashNode *pNode, const void *key, size_t key ...@@ -155,7 +129,7 @@ static SHashNode *doUpdateHashNode(SHashNode *pNode, const void *key, size_t key
* @param pHashObj * @param pHashObj
* @param pNode * @param pNode
*/ */
static void doAddToHashTable(SHashObj *pHashObj, SHashNode *pNode); static void pushfrontNodeInEntryList(SHashEntry *pEntry, SHashNode *pNode);
/** /**
* Get the next element in hash table for iterator * Get the next element in hash table for iterator
...@@ -164,7 +138,7 @@ static void doAddToHashTable(SHashObj *pHashObj, SHashNode *pNode); ...@@ -164,7 +138,7 @@ static void doAddToHashTable(SHashObj *pHashObj, SHashNode *pNode);
*/ */
static SHashNode *getNextHashNode(SHashMutableIterator *pIter); static SHashNode *getNextHashNode(SHashMutableIterator *pIter);
SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool threadsafe) { SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTypeE type) {
if (capacity == 0 || fn == NULL) { if (capacity == 0 || fn == NULL) {
return NULL; return NULL;
} }
...@@ -180,151 +154,360 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool threadsafe) { ...@@ -180,151 +154,360 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool threadsafe) {
assert((pHashObj->capacity & (pHashObj->capacity - 1)) == 0); assert((pHashObj->capacity & (pHashObj->capacity - 1)) == 0);
pHashObj->hashFp = fn; pHashObj->hashFp = fn;
pHashObj->type = type;
pHashObj->enableUpdate = update;
pHashObj->hashList = (SHashNode **)calloc(pHashObj->capacity, POINTER_BYTES); pHashObj->hashList = (SHashEntry **)calloc(pHashObj->capacity, sizeof(void *));
if (pHashObj->hashList == NULL) { if (pHashObj->hashList == NULL) {
free(pHashObj); free(pHashObj);
uError("failed to allocate memory, reason:%s", strerror(errno)); uError("failed to allocate memory, reason:%s", strerror(errno));
return NULL; return NULL;
} } else {
pHashObj->pMemBlock = taosArrayInit(8, sizeof(void *));
if (threadsafe) {
#if defined(LINUX)
pHashObj->lock = calloc(1, sizeof(pthread_rwlock_t));
#else
pHashObj->lock = calloc(1, sizeof(pthread_mutex_t));
#endif
}
if (__lock_init(pHashObj->lock) != 0) { void *p = calloc(pHashObj->capacity, sizeof(SHashEntry));
free(pHashObj->hashList); for (int32_t i = 0; i < pHashObj->capacity; ++i) {
free(pHashObj); pHashObj->hashList[i] = p + i * sizeof(SHashEntry);
}
uError("failed to init lock, reason:%s", strerror(errno)); taosArrayPush(pHashObj->pMemBlock, &p);
return NULL;
} }
return pHashObj; return pHashObj;
} }
size_t taosHashGetSize(const SHashObj *pHashObj) { size_t taosHashGetSize(const SHashObj *pHashObj) { return (pHashObj == NULL) ? 0 : pHashObj->size; }
if (pHashObj == NULL) {
return 0;
}
return pHashObj->size;
}
int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size) { int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size) {
__wr_lock(pHashObj->lock); uint32_t hashVal = (*pHashObj->hashFp)(key, keyLen);
SHashNode *pNewNode = doCreateHashNode(key, keyLen, data, size, hashVal);
uint32_t hashVal = 0; if (pNewNode == NULL) {
SHashNode *pNode = doGetNodeFromHashTable(pHashObj, key, (uint32_t)keyLen, &hashVal); return -1;
}
if (pNode == NULL) { // no data in hash table with the specified key, add it into hash table // need the resize process, write lock applied
if (HASH_NEED_RESIZE(pHashObj)) {
__wr_lock(&pHashObj->lock, pHashObj->type);
taosHashTableResize(pHashObj); taosHashTableResize(pHashObj);
__wr_unlock(&pHashObj->lock, pHashObj->type);
}
SHashNode *pNewNode = doCreateHashNode(key, keyLen, data, size, hashVal); __rd_lock(&pHashObj->lock, pHashObj->type);
if (pNewNode == NULL) {
__unlock(pHashObj->lock);
return -1; int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
} SHashEntry *pe = pHashObj->hashList[slot];
if (pHashObj->type == HASH_ENTRY_LOCK) {
taosWLockLatch(&pe->latch);
}
doAddToHashTable(pHashObj, pNewNode); SHashNode *pNode = pe->next;
if (pe->num > 0) {
assert(pNode != NULL);
} else { } else {
SHashNode *pNewNode = doUpdateHashNode(pNode, key, keyLen, data, size); assert(pNode == NULL);
if (pNewNode == NULL) { }
__unlock(pHashObj->lock);
return -1; while (pNode) {
if ((pNode->keyLen == keyLen) && (memcmp(pNode->key, key, keyLen) == 0)) {
assert(pNode->hashVal == hashVal);
break;
} }
if (pNewNode->prev) { pNode = pNode->next;
pNewNode->prev->next = pNewNode; }
if (pNode == NULL) {
// no data in hash table with the specified key, add it into hash table
pushfrontNodeInEntryList(pe, pNewNode);
if (pe->num == 0) {
assert(pe->next == NULL);
} else { } else {
int32_t slot = HASH_INDEX(pNewNode->hashVal, pHashObj->capacity); assert(pe->next != NULL);
assert(pHashObj->hashList[slot] == pNode);
pHashObj->hashList[slot] = pNewNode;
} }
if (pNewNode->next) { if (pHashObj->type == HASH_ENTRY_LOCK) {
(pNewNode->next)->prev = pNewNode; taosWUnLockLatch(&pe->latch);
} }
}
__unlock(pHashObj->lock); // enable resize
return 0; __rd_unlock(&pHashObj->lock, pHashObj->type);
atomic_add_fetch_64(&pHashObj->size, 1);
return 0;
} else {
// not support the update operation, return error
if (pHashObj->enableUpdate) {
doUpdateHashNode(pNode, pNewNode);
}
if (pHashObj->type == HASH_ENTRY_LOCK) {
taosWUnLockLatch(&pe->latch);
}
// enable resize
__rd_unlock(&pHashObj->lock, pHashObj->type);
DO_FREE_HASH_NODE(pNewNode);
return pHashObj->enableUpdate ? 0 : -1;
}
} }
void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen) { void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen) {
__rd_lock(pHashObj->lock); return taosHashGetCB(pHashObj, key, keyLen, NULL);
}
void *taosHashGetCB(SHashObj *pHashObj, const void *key, size_t keyLen, void (*fp)(void *)) {
if (pHashObj->size <= 0 || keyLen == 0 || key == NULL) {
return NULL;
}
uint32_t hashVal = 0; uint32_t hashVal = (*pHashObj->hashFp)(key, keyLen);
SHashNode *pNode = doGetNodeFromHashTable(pHashObj, key, (int32_t)keyLen, &hashVal);
__unlock(pHashObj->lock); // only add the read lock to disable the resize process
__rd_lock(&pHashObj->lock, pHashObj->type);
if (pNode != NULL) { int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
assert(pNode->hashVal == hashVal); SHashEntry *pe = pHashObj->hashList[slot];
return pNode->data; // no data, return directly
} else { if (atomic_load_32(&pe->num) == 0) {
__rd_unlock(&pHashObj->lock, pHashObj->type);
return NULL; return NULL;
} }
char *data = NULL;
// lock entry
if (pHashObj->type == HASH_ENTRY_LOCK) {
taosRLockLatch(&pe->latch);
}
if (pe->num > 0) {
assert(pe->next != NULL);
} else {
assert(pe->next == NULL);
}
SHashNode *pNode = doSearchInEntryList(pe, key, keyLen, hashVal);
if (pNode != NULL) {
if (fp != NULL) {
fp(pNode->data);
}
data = pNode->data;
}
if (pHashObj->type == HASH_ENTRY_LOCK) {
taosRUnLockLatch(&pe->latch);
}
__rd_unlock(&pHashObj->lock, pHashObj->type);
return data;
} }
void taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen) { int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen) {
__wr_lock(pHashObj->lock); return taosHashRemoveWithData(pHashObj, key, keyLen, NULL, 0);
}
uint32_t val = 0; int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t dsize) {
SHashNode *pNode = doGetNodeFromHashTable(pHashObj, key, (uint32_t)keyLen, &val); if (pHashObj == NULL || pHashObj->size <= 0) {
if (pNode == NULL) { return -1;
__unlock(pHashObj->lock); }
return;
uint32_t hashVal = (*pHashObj->hashFp)(key, keyLen);
// disable the resize process
__rd_lock(&pHashObj->lock, pHashObj->type);
int32_t slot = HASH_INDEX(hashVal, pHashObj->capacity);
SHashEntry *pe = pHashObj->hashList[slot];
// no data, return directly
if (pe->num == 0) {
assert(pe->next == NULL);
__rd_unlock(&pHashObj->lock, pHashObj->type);
return -1;
}
if (pHashObj->type == HASH_ENTRY_LOCK) {
taosWLockLatch(&pe->latch);
}
if (pe->num == 0) {
assert(pe->next == NULL);
} else {
assert(pe->next != NULL);
} }
SHashNode *pNext = pNode->next; // double check after locked
if (pNode->prev == NULL) { if (pe->num == 0) {
int32_t slot = HASH_INDEX(val, pHashObj->capacity); assert(pe->next == NULL);
assert(pHashObj->hashList[slot] == pNode); taosWUnLockLatch(&pe->latch);
pHashObj->hashList[slot] = pNext; __rd_unlock(&pHashObj->lock, pHashObj->type);
return -1;
}
SHashNode *pNode = pe->next;
SHashNode *pRes = NULL;
// remove it
if ((pNode->keyLen == keyLen) && (memcmp(pNode->key, key, keyLen) == 0)) {
pe->num -= 1;
pRes = pNode;
pe->next = pNode->next;
} else {
while (pNode->next != NULL) {
if (((pNode->next)->keyLen == keyLen) && (memcmp((pNode->next)->key, key, keyLen) == 0)) {
assert((pNode->next)->hashVal == hashVal);
break;
}
pNode = pNode->next;
}
if (pNode->next != NULL) {
pe->num -= 1;
pRes = pNode->next;
pNode->next = pNode->next->next;
}
}
if (pHashObj->type == HASH_ENTRY_LOCK) {
taosWUnLockLatch(&pe->latch);
}
__rd_unlock(&pHashObj->lock, pHashObj->type);
if (data != NULL && pRes != NULL) {
memcpy(data, pRes->data, dsize);
}
if (pRes != NULL) {
atomic_sub_fetch_64(&pHashObj->size, 1);
FREE_HASH_NODE(pHashObj, pRes);
if (pe->num == 0) {
assert(pe->next == NULL);
} else {
assert(pe->next != NULL);
}
return 0;
} else { } else {
pNode->prev->next = pNext;
if (pe->num == 0) {
assert(pe->next == NULL);
} else {
assert(pe->next != NULL);
}
return -1;
} }
}
if (pNext != NULL) {
pNext->prev = pNode->prev; int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), void *param) {
if (pHashObj == NULL || pHashObj->size == 0) {
return 0;
} }
pHashObj->size--; // disable the resize process
__rd_lock(&pHashObj->lock, pHashObj->type);
int32_t numOfEntries = pHashObj->capacity;
for (int32_t i = 0; i < numOfEntries; ++i) {
SHashEntry *pEntry = pHashObj->hashList[i];
if (pEntry->num == 0) {
continue;
}
if (pHashObj->type == HASH_ENTRY_LOCK) {
taosWLockLatch(&pEntry->latch);
}
// todo remove the first node
SHashNode *pNode = NULL;
while((pNode = pEntry->next) != NULL) {
if (fp && (!fp(param, pNode->data))) {
pEntry->num -= 1;
atomic_sub_fetch_64(&pHashObj->size, 1);
pEntry->next = pNode->next;
pNode->next = NULL; if (pEntry->num == 0) {
pNode->prev = NULL; assert(pEntry->next == NULL);
} else {
assert(pEntry->next != NULL);
}
FREE_HASH_NODE(pHashObj, pNode);
} else {
break;
}
}
// handle the following node
if (pNode != NULL) {
assert(pNode == pEntry->next);
SHashNode *pNext = NULL;
while ((pNext = pNode->next) != NULL) {
// not qualified, remove it
if (fp && (!fp(param, pNext->data))) {
pNode->next = pNext->next;
pEntry->num -= 1;
atomic_sub_fetch_64(&pHashObj->size, 1);
if (pEntry->num == 0) {
assert(pEntry->next == NULL);
} else {
assert(pEntry->next != NULL);
}
FREE_HASH_NODE(pHashObj, pNext);
} else {
pNode = pNext;
}
}
}
if (pHashObj->type == HASH_ENTRY_LOCK) {
taosWUnLockLatch(&pEntry->latch);
}
}
taosTFree(pNode); __rd_unlock(&pHashObj->lock, pHashObj->type);
__unlock(pHashObj->lock); return 0;
} }
void taosHashCleanup(SHashObj *pHashObj) { void taosHashCleanup(SHashObj *pHashObj) {
if (pHashObj == NULL) return; if (pHashObj == NULL) {
return;
}
SHashNode *pNode, *pNext; SHashNode *pNode, *pNext;
__wr_lock(pHashObj->lock); __wr_lock(&pHashObj->lock, pHashObj->type);
if (pHashObj->hashList) { if (pHashObj->hashList) {
for (int32_t i = 0; i < pHashObj->capacity; ++i) { for (int32_t i = 0; i < pHashObj->capacity; ++i) {
pNode = pHashObj->hashList[i]; SHashEntry *pEntry = pHashObj->hashList[i];
if (pEntry->num == 0) {
assert(pEntry->next == 0);
continue;
}
pNode = pEntry->next;
assert(pNode != NULL);
while (pNode) { while (pNode) {
pNext = pNode->next; pNext = pNode->next;
if (pHashObj->freeFp) { FREE_HASH_NODE(pHashObj, pNode);
pHashObj->freeFp(pNode->data);
}
free(pNode);
pNode = pNext; pNode = pNext;
} }
} }
...@@ -332,20 +515,19 @@ void taosHashCleanup(SHashObj *pHashObj) { ...@@ -332,20 +515,19 @@ void taosHashCleanup(SHashObj *pHashObj) {
free(pHashObj->hashList); free(pHashObj->hashList);
} }
__unlock(pHashObj->lock); __wr_unlock(&pHashObj->lock, pHashObj->type);
__lock_destroy(pHashObj->lock);
taosTFree(pHashObj->lock); // destroy mem block
memset(pHashObj, 0, sizeof(SHashObj)); size_t memBlock = taosArrayGetSize(pHashObj->pMemBlock);
free(pHashObj); for (int32_t i = 0; i < memBlock; ++i) {
} void *p = taosArrayGetP(pHashObj->pMemBlock, i);
taosTFree(p);
void taosHashSetFreecb(SHashObj *pHashObj, _hash_free_fn_t freeFp) {
if (pHashObj == NULL || freeFp == NULL) {
return;
} }
pHashObj->freeFp = freeFp; taosArrayDestroy(pHashObj->pMemBlock);
memset(pHashObj, 0, sizeof(SHashObj));
free(pHashObj);
} }
SHashMutableIterator *taosHashCreateIter(SHashObj *pHashObj) { SHashMutableIterator *taosHashCreateIter(SHashObj *pHashObj) {
...@@ -355,6 +537,9 @@ SHashMutableIterator *taosHashCreateIter(SHashObj *pHashObj) { ...@@ -355,6 +537,9 @@ SHashMutableIterator *taosHashCreateIter(SHashObj *pHashObj) {
} }
pIter->pHashObj = pHashObj; pIter->pHashObj = pHashObj;
// keep it in local variable, in case the resize operation expand the size
pIter->numOfEntries = pHashObj->capacity;
return pIter; return pIter;
} }
...@@ -369,28 +554,42 @@ bool taosHashIterNext(SHashMutableIterator *pIter) { ...@@ -369,28 +554,42 @@ bool taosHashIterNext(SHashMutableIterator *pIter) {
} }
// check the first one // check the first one
if (pIter->num == 0) { if (pIter->numOfChecked == 0) {
assert(pIter->pCur == NULL && pIter->pNext == NULL); assert(pIter->pCur == NULL && pIter->pNext == NULL);
while (1) { while (1) {
SHashNode *pEntry = pIter->pHashObj->hashList[pIter->entryIndex]; SHashEntry *pEntry = pIter->pHashObj->hashList[pIter->entryIndex];
if (pEntry == NULL) { if (pEntry->num == 0) {
assert(pEntry->next == NULL);
pIter->entryIndex++; pIter->entryIndex++;
continue; continue;
} }
pIter->pCur = pEntry; if (pIter->pHashObj->type == HASH_ENTRY_LOCK) {
taosRLockLatch(&pEntry->latch);
}
pIter->pCur = pEntry->next;
if (pIter->pCur->next) { if (pIter->pCur->next) {
pIter->pNext = pIter->pCur->next; pIter->pNext = pIter->pCur->next;
if (pIter->pHashObj->type == HASH_ENTRY_LOCK) {
taosRUnLockLatch(&pEntry->latch);
}
} else { } else {
if (pIter->pHashObj->type == HASH_ENTRY_LOCK) {
taosRUnLockLatch(&pEntry->latch);
}
pIter->pNext = getNextHashNode(pIter); pIter->pNext = getNextHashNode(pIter);
} }
break; break;
} }
pIter->num++; pIter->numOfChecked++;
return true; return true;
} else { } else {
assert(pIter->pCur != NULL); assert(pIter->pCur != NULL);
...@@ -400,7 +599,7 @@ bool taosHashIterNext(SHashMutableIterator *pIter) { ...@@ -400,7 +599,7 @@ bool taosHashIterNext(SHashMutableIterator *pIter) {
return false; return false;
} }
pIter->num++; pIter->numOfChecked++;
if (pIter->pCur->next) { if (pIter->pCur->next) {
pIter->pNext = pIter->pCur->next; pIter->pNext = pIter->pCur->next;
...@@ -432,19 +631,9 @@ int32_t taosHashGetMaxOverflowLinkLength(const SHashObj *pHashObj) { ...@@ -432,19 +631,9 @@ int32_t taosHashGetMaxOverflowLinkLength(const SHashObj *pHashObj) {
int32_t num = 0; int32_t num = 0;
for (int32_t i = 0; i < pHashObj->size; ++i) { for (int32_t i = 0; i < pHashObj->size; ++i) {
SHashNode *pEntry = pHashObj->hashList[i]; SHashEntry *pEntry = pHashObj->hashList[i];
if (pEntry == NULL) { if (num < pEntry->num) {
continue; num = pEntry->num;
}
int32_t j = 0;
while(pEntry != NULL) {
pEntry = pEntry->next;
j++;
}
if (num < j) {
num = j;
} }
} }
...@@ -452,146 +641,166 @@ int32_t taosHashGetMaxOverflowLinkLength(const SHashObj *pHashObj) { ...@@ -452,146 +641,166 @@ int32_t taosHashGetMaxOverflowLinkLength(const SHashObj *pHashObj) {
} }
void taosHashTableResize(SHashObj *pHashObj) { void taosHashTableResize(SHashObj *pHashObj) {
if (pHashObj->size < pHashObj->capacity * HASH_DEFAULT_LOAD_FACTOR) { if (!HASH_NEED_RESIZE(pHashObj)) {
return; return;
} }
// double the original capacity // double the original capacity
SHashNode *pNode = NULL; SHashNode *pNode = NULL;
SHashNode *pNext = NULL; SHashNode *pNext = NULL;
int32_t newSize = (int32_t)(pHashObj->capacity) << 1u; int32_t newSize = pHashObj->capacity << 1u;
if (newSize > HASH_MAX_CAPACITY) { if (newSize > HASH_MAX_CAPACITY) {
// uDebug("current capacity:%d, maximum capacity:%d, no resize applied due to limitation is reached", // uDebug("current capacity:%d, maximum capacity:%d, no resize applied due to limitation is reached",
// pHashObj->capacity, HASH_MAX_CAPACITY); // pHashObj->capacity, HASH_MAX_CAPACITY);
return; return;
} }
int32_t pointerSize = POINTER_BYTES; int64_t st = taosGetTimestampUs();
void *pNewEntry = realloc(pHashObj->hashList, pointerSize * newSize); void *pNewEntryList = realloc(pHashObj->hashList, sizeof(void*) * newSize);
if (pNewEntry == NULL) {// todo handle error if (pNewEntryList == NULL) { // todo handle error
// uDebug("cache resize failed due to out of memory, capacity remain:%d", pHashObj->capacity); // uDebug("cache resize failed due to out of memory, capacity remain:%d", pHashObj->capacity);
return; return;
} }
pHashObj->hashList = pNewEntry; pHashObj->hashList = pNewEntryList;
memset(&pHashObj->hashList[pHashObj->capacity], 0, POINTER_BYTES * (newSize - pHashObj->capacity));
size_t inc = newSize - pHashObj->capacity;
void * p = calloc(inc, sizeof(SHashEntry));
for (int32_t i = 0; i < inc; ++i) {
pHashObj->hashList[i + pHashObj->capacity] = p + i * sizeof(SHashEntry);
}
taosArrayPush(pHashObj->pMemBlock, &p);
pHashObj->capacity = newSize; pHashObj->capacity = newSize;
for (int32_t i = 0; i < pHashObj->capacity; ++i) { for (int32_t i = 0; i < pHashObj->capacity; ++i) {
pNode = pHashObj->hashList[i]; SHashEntry *pe = pHashObj->hashList[i];
if (pNode != NULL) {
assert(pNode->prev == NULL); if (pe->num == 0) {
assert(pe->next == NULL);
} else {
assert(pe->next != NULL);
} }
while (pNode) { if (pe->num == 0) {
assert(pe->next == NULL);
continue;
}
while ((pNode = pe->next) != NULL) {
int32_t j = HASH_INDEX(pNode->hashVal, pHashObj->capacity); int32_t j = HASH_INDEX(pNode->hashVal, pHashObj->capacity);
if (j == i) { // this key locates in the same slot, no need to relocate it if (j != i) {
pNode = pNode->next; pe->num -= 1;
} else { pe->next = pNode->next;
pNext = pNode->next;
if (pe->num == 0) {
if (pNode->prev == NULL) { // first node of the overflow linked list assert(pe->next == NULL);
pHashObj->hashList[i] = pNext;
} else { } else {
pNode->prev->next = pNext; assert(pe->next != NULL);
} }
if (pNext != NULL) { SHashEntry *pNewEntry = pHashObj->hashList[j];
pNext->prev = pNode->prev; pushfrontNodeInEntryList(pNewEntry, pNode);
} } else {
break;
// clear pointer }
pNode->next = NULL; }
pNode->prev = NULL;
if (pNode != NULL) {
// added into new slot while ((pNext = pNode->next) != NULL) {
SHashNode *pNew = pHashObj->hashList[j]; int32_t j = HASH_INDEX(pNext->hashVal, pHashObj->capacity);
if (pNew != NULL) { if (j != i) {
assert(pNew->prev == NULL); pe->num -= 1;
pNew->prev = pNode;
pNode->next = pNext->next;
pNext->next = NULL;
// added into new slot
SHashEntry *pNewEntry = pHashObj->hashList[j];
if (pNewEntry->num == 0) {
assert(pNewEntry->next == NULL);
} else {
assert(pNewEntry->next != NULL);
}
pushfrontNodeInEntryList(pNewEntry, pNext);
} else {
pNode = pNext;
} }
pNode->next = pNew;
pHashObj->hashList[j] = pNode;
// continue
pNode = pNext;
} }
if (pe->num == 0) {
assert(pe->next == NULL);
} else {
assert(pe->next != NULL);
}
} }
} }
// uDebug("hash table resize completed, new capacity:%d, load factor:%f, elapsed time:%fms", pHashObj->capacity, int64_t et = taosGetTimestampUs();
// ((double)pHashObj->size) / pHashObj->capacity, (et - st) / 1000.0);
uDebug("hash table resize completed, new capacity:%"PRId64", load factor:%f, elapsed time:%fms", pHashObj->capacity,
((double)pHashObj->size) / pHashObj->capacity, (et - st) / 1000.0);
} }
SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, size_t dsize, uint32_t hashVal) { SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, size_t dsize, uint32_t hashVal) {
size_t totalSize = dsize + sizeof(SHashNode) + keyLen; SHashNode *pNewNode = calloc(1, sizeof(SHashNode));
SHashNode *pNewNode = calloc(1, totalSize);
if (pNewNode == NULL) { if (pNewNode == NULL) {
uError("failed to allocate memory, reason:%s", strerror(errno)); uError("failed to allocate memory, reason:%s", strerror(errno));
return NULL; return NULL;
} }
pNewNode->data = malloc(dsize + keyLen);
memcpy(pNewNode->data, pData, dsize); memcpy(pNewNode->data, pData, dsize);
pNewNode->key = pNewNode->data + dsize; pNewNode->key = pNewNode->data + dsize;
memcpy(pNewNode->key, key, keyLen); memcpy(pNewNode->key, key, keyLen);
pNewNode->keyLen = (uint32_t)keyLen;
pNewNode->keyLen = keyLen;
pNewNode->hashVal = hashVal; pNewNode->hashVal = hashVal;
return pNewNode; return pNewNode;
} }
SHashNode *doUpdateHashNode(SHashNode *pNode, const void *key, size_t keyLen, const void *pData, size_t dsize) { void pushfrontNodeInEntryList(SHashEntry *pEntry, SHashNode *pNode) {
size_t size = dsize + sizeof(SHashNode) + keyLen; assert(pNode != NULL && pEntry != NULL);
SHashNode *pNewNode = (SHashNode *)realloc(pNode, size);
if (pNewNode == NULL) {
return NULL;
}
memcpy(pNewNode->data, pData, dsize);
pNewNode->key = pNewNode->data + dsize;
assert(memcmp(pNewNode->key, key, keyLen) == 0 && keyLen == pNewNode->keyLen);
memcpy(pNewNode->key, key, keyLen);
return pNewNode;
}
void doAddToHashTable(SHashObj *pHashObj, SHashNode *pNode) { pNode->next = pEntry->next;
assert(pNode != NULL); pEntry->next = pNode;
int32_t index = HASH_INDEX(pNode->hashVal, pHashObj->capacity); pEntry->num += 1;
SHashNode* pEntry = pHashObj->hashList[index];
if (pEntry != NULL) {
pEntry->prev = pNode;
pNode->next = pEntry;
pNode->prev = NULL;
}
pHashObj->hashList[index] = pNode;
pHashObj->size++;
} }
SHashNode *getNextHashNode(SHashMutableIterator *pIter) { SHashNode *getNextHashNode(SHashMutableIterator *pIter) {
assert(pIter != NULL); assert(pIter != NULL);
pIter->entryIndex++; pIter->entryIndex++;
while (pIter->entryIndex < pIter->pHashObj->capacity) { SHashNode *p = NULL;
SHashNode *pNode = pIter->pHashObj->hashList[pIter->entryIndex];
if (pNode == NULL) { while (pIter->entryIndex < pIter->numOfEntries) {
SHashEntry *pEntry = pIter->pHashObj->hashList[pIter->entryIndex];
if (pEntry->num == 0) {
pIter->entryIndex++; pIter->entryIndex++;
continue; continue;
} }
return pNode; if (pIter->pHashObj->type == HASH_ENTRY_LOCK) {
taosRLockLatch(&pEntry->latch);
}
p = pEntry->next;
if (pIter->pHashObj->type == HASH_ENTRY_LOCK) {
taosRUnLockLatch(&pEntry->latch);
}
return p;
} }
return NULL; return NULL;
} }
...@@ -30,14 +30,6 @@ static FORCE_INLINE void __cache_wr_lock(SCacheObj *pCacheObj) { ...@@ -30,14 +30,6 @@ static FORCE_INLINE void __cache_wr_lock(SCacheObj *pCacheObj) {
#endif #endif
} }
static FORCE_INLINE void __cache_rd_lock(SCacheObj *pCacheObj) {
#if defined(LINUX)
pthread_rwlock_rdlock(&pCacheObj->lock);
#else
pthread_mutex_lock(&pCacheObj->lock);
#endif
}
static FORCE_INLINE void __cache_unlock(SCacheObj *pCacheObj) { static FORCE_INLINE void __cache_unlock(SCacheObj *pCacheObj) {
#if defined(LINUX) #if defined(LINUX)
pthread_rwlock_unlock(&pCacheObj->lock); pthread_rwlock_unlock(&pCacheObj->lock);
...@@ -62,13 +54,6 @@ static FORCE_INLINE void __cache_lock_destroy(SCacheObj *pCacheObj) { ...@@ -62,13 +54,6 @@ static FORCE_INLINE void __cache_lock_destroy(SCacheObj *pCacheObj) {
#endif #endif
} }
#if 0
static FORCE_INLINE void taosFreeNode(void *data) {
SCacheDataNode *pNode = *(SCacheDataNode **)data;
free(pNode);
}
#endif
/** /**
* @param key key of object for hash, usually a null-terminated string * @param key key of object for hash, usually a null-terminated string
* @param keyLen length of key * @param keyLen length of key
...@@ -88,13 +73,6 @@ static SCacheDataNode *taosCreateCacheNode(const char *key, size_t keyLen, const ...@@ -88,13 +73,6 @@ static SCacheDataNode *taosCreateCacheNode(const char *key, size_t keyLen, const
*/ */
static void taosAddToTrash(SCacheObj *pCacheObj, SCacheDataNode *pNode); static void taosAddToTrash(SCacheObj *pCacheObj, SCacheDataNode *pNode);
/**
* remove node in trash can
* @param pCacheObj
* @param pElem
*/
static void taosRemoveFromTrashCan(SCacheObj *pCacheObj, STrashElem *pElem);
/** /**
* remove nodes in trash with refCount == 0 in cache * remove nodes in trash with refCount == 0 in cache
* @param pNode * @param pNode
...@@ -107,111 +85,54 @@ static void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force); ...@@ -107,111 +85,54 @@ static void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force);
/** /**
* release node * release node
* @param pCacheObj cache object * @param pCacheObj cache object
* @param pNode data node * @param pNode data node
*/ */
static FORCE_INLINE void taosCacheReleaseNode(SCacheObj *pCacheObj, SCacheDataNode *pNode) { static FORCE_INLINE void taosCacheReleaseNode(SCacheObj *pCacheObj, SCacheDataNode *pNode) {
if (pNode->signature != (uint64_t)pNode) { if (pNode->signature != (uint64_t)pNode) {
uError("key:%s, %p data is invalid, or has been released", pNode->key, pNode); uError("key:%s, %p data is invalid, or has been released", pNode->key, pNode);
assert(0);
return; return;
} }
taosHashRemove(pCacheObj->pHashTable, pNode->key, pNode->keySize);
pCacheObj->totalSize -= pNode->size; pCacheObj->totalSize -= pNode->size;
uDebug("cache:%s, key:%p, %p is destroyed from cache, totalNum:%d totalSize:%" PRId64 "bytes size:%dbytes", int32_t size = taosHashGetSize(pCacheObj->pHashTable);
pCacheObj->name, pNode->key, pNode->data, (int32_t)taosHashGetSize(pCacheObj->pHashTable), pCacheObj->totalSize, assert(size > 0);
pNode->size);
uDebug("cache:%s, key:%p, %p is destroyed from cache, size:%dbytes, num:%d size:%" PRId64 "bytes",
pCacheObj->name, pNode->key, pNode->data, pNode->size, size - 1, pCacheObj->totalSize);
if (pCacheObj->freeFp) {
pCacheObj->freeFp(pNode->data);
}
if (pCacheObj->freeFp) pCacheObj->freeFp(pNode->data);
free(pNode); free(pNode);
} }
/** static FORCE_INLINE void doRemoveElemInTrashcan(SCacheObj* pCacheObj, STrashElem *pElem) {
* move the old node into trash if (pElem->pData->signature != (uint64_t) pElem->pData) {
* @param pCacheObj uError("key:sig:0x%" PRIx64 " %p data has been released, ignore", pElem->pData->signature, pElem->pData);
* @param pNode return;
*/ }
static FORCE_INLINE void taosCacheMoveToTrash(SCacheObj *pCacheObj, SCacheDataNode *pNode) {
taosHashRemove(pCacheObj->pHashTable, pNode->key, pNode->keySize);
taosAddToTrash(pCacheObj, pNode);
}
/** pCacheObj->numOfElemsInTrash--;
* update data in cache if (pElem->prev) {
* @param pCacheObj pElem->prev->next = pElem->next;
* @param pNode } else { // pnode is the header, update header
* @param key pCacheObj->pTrash = pElem->next;
* @param keyLen }
* @param pData
* @param dataSize if (pElem->next) {
* @return pElem->next->prev = pElem->prev;
*/
static SCacheDataNode *taosUpdateCacheImpl(SCacheObj *pCacheObj, SCacheDataNode *pNode, const char *key, int32_t keyLen,
const void *pData, uint32_t dataSize, uint64_t duration) {
SCacheDataNode *pNewNode = NULL;
// only a node is not referenced by any other object, in-place update it
if (T_REF_VAL_GET(pNode) == 0) {
size_t newSize = sizeof(SCacheDataNode) + dataSize + keyLen + 1;
pNewNode = (SCacheDataNode *)realloc(pNode, newSize);
if (pNewNode == NULL) {
return NULL;
}
memset(pNewNode, 0, newSize);
pNewNode->signature = (uint64_t)pNewNode;
memcpy(pNewNode->data, pData, dataSize);
pNewNode->key = (char *)pNewNode + sizeof(SCacheDataNode) + dataSize;
pNewNode->keySize = keyLen;
memcpy(pNewNode->key, key, keyLen);
// update the timestamp information for updated key/value
pNewNode->addedTime = taosGetTimestampMs();
pNewNode->lifespan = duration;
T_REF_INC(pNewNode);
// the address of this node may be changed, so the prev and next element should update the corresponding pointer
taosHashPut(pCacheObj->pHashTable, key, keyLen, &pNewNode, sizeof(void *));
} else {
taosCacheMoveToTrash(pCacheObj, pNode);
pNewNode = taosCreateCacheNode(key, keyLen, pData, dataSize, duration);
if (pNewNode == NULL) {
return NULL;
}
T_REF_INC(pNewNode);
// addedTime new element to hashtable
taosHashPut(pCacheObj->pHashTable, key, keyLen, &pNewNode, sizeof(void *));
} }
return pNewNode;
} }
/** static FORCE_INLINE void doDestroyTrashcanElem(SCacheObj* pCacheObj, STrashElem *pElem) {
* addedTime data into hash table if (pCacheObj->freeFp) {
* @param key pCacheObj->freeFp(pElem->pData->data);
* @param pData
* @param size
* @param pCacheObj
* @param keyLen
* @param pNode
* @return
*/
static FORCE_INLINE SCacheDataNode *taosAddToCacheImpl(SCacheObj *pCacheObj, const char *key, size_t keyLen, const void *pData,
size_t dataSize, uint64_t duration) {
SCacheDataNode *pNode = taosCreateCacheNode(key, keyLen, pData, dataSize, duration);
if (pNode == NULL) {
return NULL;
} }
T_REF_INC(pNode); free(pElem->pData);
taosHashPut(pCacheObj->pHashTable, key, keyLen, &pNode, sizeof(void *)); free(pElem);
return pNode;
} }
/** /**
...@@ -237,7 +158,7 @@ SCacheObj *taosCacheInit(int32_t keyType, int64_t refreshTimeInSeconds, bool ext ...@@ -237,7 +158,7 @@ SCacheObj *taosCacheInit(int32_t keyType, int64_t refreshTimeInSeconds, bool ext
return NULL; return NULL;
} }
pCacheObj->pHashTable = taosHashInit(128, taosGetDefaultHashFunction(keyType), false); pCacheObj->pHashTable = taosHashInit(4096, taosGetDefaultHashFunction(keyType), false, HASH_ENTRY_LOCK);
pCacheObj->name = strdup(cacheName); pCacheObj->name = strdup(cacheName);
if (pCacheObj->pHashTable == NULL) { if (pCacheObj->pHashTable == NULL) {
free(pCacheObj); free(pCacheObj);
...@@ -269,95 +190,94 @@ SCacheObj *taosCacheInit(int32_t keyType, int64_t refreshTimeInSeconds, bool ext ...@@ -269,95 +190,94 @@ SCacheObj *taosCacheInit(int32_t keyType, int64_t refreshTimeInSeconds, bool ext
} }
void *taosCachePut(SCacheObj *pCacheObj, const void *key, size_t keyLen, const void *pData, size_t dataSize, int duration) { void *taosCachePut(SCacheObj *pCacheObj, const void *key, size_t keyLen, const void *pData, size_t dataSize, int duration) {
SCacheDataNode *pNode;
if (pCacheObj == NULL || pCacheObj->pHashTable == NULL) { if (pCacheObj == NULL || pCacheObj->pHashTable == NULL) {
return NULL; return NULL;
} }
__cache_wr_lock(pCacheObj); SCacheDataNode *pNode1 = taosCreateCacheNode(key, keyLen, pData, dataSize, duration);
SCacheDataNode **pt = (SCacheDataNode **)taosHashGet(pCacheObj->pHashTable, key, keyLen); if (pNode1 == NULL) {
SCacheDataNode * pOld = (pt != NULL) ? (*pt) : NULL; uError("cache:%s, key:%p, failed to added into cache, out of memory", pCacheObj->name, key);
return NULL;
if (pOld == NULL) { // do addedTime to cache
pNode = taosAddToCacheImpl(pCacheObj, key, keyLen, pData, dataSize, duration * 1000L);
if (NULL != pNode) {
pCacheObj->totalSize += pNode->size;
uDebug("cache:%s, key:%p, %p added into cache, added:%" PRIu64 ", expire:%" PRIu64 ", totalNum:%d totalSize:%" PRId64
"bytes size:%" PRId64 "bytes",
pCacheObj->name, key, pNode->data, pNode->addedTime, pNode->expireTime,
(int32_t)taosHashGetSize(pCacheObj->pHashTable), pCacheObj->totalSize, (int64_t)dataSize);
} else {
uError("cache:%s, key:%p, failed to added into cache, out of memory", pCacheObj->name, key);
}
} else { // old data exists, update the node
pNode = taosUpdateCacheImpl(pCacheObj, pOld, key, (int32_t)keyLen, pData, (uint32_t)dataSize, duration * 1000L);
uDebug("cache:%s, key:%p, %p exist in cache, updated old:%p", pCacheObj->name, key, pNode->data, pOld);
} }
__cache_unlock(pCacheObj); T_REF_INC(pNode1);
int32_t succ = taosHashPut(pCacheObj->pHashTable, key, keyLen, &pNode1, sizeof(void *));
if (succ == 0) {
atomic_add_fetch_64(&pCacheObj->totalSize, pNode1->size);
uDebug("cache:%s, key:%p, %p added into cache, added:%" PRIu64 ", expire:%" PRIu64
", totalNum:%d totalSize:%" PRId64 "bytes size:%" PRId64 "bytes",
pCacheObj->name, key, pNode1->data, pNode1->addedTime, pNode1->expireTime,
(int32_t)taosHashGetSize(pCacheObj->pHashTable), pCacheObj->totalSize, (int64_t)dataSize);
} else { // duplicated key exists
while (1) {
SCacheDataNode* p = NULL;
int32_t ret = taosHashRemoveWithData(pCacheObj->pHashTable, key, keyLen, (void*) &p, sizeof(void*));
// add to trashcan
if (ret == 0) {
if (T_REF_VAL_GET(p) == 0) {
if (pCacheObj->freeFp) {
pCacheObj->freeFp(p->data);
}
taosTFree(p);
} else {
taosAddToTrash(pCacheObj, p);
uDebug("cache:%s, key:%p, %p exist in cache, updated old:%p", pCacheObj->name, key, pNode1->data, p);
}
}
return (pNode != NULL) ? pNode->data : NULL; assert(T_REF_VAL_GET(pNode1) == 1);
}
void *taosCacheAcquireByKey(SCacheObj *pCacheObj, const void *key, size_t keyLen) { ret = taosHashPut(pCacheObj->pHashTable, key, keyLen, &pNode1, sizeof(void *));
if (pCacheObj == NULL || taosHashGetSize(pCacheObj->pHashTable) == 0) { if (ret == 0) {
return NULL; atomic_add_fetch_64(&pCacheObj->totalSize, pNode1->size);
}
void *pData = NULL;
__cache_rd_lock(pCacheObj); uDebug("cache:%s, key:%p, %p added into cache, added:%" PRIu64 ", expire:%" PRIu64
", totalNum:%d totalSize:%" PRId64 "bytes size:%" PRId64 "bytes",
pCacheObj->name, key, pNode1->data, pNode1->addedTime, pNode1->expireTime,
(int32_t)taosHashGetSize(pCacheObj->pHashTable), pCacheObj->totalSize, (int64_t)dataSize);
SCacheDataNode **ptNode = (SCacheDataNode **)taosHashGet(pCacheObj->pHashTable, key, keyLen); return pNode1->data;
int32_t ref = 0; } else {
if (ptNode != NULL) { // failed, try again
ref = T_REF_INC(*ptNode); }
pData = (*ptNode)->data; }
} }
__cache_unlock(pCacheObj); return pNode1->data;
}
if (pData != NULL) { static void incRefFn(void* ptNode) {
atomic_add_fetch_32(&pCacheObj->statistics.hitCount, 1); assert(ptNode != NULL);
uDebug("cache:%s, key:%p, %p is retrieved from cache, refcnt:%d", pCacheObj->name, key, pData, ref);
} else {
atomic_add_fetch_32(&pCacheObj->statistics.missCount, 1);
uDebug("cache:%s, key:%p, not in cache, retrieved failed", pCacheObj->name, key);
}
atomic_add_fetch_32(&pCacheObj->statistics.totalAccess, 1); SCacheDataNode** p = (SCacheDataNode**) ptNode;
return pData; assert(T_REF_VAL_GET(*p) >= 0);
int32_t ret = T_REF_INC(*p);
assert(ret > 0);
} }
void* taosCacheUpdateExpireTimeByName(SCacheObj *pCacheObj, void *key, size_t keyLen, uint64_t expireTime) { void *taosCacheAcquireByKey(SCacheObj *pCacheObj, const void *key, size_t keyLen) {
if (pCacheObj == NULL || taosHashGetSize(pCacheObj->pHashTable) == 0) { if (pCacheObj == NULL || taosHashGetSize(pCacheObj->pHashTable) == 0) {
return NULL; return NULL;
} }
__cache_rd_lock(pCacheObj); SCacheDataNode **ptNode = (SCacheDataNode **)taosHashGetCB(pCacheObj->pHashTable, key, keyLen, incRefFn);
void* pData = (ptNode != NULL)? (*ptNode)->data:NULL;
SCacheDataNode **ptNode = (SCacheDataNode **)taosHashGet(pCacheObj->pHashTable, key, keyLen);
if (ptNode != NULL) {
T_REF_INC(*ptNode);
(*ptNode)->expireTime = expireTime; // taosGetTimestampMs() + (*ptNode)->lifespan;
}
__cache_unlock(pCacheObj);
if (ptNode != NULL) { if (pData != NULL) {
atomic_add_fetch_32(&pCacheObj->statistics.hitCount, 1); atomic_add_fetch_32(&pCacheObj->statistics.hitCount, 1);
uDebug("cache:%s, key:%p, %p expireTime is updated in cache, refcnt:%d", pCacheObj->name, key, uDebug("cache:%s, key:%p, %p is retrieved from cache, refcnt:%d", pCacheObj->name, key, pData, T_REF_VAL_GET(*ptNode));
(*ptNode)->data, T_REF_VAL_GET(*ptNode));
} else { } else {
atomic_add_fetch_32(&pCacheObj->statistics.missCount, 1); atomic_add_fetch_32(&pCacheObj->statistics.missCount, 1);
uDebug("cache:%s, key:%p, not in cache, retrieved failed", pCacheObj->name, key); uDebug("cache:%s, key:%p, not in cache, retrieved failed", pCacheObj->name, key);
} }
atomic_add_fetch_32(&pCacheObj->statistics.totalAccess, 1); atomic_add_fetch_32(&pCacheObj->statistics.totalAccess, 1);
return (ptNode != NULL) ? (*ptNode)->data : NULL; return pData;
} }
void *taosCacheAcquireByData(SCacheObj *pCacheObj, void *data) { void *taosCacheAcquireByData(SCacheObj *pCacheObj, void *data) {
...@@ -420,15 +340,16 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) { ...@@ -420,15 +340,16 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
if (pCacheObj->extendLifespan && (!inTrashCan) && (!_remove)) { if (pCacheObj->extendLifespan && (!inTrashCan) && (!_remove)) {
atomic_store_64(&pNode->expireTime, pNode->lifespan + taosGetTimestampMs()); atomic_store_64(&pNode->expireTime, pNode->lifespan + taosGetTimestampMs());
uDebug("cache:%s data:%p extend life time to %"PRId64 " before release", pCacheObj->name, pNode->data, pNode->expireTime); uDebug("cache:%s data:%p extend expire time: %"PRId64, pCacheObj->name, pNode->data, pNode->expireTime);
} }
if (_remove) { if (_remove) {
__cache_wr_lock(pCacheObj);
// NOTE: once refcount is decrease, pNode may be freed by other thread immediately. // NOTE: once refcount is decrease, pNode may be freed by other thread immediately.
int32_t ref = T_REF_DEC(pNode); char* key = pNode->key;
uDebug("cache:%s, key:%p, %p is released, refcnt:%d", pCacheObj->name, pNode->key, pNode->data, ref); char* d = pNode->data;
int32_t ref = T_REF_VAL_GET(pNode);
uDebug("cache:%s, key:%p, %p is released, refcnt:%d", pCacheObj->name, key, d, ref - 1);
/* /*
* If it is not referenced by other users, remove it immediately. Otherwise move this node to trashcan wait for all users * If it is not referenced by other users, remove it immediately. Otherwise move this node to trashcan wait for all users
...@@ -437,50 +358,85 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) { ...@@ -437,50 +358,85 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
* NOTE: previous ref is 0, and current ref is still 0, remove it. If previous is not 0, there is another thread * NOTE: previous ref is 0, and current ref is still 0, remove it. If previous is not 0, there is another thread
* that tries to do the same thing. * that tries to do the same thing.
*/ */
if (pNode->inTrashCan) { if (inTrashCan) {
ref = T_REF_DEC(pNode);
if (ref == 0) { if (ref == 0) {
assert(pNode->pTNodeHeader->pData == pNode); assert(pNode->pTNodeHeader->pData == pNode);
taosRemoveFromTrashCan(pCacheObj, pNode->pTNodeHeader);
__cache_wr_lock(pCacheObj);
doRemoveElemInTrashcan(pCacheObj, pNode->pTNodeHeader);
__cache_unlock(pCacheObj);
doDestroyTrashcanElem(pCacheObj, pNode->pTNodeHeader);
} }
} else { } else {
if (ref > 0) { // NOTE: remove it from hash in the first place, otherwise, the pNode may have been released by other thread
assert(pNode->pTNodeHeader == NULL); // when reaches here.
taosCacheMoveToTrash(pCacheObj, pNode); int32_t ret = taosHashRemove(pCacheObj->pHashTable, pNode->key, pNode->keySize);
} else { ref = T_REF_DEC(pNode);
taosCacheReleaseNode(pCacheObj, pNode);
// successfully remove from hash table, if failed, this node must have been move to trash already, do nothing.
// note that the remove operation can be executed only once.
if (ret == 0) {
if (ref > 0) {
assert(pNode->pTNodeHeader == NULL);
__cache_wr_lock(pCacheObj);
taosAddToTrash(pCacheObj, pNode);
__cache_unlock(pCacheObj);
} else { // ref == 0
atomic_sub_fetch_64(&pCacheObj->totalSize, pNode->size);
int32_t size = taosHashGetSize(pCacheObj->pHashTable);
uDebug("cache:%s, key:%p, %p is destroyed from cache, size:%dbytes, num:%d size:%" PRId64 "bytes",
pCacheObj->name, pNode->key, pNode->data, pNode->size, size, pCacheObj->totalSize);
if (pCacheObj->freeFp) {
pCacheObj->freeFp(pNode->data);
}
free(pNode);
}
} }
} }
__cache_unlock(pCacheObj);
} else { } else {
// NOTE: once refcount is decrease, pNode may be freed by other thread immediately. // NOTE: once refcount is decrease, pNode may be freed by other thread immediately.
char* key = pNode->key;
char* p = pNode->data;
int32_t ref = T_REF_DEC(pNode); int32_t ref = T_REF_DEC(pNode);
uDebug("cache:%s, key:%p, %p released, refcnt:%d, data in trancan:%d", pCacheObj->name, key, p, ref, inTrashCan);
}
}
typedef struct SHashTravSupp {
SCacheObj* pCacheObj;
int64_t time;
__cache_free_fn_t fp;
} SHashTravSupp;
static bool travHashTableEmptyFn(void* param, void* data) {
SHashTravSupp* ps = (SHashTravSupp*) param;
SCacheObj* pCacheObj= ps->pCacheObj;
SCacheDataNode *pNode = *(SCacheDataNode **) data;
uDebug("cache:%s, key:%p, %p released, refcnt:%d, data in trancan:%d", pCacheObj->name, pNode->key, pNode->data, if (T_REF_VAL_GET(pNode) == 0) {
ref, inTrashCan); taosCacheReleaseNode(pCacheObj, pNode);
} else { // do add to trashcan
taosAddToTrash(pCacheObj, pNode);
} }
// this node should be remove from hash table
return false;
} }
void taosCacheEmpty(SCacheObj *pCacheObj) { void taosCacheEmpty(SCacheObj *pCacheObj) {
SHashMutableIterator *pIter = taosHashCreateIter(pCacheObj->pHashTable); SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = NULL, .time = taosGetTimestampMs()};
__cache_wr_lock(pCacheObj); taosHashCondTraverse(pCacheObj->pHashTable, travHashTableEmptyFn, &sup);
while (taosHashIterNext(pIter)) {
if (pCacheObj->deleting == 1) {
break;
}
SCacheDataNode *pNode = *(SCacheDataNode **) taosHashIterGet(pIter);
if (T_REF_VAL_GET(pNode) == 0) {
taosCacheReleaseNode(pCacheObj, pNode);
} else {
taosCacheMoveToTrash(pCacheObj, pNode);
}
}
__cache_unlock(pCacheObj);
taosHashDestroyIter(pIter);
taosTrashCanEmpty(pCacheObj, false); taosTrashCanEmpty(pCacheObj, false);
} }
...@@ -496,8 +452,7 @@ void taosCacheCleanup(SCacheObj *pCacheObj) { ...@@ -496,8 +452,7 @@ void taosCacheCleanup(SCacheObj *pCacheObj) {
doCleanupDataCache(pCacheObj); doCleanupDataCache(pCacheObj);
} }
SCacheDataNode *taosCreateCacheNode(const char *key, size_t keyLen, const char *pData, size_t size, SCacheDataNode *taosCreateCacheNode(const char *key, size_t keyLen, const char *pData, size_t size, uint64_t duration) {
uint64_t duration) {
size_t totalSize = size + sizeof(SCacheDataNode) + keyLen; size_t totalSize = size + sizeof(SCacheDataNode) + keyLen;
SCacheDataNode *pNewNode = calloc(1, totalSize); SCacheDataNode *pNewNode = calloc(1, totalSize);
...@@ -543,36 +498,10 @@ void taosAddToTrash(SCacheObj *pCacheObj, SCacheDataNode *pNode) { ...@@ -543,36 +498,10 @@ void taosAddToTrash(SCacheObj *pCacheObj, SCacheDataNode *pNode) {
pNode->pTNodeHeader = pElem; pNode->pTNodeHeader = pElem;
pCacheObj->numOfElemsInTrash++; pCacheObj->numOfElemsInTrash++;
uDebug("key:%p, %p move to trash, numOfElem in trash:%d", pNode->key, pNode->data, pCacheObj->numOfElemsInTrash); uDebug("%s key:%p, %p move to trash, numOfElem in trash:%d", pCacheObj->name, pNode->key, pNode->data,
pCacheObj->numOfElemsInTrash);
} }
void taosRemoveFromTrashCan(SCacheObj *pCacheObj, STrashElem *pElem) {
if (pElem->pData->signature != (uint64_t)pElem->pData) {
uError("key:sig:0x%" PRIx64 " %p data has been released, ignore", pElem->pData->signature, pElem->pData);
return;
}
pCacheObj->numOfElemsInTrash--;
if (pElem->prev) {
pElem->prev->next = pElem->next;
} else { /* pnode is the header, update header */
pCacheObj->pTrash = pElem->next;
}
if (pElem->next) {
pElem->next->prev = pElem->prev;
}
pElem->pData->signature = 0;
if (pCacheObj->freeFp) {
pCacheObj->freeFp(pElem->pData->data);
}
free(pElem->pData);
free(pElem);
}
// TODO add another lock when scanning trashcan
void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force) { void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force) {
__cache_wr_lock(pCacheObj); __cache_wr_lock(pCacheObj);
...@@ -580,8 +509,8 @@ void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force) { ...@@ -580,8 +509,8 @@ void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force) {
if (pCacheObj->pTrash != NULL) { if (pCacheObj->pTrash != NULL) {
uError("key:inconsistency data in cache, numOfElem in trash:%d", pCacheObj->numOfElemsInTrash); uError("key:inconsistency data in cache, numOfElem in trash:%d", pCacheObj->numOfElemsInTrash);
} }
pCacheObj->pTrash = NULL;
pCacheObj->pTrash = NULL;
__cache_unlock(pCacheObj); __cache_unlock(pCacheObj);
return; return;
} }
...@@ -597,10 +526,12 @@ void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force) { ...@@ -597,10 +526,12 @@ void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force) {
if (force || (T_REF_VAL_GET(pElem->pData) == 0)) { if (force || (T_REF_VAL_GET(pElem->pData) == 0)) {
uDebug("key:%p, %p removed from trash. numOfElem in trash:%d", pElem->pData->key, pElem->pData->data, uDebug("key:%p, %p removed from trash. numOfElem in trash:%d", pElem->pData->key, pElem->pData->data,
pCacheObj->numOfElemsInTrash - 1); pCacheObj->numOfElemsInTrash - 1);
STrashElem *p = pElem;
STrashElem *p = pElem;
pElem = pElem->next; pElem = pElem->next;
taosRemoveFromTrashCan(pCacheObj, p);
doRemoveElemInTrashcan(pCacheObj, p);
doDestroyTrashcanElem(pCacheObj, p);
} else { } else {
pElem = pElem->next; pElem = pElem->next;
} }
...@@ -610,27 +541,13 @@ void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force) { ...@@ -610,27 +541,13 @@ void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force) {
} }
void doCleanupDataCache(SCacheObj *pCacheObj) { void doCleanupDataCache(SCacheObj *pCacheObj) {
__cache_wr_lock(pCacheObj); SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = NULL, .time = taosGetTimestampMs()};
taosHashCondTraverse(pCacheObj->pHashTable, travHashTableEmptyFn, &sup);
SHashMutableIterator *pIter = taosHashCreateIter(pCacheObj->pHashTable);
while (taosHashIterNext(pIter)) {
SCacheDataNode *pNode = *(SCacheDataNode **)taosHashIterGet(pIter);
int32_t c = T_REF_VAL_GET(pNode);
if (c <= 0) {
taosCacheReleaseNode(pCacheObj, pNode);
} else {
uDebug("cache:%s key:%p, %p will not remove from cache, refcnt:%d", pCacheObj->name, pNode->key,
pNode->data, T_REF_VAL_GET(pNode));
}
}
taosHashDestroyIter(pIter);
// todo memory leak if there are object with refcount greater than 0 in hash table? // todo memory leak if there are object with refcount greater than 0 in hash table?
taosHashCleanup(pCacheObj->pHashTable); taosHashCleanup(pCacheObj->pHashTable);
__cache_unlock(pCacheObj);
taosTrashCanEmpty(pCacheObj, true); taosTrashCanEmpty(pCacheObj, true);
__cache_lock_destroy(pCacheObj); __cache_lock_destroy(pCacheObj);
taosTFree(pCacheObj->name); taosTFree(pCacheObj->name);
...@@ -638,26 +555,31 @@ void doCleanupDataCache(SCacheObj *pCacheObj) { ...@@ -638,26 +555,31 @@ void doCleanupDataCache(SCacheObj *pCacheObj) {
free(pCacheObj); free(pCacheObj);
} }
static void doCacheRefresh(SCacheObj* pCacheObj, int64_t time, __cache_free_fn_t fp) { bool travHashTableFn(void* param, void* data) {
SHashMutableIterator *pIter = taosHashCreateIter(pCacheObj->pHashTable); SHashTravSupp* ps = (SHashTravSupp*) param;
SCacheObj* pCacheObj= ps->pCacheObj;
__cache_wr_lock(pCacheObj); SCacheDataNode* pNode = *(SCacheDataNode **) data;
while (taosHashIterNext(pIter)) { if (pNode->expireTime < ps->time && T_REF_VAL_GET(pNode) <= 0) {
SCacheDataNode *pNode = *(SCacheDataNode **)taosHashIterGet(pIter); taosCacheReleaseNode(pCacheObj, pNode);
if (pNode->expireTime < (uint64_t)time && T_REF_VAL_GET(pNode) <= 0) { // this node should be remove from hash table
taosCacheReleaseNode(pCacheObj, pNode); return false;
continue; }
}
if (fp) { if (ps->fp) {
fp(pNode->data); (ps->fp)(pNode->data);
}
} }
__cache_unlock(pCacheObj); // do not remove element in hash table
return true;
}
static void doCacheRefresh(SCacheObj* pCacheObj, int64_t time, __cache_free_fn_t fp) {
assert(pCacheObj != NULL);
taosHashDestroyIter(pIter); SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = fp, .time = time};
taosHashCondTraverse(pCacheObj->pHashTable, travHashTableFn, &sup);
} }
void* taosCacheTimedRefresh(void *handle) { void* taosCacheTimedRefresh(void *handle) {
......
...@@ -433,7 +433,7 @@ static SKVStore *tdNewKVStore(char *fname, iterFunc iFunc, afterFunc aFunc, void ...@@ -433,7 +433,7 @@ static SKVStore *tdNewKVStore(char *fname, iterFunc iFunc, afterFunc aFunc, void
pStore->iFunc = iFunc; pStore->iFunc = iFunc;
pStore->aFunc = aFunc; pStore->aFunc = aFunc;
pStore->appH = appH; pStore->appH = appH;
pStore->map = taosHashInit(4096, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false); pStore->map = taosHashInit(4096, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false);
if (pStore->map == NULL) { if (pStore->map == NULL) {
terrno = TSDB_CODE_COM_OUT_OF_MEMORY; terrno = TSDB_CODE_COM_OUT_OF_MEMORY;
goto _err; goto _err;
......
...@@ -10,6 +10,6 @@ IF (HEADER_GTEST_INCLUDE_DIR AND LIB_GTEST_STATIC_DIR) ...@@ -10,6 +10,6 @@ IF (HEADER_GTEST_INCLUDE_DIR AND LIB_GTEST_STATIC_DIR)
INCLUDE_DIRECTORIES(${HEADER_GTEST_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${HEADER_GTEST_INCLUDE_DIR})
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
ADD_EXECUTABLE(utilTest ${SOURCE_LIST}) ADD_EXECUTABLE(utilTest ./cacheTest.cpp ./hashTest.cpp)
TARGET_LINK_LIBRARIES(utilTest tutil common osdetail gtest pthread gcov) TARGET_LINK_LIBRARIES(utilTest tutil common osdetail gtest pthread gcov)
ENDIF() ENDIF()
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
namespace { namespace {
// the simple test code for basic operations // the simple test code for basic operations
void simpleTest() { void simpleTest() {
auto* hashTable = (SHashObj*) taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false); SHashObj* hashTable = (SHashObj*) taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
ASSERT_EQ(taosHashGetSize(hashTable), 0); ASSERT_EQ(taosHashGetSize(hashTable), 0);
// put 400 elements in the hash table // put 400 elements in the hash table
...@@ -47,7 +47,7 @@ void simpleTest() { ...@@ -47,7 +47,7 @@ void simpleTest() {
} }
void stringKeyTest() { void stringKeyTest() {
auto* hashTable = (SHashObj*) taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false); auto* hashTable = (SHashObj*) taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
ASSERT_EQ(taosHashGetSize(hashTable), 0); ASSERT_EQ(taosHashGetSize(hashTable), 0);
char key[128] = {0}; char key[128] = {0};
...@@ -97,7 +97,7 @@ void functionTest() { ...@@ -97,7 +97,7 @@ void functionTest() {
* a single threads situation * a single threads situation
*/ */
void noLockPerformanceTest() { void noLockPerformanceTest() {
auto* hashTable = (SHashObj*) taosHashInit(4096, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false); auto* hashTable = (SHashObj*) taosHashInit(4096, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
ASSERT_EQ(taosHashGetSize(hashTable), 0); ASSERT_EQ(taosHashGetSize(hashTable), 0);
char key[128] = {0}; char key[128] = {0};
......
...@@ -50,7 +50,7 @@ int32_t vnodeInitResources() { ...@@ -50,7 +50,7 @@ int32_t vnodeInitResources() {
vnodeInitWriteFp(); vnodeInitWriteFp();
vnodeInitReadFp(); vnodeInitReadFp();
tsDnodeVnodesHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true); tsDnodeVnodesHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, true);
if (tsDnodeVnodesHash == NULL) { if (tsDnodeVnodesHash == NULL) {
vError("failed to init vnode list"); vError("failed to init vnode list");
return TSDB_CODE_VND_OUT_OF_MEMORY; return TSDB_CODE_VND_OUT_OF_MEMORY;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
*/ */
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#include <dnode.h> //#include <dnode.h>
#include "os.h" #include "os.h"
#include "tglobal.h" #include "tglobal.h"
...@@ -66,7 +66,7 @@ int32_t vnodeProcessRead(void *param, SReadMsg *pReadMsg) { ...@@ -66,7 +66,7 @@ int32_t vnodeProcessRead(void *param, SReadMsg *pReadMsg) {
return (*vnodeProcessReadMsgFp[msgType])(pVnode, pReadMsg); return (*vnodeProcessReadMsgFp[msgType])(pVnode, pReadMsg);
} }
static void vnodePutItemIntoReadQueue(SVnodeObj *pVnode, void *qhandle) { static void vnodePutItemIntoReadQueue(SVnodeObj *pVnode, void **qhandle) {
SReadMsg *pRead = (SReadMsg *)taosAllocateQitem(sizeof(SReadMsg)); SReadMsg *pRead = (SReadMsg *)taosAllocateQitem(sizeof(SReadMsg));
pRead->rpcMsg.msgType = TSDB_MSG_TYPE_QUERY; pRead->rpcMsg.msgType = TSDB_MSG_TYPE_QUERY;
pRead->pCont = qhandle; pRead->pCont = qhandle;
...@@ -74,22 +74,23 @@ static void vnodePutItemIntoReadQueue(SVnodeObj *pVnode, void *qhandle) { ...@@ -74,22 +74,23 @@ static void vnodePutItemIntoReadQueue(SVnodeObj *pVnode, void *qhandle) {
pRead->rpcMsg.handle = NULL; pRead->rpcMsg.handle = NULL;
atomic_add_fetch_32(&pVnode->refCount, 1); atomic_add_fetch_32(&pVnode->refCount, 1);
vDebug("QInfo:%p add to vread queue for exec query, msg:%p", *qhandle, pRead);
taosWriteQitem(pVnode->rqueue, TAOS_QTYPE_QUERY, pRead); taosWriteQitem(pVnode->rqueue, TAOS_QTYPE_QUERY, pRead);
} }
static int32_t vnodeDumpQueryResult(SRspRet *pRet, void* pVnode, void* handle, bool* freeHandle) { static int32_t vnodeDumpQueryResult(SRspRet *pRet, void* pVnode, void** handle, bool* freeHandle) {
bool continueExec = false; bool continueExec = false;
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
if ((code = qDumpRetrieveResult(handle, (SRetrieveTableRsp **)&pRet->rsp, &pRet->len, &continueExec)) == TSDB_CODE_SUCCESS) { if ((code = qDumpRetrieveResult(*handle, (SRetrieveTableRsp **)&pRet->rsp, &pRet->len, &continueExec)) == TSDB_CODE_SUCCESS) {
if (continueExec) { if (continueExec) {
vDebug("QInfo:%p add to query task queue for exec", handle);
vnodePutItemIntoReadQueue(pVnode, handle);
pRet->qhandle = handle;
*freeHandle = false; *freeHandle = false;
vnodePutItemIntoReadQueue(pVnode, handle);
pRet->qhandle = *handle;
} else { } else {
vDebug("QInfo:%p exec completed", handle);
*freeHandle = true; *freeHandle = true;
vDebug("QInfo:%p exec completed, free handle:%d", *handle, *freeHandle);
} }
} else { } else {
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp)); pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
...@@ -158,7 +159,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) { ...@@ -158,7 +159,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
// current connect is broken // current connect is broken
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
handle = qRegisterQInfo(pVnode->qMgmt, (uint64_t) pQInfo); handle = qRegisterQInfo(pVnode->qMgmt, (uint64_t) pQInfo);
if (handle == NULL) { // failed to register qhandle if (handle == NULL) { // failed to register qhandle, todo add error test case
vError("vgId:%d QInfo:%p register qhandle failed, return to app, code:%s", pVnode->vgId, (void *)pQInfo, vError("vgId:%d QInfo:%p register qhandle failed, return to app, code:%s", pVnode->vgId, (void *)pQInfo,
tstrerror(pRsp->code)); tstrerror(pRsp->code));
pRsp->code = TSDB_CODE_QRY_INVALID_QHANDLE; pRsp->code = TSDB_CODE_QRY_INVALID_QHANDLE;
...@@ -179,41 +180,40 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) { ...@@ -179,41 +180,40 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
} }
if (handle != NULL) { if (handle != NULL) {
vDebug("vgId:%d, QInfo:%p, dnode query msg disposed, register qhandle and return to app", vgId, *handle); vDebug("vgId:%d, QInfo:%p, dnode query msg disposed, create qhandle and returns to app", vgId, *handle);
vnodePutItemIntoReadQueue(pVnode, handle);
vnodePutItemIntoReadQueue(pVnode, *handle);
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, false);
} }
} else { } else {
assert(pCont != NULL); assert(pCont != NULL);
void** qhandle = (void**) pCont;
handle = qAcquireQInfo(pVnode->qMgmt, (uint64_t) pCont); vDebug("vgId:%d, QInfo:%p, dnode continues to exec query", pVnode->vgId, *qhandle);
if (handle == NULL) {
vWarn("QInfo:%p invalid qhandle in continuing exec query, conn:%p", (void*) pCont, pReadMsg->rpcMsg.handle);
code = TSDB_CODE_QRY_INVALID_QHANDLE;
} else {
vDebug("vgId:%d, QInfo:%p, dnode continue exec query", pVnode->vgId, (void*) pCont);
bool freehandle = false; bool freehandle = false;
bool buildRes = qTableQuery(*handle); // do execute query bool buildRes = qTableQuery(*qhandle); // do execute query
// build query rsp // build query rsp, the retrieve request has reached here already
if (buildRes) { if (buildRes) {
// update the connection info according to the retrieve connection // update the connection info according to the retrieve connection
pReadMsg->rpcMsg.handle = qGetResultRetrieveMsg(*handle); pReadMsg->rpcMsg.handle = qGetResultRetrieveMsg(*qhandle);
assert(pReadMsg->rpcMsg.handle != NULL); assert(pReadMsg->rpcMsg.handle != NULL);
vDebug("vgId:%d, QInfo:%p, start to build result rsp after query paused, %p", pVnode->vgId, *handle, pReadMsg->rpcMsg.handle); vDebug("vgId:%d, QInfo:%p, start to build retrieval rsp after query paused, %p", pVnode->vgId, *qhandle,
code = vnodeDumpQueryResult(&pReadMsg->rspRet, pVnode, *handle, &freehandle); pReadMsg->rpcMsg.handle);
code = vnodeDumpQueryResult(&pReadMsg->rspRet, pVnode, qhandle, &freehandle);
// todo test the error code case // todo test the error code case
if (code == TSDB_CODE_SUCCESS) { if (code == TSDB_CODE_SUCCESS) {
code = TSDB_CODE_QRY_HAS_RSP; code = TSDB_CODE_QRY_HAS_RSP;
}
} }
} else {
freehandle = qQueryCompleted(*qhandle);
}
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, freehandle); // NOTE: if the qhandle is not put into vread queue or query is completed, free the qhandle.
// if not build result, free it not by forced.
if (freehandle || (!buildRes)) {
qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, freehandle);
} }
} }
...@@ -225,8 +225,8 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) { ...@@ -225,8 +225,8 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
SRspRet *pRet = &pReadMsg->rspRet; SRspRet *pRet = &pReadMsg->rspRet;
SRetrieveTableMsg *pRetrieve = pCont; SRetrieveTableMsg *pRetrieve = pCont;
pRetrieve->qhandle = htobe64(pRetrieve->qhandle);
pRetrieve->free = htons(pRetrieve->free); pRetrieve->free = htons(pRetrieve->free);
pRetrieve->qhandle = htobe64(pRetrieve->qhandle);
vDebug("vgId:%d, QInfo:%p, retrieve msg is disposed, free:%d, conn:%p", pVnode->vgId, (void*) pRetrieve->qhandle, pRetrieve->free, pReadMsg->rpcMsg.handle); vDebug("vgId:%d, QInfo:%p, retrieve msg is disposed, free:%d, conn:%p", pVnode->vgId, (void*) pRetrieve->qhandle, pRetrieve->free, pReadMsg->rpcMsg.handle);
...@@ -236,18 +236,27 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) { ...@@ -236,18 +236,27 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
void** handle = qAcquireQInfo(pVnode->qMgmt, pRetrieve->qhandle); void** handle = qAcquireQInfo(pVnode->qMgmt, pRetrieve->qhandle);
if (handle == NULL || (*handle) != (void*) pRetrieve->qhandle) { if (handle == NULL || (*handle) != (void*) pRetrieve->qhandle) {
code = TSDB_CODE_QRY_INVALID_QHANDLE; code = TSDB_CODE_QRY_INVALID_QHANDLE;
vDebug("vgId:%d, invalid qhandle in fetch result, QInfo:%p", pVnode->vgId, (void*) pRetrieve->qhandle); vDebug("vgId:%d, invalid qhandle in retrieving result, QInfo:%p", pVnode->vgId, (void*) pRetrieve->qhandle);
vnodeBuildNoResultQueryRsp(pRet); vnodeBuildNoResultQueryRsp(pRet);
return code; return code;
} }
if (pRetrieve->free == 1) { if (pRetrieve->free == 1) {
vDebug("vgId:%d, QInfo:%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, *handle); vWarn("vgId:%d, QInfo:%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, *handle);
qKillQuery(*handle); qKillQuery(*handle);
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true); qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
vnodeBuildNoResultQueryRsp(pRet); vnodeBuildNoResultQueryRsp(pRet);
code = TSDB_CODE_TSC_QUERY_CANCELLED;
return code;
}
// register the qhandle to connect to quit query immediate if connection is broken
if (vnodeNotifyCurrentQhandle(pReadMsg->rpcMsg.handle, *handle, pVnode->vgId) != TSDB_CODE_SUCCESS) {
vError("vgId:%d, QInfo:%p, retrieve discarded since link is broken, %p", pVnode->vgId, *handle, pReadMsg->rpcMsg.handle);
code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
return code; return code;
} }
...@@ -259,16 +268,22 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) { ...@@ -259,16 +268,22 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
//TODO handle malloc failure //TODO handle malloc failure
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp)); pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp)); memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp));
freeHandle = true;
} else { // result is not ready, return immediately } else { // result is not ready, return immediately
if (!buildRes) { if (!buildRes) {
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, false); qReleaseQInfo(pVnode->qMgmt, (void**) &handle, false);
return TSDB_CODE_QRY_NOT_READY; return TSDB_CODE_QRY_NOT_READY;
} }
code = vnodeDumpQueryResult(pRet, pVnode, *handle, &freeHandle); code = vnodeDumpQueryResult(pRet, pVnode, handle, &freeHandle);
}
// If qhandle is not added into vread queue, the query should be completed already or paused with error.
// Here free qhandle immediately
if (freeHandle) {
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
} }
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, freeHandle);
return code; return code;
} }
......
...@@ -257,6 +257,21 @@ if $data01 != $val then ...@@ -257,6 +257,21 @@ if $data01 != $val then
return -1 return -1
endi endi
sql select count(join_tb1.*) + count(join_tb0.*) from join_tb1 , join_tb0 where join_tb1.ts = join_tb0.ts and join_tb1.ts >= 100000 and join_tb0.c7 = false;;
if $rows != 1 then
return -1
endi
if $data00 != 20.000000000 then
print expect 20.000000000 actual $data00
return -1
endi
sql select count(join_tb1.*)/10 from join_tb1 , join_tb0 where join_tb1.ts = join_tb0.ts and join_tb1.ts >= 100000 and join_tb0.c7 = false;;
if $data00 != 1.000000000 then
return -1
endi
print 3 print 3
#agg + where condition #agg + where condition
sql select count(join_tb1.c3), count(join_tb0.ts) from $tb1 , $tb2 where $ts1 = $ts2 and join_tb1.ts <= 100002 and join_tb0.c7 = true; sql select count(join_tb1.c3), count(join_tb0.ts) from $tb1 , $tb2 where $ts1 = $ts2 and join_tb1.ts <= 100002 and join_tb0.c7 = true;
...@@ -381,6 +396,15 @@ if $data00 != $val then ...@@ -381,6 +396,15 @@ if $data00 != $val then
return -1 return -1
endi endi
sql select sum(join_mt0.c1)+sum(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.ts = join_mt1.ts and join_mt0.t1=join_mt1.t1 and join_mt0.c2=99 and join_mt1.ts=100999;
if $rows != 1 then
return -1
endi
if $data00 != 396.000000000 then
return -1
endi
# first/last # first/last
sql select count(join_mt0.c1), sum(join_mt1.c2), first(join_mt0.c5), last(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts and join_mt0.t1=1 interval(10a) order by join_mt0.ts asc; sql select count(join_mt0.c1), sum(join_mt1.c2), first(join_mt0.c5), last(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts and join_mt0.t1=1 interval(10a) order by join_mt0.ts asc;
......
system sh/stop_dnodes.sh system sh/stop_dnodes.sh
system sh/deploy.sh -n dnode1 -i 1 system sh/deploy.sh -n dnode1 -i 1
system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c walLevel -v 1
system sh/cfg.sh -n dnode1 -c debugFlag -v 135 system sh/cfg.sh -n dnode1 -c debugFlag -v 135
system sh/cfg.sh -n dnode1 -c rpcDebugFlag -v 135 system sh/cfg.sh -n dnode1 -c rpcDebugFlag -v 135
system sh/exec.sh -n dnode1 -s start system sh/exec.sh -n dnode1 -s start
...@@ -28,7 +28,7 @@ $mt = $mtPrefix . $i ...@@ -28,7 +28,7 @@ $mt = $mtPrefix . $i
sql drop database if exits $db -x step1 sql drop database if exits $db -x step1
step1: step1:
sql create database if not exists $db tables 4 keep 36500 sql create database if not exists $db maxtables 4 keep 36500
sql use $db sql use $db
sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12)) sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12))
......
sleep 2000 #sleep 2000
run general/parser/alter.sim #run general/parser/alter.sim
sleep 2000 #sleep 2000
run general/parser/alter1.sim #run general/parser/alter1.sim
sleep 2000 #sleep 2000
run general/parser/alter_stable.sim #run general/parser/alter_stable.sim
sleep 2000 #sleep 2000
run general/parser/auto_create_tb.sim #run general/parser/auto_create_tb.sim
sleep 2000 #sleep 2000
run general/parser/auto_create_tb_drop_tb.sim #run general/parser/auto_create_tb_drop_tb.sim
sleep 2000 #sleep 2000
run general/parser/col_arithmetic_operation.sim #run general/parser/col_arithmetic_operation.sim
sleep 2000 #sleep 2000
run general/parser/columnValue.sim #run general/parser/columnValue.sim
sleep 2000 #sleep 2000
run general/parser/commit.sim #run general/parser/commit.sim
sleep 2000 #sleep 2000
run general/parser/create_db.sim #run general/parser/create_db.sim
sleep 2000 #sleep 2000
run general/parser/create_mt.sim #run general/parser/create_mt.sim
sleep 2000 #sleep 2000
run general/parser/create_tb.sim #run general/parser/create_tb.sim
sleep 2000 #sleep 2000
run general/parser/dbtbnameValidate.sim #run general/parser/dbtbnameValidate.sim
sleep 2000 sleep 2000
run general/parser/fill.sim run general/parser/fill.sim
sleep 2000 sleep 2000
......
...@@ -66,9 +66,56 @@ if $row != 100 then ...@@ -66,9 +66,56 @@ if $row != 100 then
return -1 return -1
endi endi
sql select last(c2) from tb_tb9 sql select bottom(c1, 100) from tb_stb0
if $row != 100 then
return -1
endi
sql select last(*) from tb_tb9
if $row != 1 then if $row != 1 then
return -1 return -1
endi endi
sql select last(c2) from tb_tb9
if $row != 0 then
return -1
endi
sql select first(c2), last(c2) from tb_tb9
if $row != 0 then
return -1
endi
sql create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double, col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20));
sql create table test1 using test tags('beijing');
sql insert into test1 values(1537146000000, 1, 1, 1, 1, 0.100000, 0.100000, 0, 'taosdata1', '涛思数据1');
sql insert into test1 values(1537146000001, 2, 2, 2, 2, 1.100000, 1.100000, 1, 'taosdata2', '涛思数据2');
sql insert into test1 values(1537146000002, 3, 3, 3, 3, 2.100000, 2.100000, 0, 'taosdata3', '涛思数据3');
sql insert into test1 values(1537146000003, 4, 4, 4, 4, 3.100000, 3.100000, 1, 'taosdata4', '涛思数据4');
sql insert into test1 values(1537146000004, 5, 5, 5, 5, 4.100000, 4.100000, 0, 'taosdata5', '涛思数据5');
sql insert into test1 values(1537146000005, 6, 6, 6, 6, 5.100000, 5.100000, 1, 'taosdata6', '涛思数据6');
sql insert into test1 values(1537146000006, 7, 7, 7, 7, 6.100000, 6.100000, 0, 'taosdata7', '涛思数据7');
sql insert into test1 values(1537146000007, 8, 8, 8, 8, 7.100000, 7.100000, 1, 'taosdata8', '涛思数据8');
sql insert into test1 values(1537146000008, 9, 9, 9, 9, 8.100000, 8.100000, 0, 'taosdata9', '涛思数据9');
sql insert into test1 values(1537146000009, 10, 10, 10, 10, 9.100000, 9.100000, 1, 'taosdata10', '涛思数据10');
sql select bottom(col5, 10) from test
if $rows != 10 then
return -1
endi
if $data01 != 0.10000 then
print expect 0.10000 actual: $data01
return -1
endi
if $data11 != 1.10000 then
print expect 1.10000 actual: $data11
return -1
endi
if $data21 != 2.10000 then
print expect 2.10000 actual: $data21
return -1
endi
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
#system sh/stop_dnodes.sh system sh/stop_dnodes.sh
#
#system sh/deploy.sh -n dnode1 -i 1 system sh/deploy.sh -n dnode1 -i 1
#system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c walLevel -v 0
#system sh/cfg.sh -n dnode1 -c debugFlag -v 135 system sh/cfg.sh -n dnode1 -c debugFlag -v 135
#system sh/cfg.sh -n dnode1 -c rpcDebugFlag -v 135 system sh/cfg.sh -n dnode1 -c rpcDebugFlag -v 135
#system sh/exec.sh -n dnode1 -s start system sh/exec.sh -n dnode1 -s start
sleep 1000 sleep 1000
sql connect sql connect
...@@ -24,77 +24,77 @@ $mt = $mtPrefix . $i ...@@ -24,77 +24,77 @@ $mt = $mtPrefix . $i
$j = 1 $j = 1
$mt1 = $mtPrefix . $j $mt1 = $mtPrefix . $j
#
#sql drop database if exits $db -x step1 sql drop database if exits $db -x step1
#step1: step1:
#sql create database if not exists $db maxtables 4 sql create database if not exists $db maxtables 4
sql use $db sql use $db
#sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int) sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int)
#
#$i = 0 $i = 0
#$t = 1578203484000 $t = 1578203484000
#
#while $i < $tbNum while $i < $tbNum
# $tb = $tbPrefix . $i $tb = $tbPrefix . $i
# sql create table $tb using $mt tags( $i ) sql create table $tb using $mt tags( $i )
#
# $x = 0 $x = 0
# while $x < $rowNum while $x < $rowNum
# $ms = $x * 1000 $ms = $x * 1000
# $ms = $ms * 60 $ms = $ms * 60
#
# $c = $x / 100 $c = $x / 100
# $c = $c * 100 $c = $c * 100
# $c = $x - $c $c = $x - $c
# $binary = 'binary . $c $binary = 'binary . $c
# $binary = $binary . ' $binary = $binary . '
# $nchar = 'nchar . $c $nchar = 'nchar . $c
# $nchar = $nchar . ' $nchar = $nchar . '
#
# $t1 = $t + $ms $t1 = $t + $ms
# sql insert into $tb values ($t1 , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) sql insert into $tb values ($t1 , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar )
# $x = $x + 1 $x = $x + 1
# endw endw
#
# $i = $i + 1 $i = $i + 1
#endw endw
#
#sql create table $mt1 (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int) sql create table $mt1 (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int)
#
#$j = 0 $j = 0
#$t = 1578203484000 $t = 1578203484000
#$rowNum = 1000 $rowNum = 1000
#$tbNum = 5 $tbNum = 5
#$i = 0 $i = 0
#
#while $i < $tbNum while $i < $tbNum
# $tb1 = $tbPrefix1 . $j $tb1 = $tbPrefix1 . $j
# sql create table $tb1 using $mt1 tags( $i ) sql create table $tb1 using $mt1 tags( $i )
#
# $x = 0 $x = 0
# while $x < $rowNum while $x < $rowNum
# $ms = $x * 1000 $ms = $x * 1000
# $ms = $ms * 60 $ms = $ms * 60
#
# $c = $x / 100 $c = $x / 100
# $c = $c * 100 $c = $c * 100
# $c = $x - $c $c = $x - $c
# $binary = 'binary . $c $binary = 'binary . $c
# $binary = $binary . ' $binary = $binary . '
# $nchar = 'nchar . $c $nchar = 'nchar . $c
# $nchar = $nchar . ' $nchar = $nchar . '
#
# $t1 = $t + $ms $t1 = $t + $ms
# sql insert into $tb1 values ($t1 , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) sql insert into $tb1 values ($t1 , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar )
# $x = $x + 1 $x = $x + 1
# endw endw
#
# $i = $i + 1 $i = $i + 1
# $j = $j + 1 $j = $j + 1
#endw endw
#
#print sleep 1sec. print sleep 1sec.
#sleep 1000 sleep 1000
$i = 1 $i = 1
$tb = $tbPrefix . $i $tb = $tbPrefix . $i
...@@ -412,4 +412,8 @@ if $data10 != @union_db0@ then ...@@ -412,4 +412,8 @@ if $data10 != @union_db0@ then
return -1 return -1
endi endi
sql_error show tables union all show tables
sql_error show stables union all show stables
sql_error show databases union all show databases
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册