Merge branch 'develop' into xiaoping/add_test_case
This commit is contained in:
commit
aa9092ded4
|
@ -237,21 +237,21 @@ static bool bnCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) {
|
||||||
bool isReady = false;
|
bool isReady = false;
|
||||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||||
SVnodeGid *pVnode = pVgroup->vnodeGid + i;
|
SVnodeGid *pVnode = pVgroup->vnodeGid + i;
|
||||||
|
SDnodeObj *pDnode = pVnode->pDnode;
|
||||||
if (pVnode == pRmVnode) continue;
|
if (pVnode == pRmVnode) continue;
|
||||||
int32_t vver = mnodeGetVgidVer(pVnode->vver);
|
int32_t vver = mnodeGetVgidVer(pVnode->vver);
|
||||||
|
|
||||||
mTrace("vgId:%d, check vgroup status, vindex:%d dnode:%d status:%s role:%s vver:%d, rmvver:%d" , pVgroup->vgId, i,
|
mTrace("vgId:%d, check vgroup status, vindex:%d dnode:%d status:%s role:%s vver:%d, rmvver:%d", pVgroup->vgId, i,
|
||||||
pVnode->dnodeId, dnodeStatus[pVnode->pDnode->status], syncRole[pVnode->role], vver, rmVnodeVer);
|
pVnode->dnodeId, dnodeStatus[pDnode->status], syncRole[pVnode->role], vver, rmVnodeVer);
|
||||||
if (pVnode->pDnode->status == TAOS_DN_STATUS_DROPPING) continue;
|
if (pDnode->status == TAOS_DN_STATUS_DROPPING) continue;
|
||||||
if (pVnode->pDnode->status == TAOS_DN_STATUS_OFFLINE) continue;
|
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) continue;
|
||||||
if (pVnode->role != TAOS_SYNC_ROLE_SLAVE && pVnode->role != TAOS_SYNC_ROLE_MASTER) continue;
|
if (pVnode->role != TAOS_SYNC_ROLE_SLAVE && pVnode->role != TAOS_SYNC_ROLE_MASTER) continue;
|
||||||
|
|
||||||
if (rmVnodeVer == 0 || vver >= rmVnodeVer) {
|
if (rmVnodeVer == 0 || vver >= rmVnodeVer) {
|
||||||
mInfo("vgId:%d, is ready for vindex:%d in dnode:%d status:%s role:%s vver:%d larger than rmvver:%d", pVgroup->vgId, i,
|
mInfo("vgId:%d, is ready for vindex:%d in dnode:%d status:%s role:%s vver:%d larger than rmvver:%d",
|
||||||
pVnode->dnodeId, dnodeStatus[pVnode->pDnode->status], syncRole[pVnode->role], vver, rmVnodeVer);
|
pVgroup->vgId, i, pVnode->dnodeId, dnodeStatus[pDnode->status], syncRole[pVnode->role], vver, rmVnodeVer);
|
||||||
|
isReady = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
isReady = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return isReady;
|
return isReady;
|
||||||
|
|
|
@ -20,9 +20,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* @date 2018/09/30
|
|
||||||
*/
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "qExtbuffer.h"
|
#include "qExtbuffer.h"
|
||||||
|
@ -216,7 +213,7 @@ STableMetaInfo* tscGetMetaInfo(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
||||||
SQueryInfo *tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex);
|
SQueryInfo *tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex);
|
||||||
SQueryInfo *tscGetQueryInfoDetailSafely(SSqlCmd *pCmd, int32_t subClauseIndex);
|
SQueryInfo *tscGetQueryInfoDetailSafely(SSqlCmd *pCmd, int32_t subClauseIndex);
|
||||||
|
|
||||||
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache);
|
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo);
|
||||||
|
|
||||||
STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pTableMeta,
|
STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pTableMeta,
|
||||||
SVgroupsInfo* vgroupList, SArray* pTagCols, SArray* pVgroupTables);
|
SVgroupsInfo* vgroupList, SArray* pTagCols, SArray* pVgroupTables);
|
||||||
|
@ -276,7 +273,7 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex);
|
||||||
bool hasMoreVnodesToTry(SSqlObj *pSql);
|
bool hasMoreVnodesToTry(SSqlObj *pSql);
|
||||||
bool hasMoreClauseToTry(SSqlObj* pSql);
|
bool hasMoreClauseToTry(SSqlObj* pSql);
|
||||||
|
|
||||||
void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeFromCache);
|
void tscFreeQueryInfo(SSqlCmd* pCmd);
|
||||||
|
|
||||||
void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp);
|
void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp);
|
||||||
void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
||||||
|
@ -290,6 +287,14 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
||||||
char* serializeTagData(STagData* pTagData, char* pMsg);
|
char* serializeTagData(STagData* pTagData, char* pMsg);
|
||||||
int32_t copyTagData(STagData* dst, const STagData* src);
|
int32_t copyTagData(STagData* dst, const STagData* src);
|
||||||
|
|
||||||
|
STableMeta* createSuperTableMeta(STableMetaMsg* pChild);
|
||||||
|
uint32_t tscGetTableMetaSize(STableMeta* pTableMeta);
|
||||||
|
CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta);
|
||||||
|
uint32_t tscGetTableMetaMaxSize();
|
||||||
|
int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name);
|
||||||
|
STableMeta* tscTableMetaClone(STableMeta* pTableMeta);
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -105,7 +105,10 @@ SSchema tscGetTbnameColumnSchema();
|
||||||
* @param size size of the table meta
|
* @param size size of the table meta
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size);
|
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg);
|
||||||
|
|
||||||
|
bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src);
|
||||||
|
SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,23 +56,28 @@ typedef struct STableComInfo {
|
||||||
int32_t rowSize;
|
int32_t rowSize;
|
||||||
} STableComInfo;
|
} STableComInfo;
|
||||||
|
|
||||||
typedef struct SCorVgroupInfo {
|
typedef struct SNewVgroupInfo {
|
||||||
int32_t version;
|
int32_t vgId;
|
||||||
int8_t inUse;
|
int8_t inUse;
|
||||||
int8_t numOfEps;
|
int8_t numOfEps;
|
||||||
SEpAddr1 epAddr[TSDB_MAX_REPLICA];
|
SEpAddrMsg ep[TSDB_MAX_REPLICA];
|
||||||
} SCorVgroupInfo;
|
} SNewVgroupInfo;
|
||||||
|
|
||||||
|
typedef struct CChildTableMeta {
|
||||||
|
int32_t vgId;
|
||||||
|
STableId id;
|
||||||
|
uint8_t tableType;
|
||||||
|
char sTableName[TSDB_TABLE_FNAME_LEN];
|
||||||
|
} CChildTableMeta;
|
||||||
|
|
||||||
typedef struct STableMeta {
|
typedef struct STableMeta {
|
||||||
STableComInfo tableInfo;
|
int32_t vgId;
|
||||||
|
STableId id;
|
||||||
uint8_t tableType;
|
uint8_t tableType;
|
||||||
|
char sTableName[TSDB_TABLE_FNAME_LEN];
|
||||||
int16_t sversion;
|
int16_t sversion;
|
||||||
int16_t tversion;
|
int16_t tversion;
|
||||||
char sTableId[TSDB_TABLE_FNAME_LEN];
|
STableComInfo tableInfo;
|
||||||
int32_t vgId;
|
|
||||||
SCorVgroupInfo corVgroupInfo;
|
|
||||||
STableId id;
|
|
||||||
// union {int64_t stableUid; SSchema* schema;};
|
|
||||||
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
|
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
|
||||||
} STableMeta;
|
} STableMeta;
|
||||||
|
|
||||||
|
@ -171,7 +176,7 @@ typedef struct SParamInfo {
|
||||||
} SParamInfo;
|
} SParamInfo;
|
||||||
|
|
||||||
typedef struct STableDataBlocks {
|
typedef struct STableDataBlocks {
|
||||||
char tableId[TSDB_TABLE_FNAME_LEN];
|
char tableName[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
|
||||||
|
@ -249,7 +254,7 @@ typedef struct {
|
||||||
int8_t submitSchema; // submit block is built with table schema
|
int8_t submitSchema; // submit block is built with table schema
|
||||||
STagData tagData; // NOTE: pTagData->data is used as a variant length array
|
STagData tagData; // NOTE: pTagData->data is used as a variant length array
|
||||||
|
|
||||||
STableMeta **pTableMetaList; // all involved tableMeta list of current insert sql statement.
|
char **pTableNameList; // all involved tableMeta list of current insert sql statement.
|
||||||
int32_t numOfTables;
|
int32_t numOfTables;
|
||||||
|
|
||||||
SHashObj *pTableBlockHashList; // data block for each table
|
SHashObj *pTableBlockHashList; // data block for each table
|
||||||
|
@ -386,7 +391,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet);
|
||||||
int tscProcessSql(SSqlObj *pSql);
|
int tscProcessSql(SSqlObj *pSql);
|
||||||
|
|
||||||
int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex);
|
int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex);
|
||||||
void tscQueueAsyncRes(SSqlObj *pSql);
|
void tscAsyncResultOnError(SSqlObj *pSql);
|
||||||
|
|
||||||
void tscQueueAsyncError(void(*fp), void *param, int32_t code);
|
void tscQueueAsyncError(void(*fp), void *param, int32_t code);
|
||||||
|
|
||||||
|
@ -400,7 +405,7 @@ void tscRestoreSQLFuncForSTableQuery(SQueryInfo *pQueryInfo);
|
||||||
int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
|
int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
|
||||||
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
void tscResetSqlCmdObj(SSqlCmd *pCmd, bool removeFromCache);
|
void tscResetSqlCmdObj(SSqlCmd *pCmd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* free query result of the sql object
|
* free query result of the sql object
|
||||||
|
@ -414,7 +419,6 @@ void tscFreeSqlResult(SSqlObj *pSql);
|
||||||
*/
|
*/
|
||||||
void tscFreeSqlObj(SSqlObj *pSql);
|
void tscFreeSqlObj(SSqlObj *pSql);
|
||||||
void tscFreeRegisteredSqlObj(void *pSql);
|
void tscFreeRegisteredSqlObj(void *pSql);
|
||||||
void tscFreeTableMetaHelper(void *pTableMeta);
|
|
||||||
|
|
||||||
void tscCloseTscObj(void *pObj);
|
void tscCloseTscObj(void *pObj);
|
||||||
|
|
||||||
|
@ -479,7 +483,9 @@ static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pField
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern SCacheObj *tscMetaCache;
|
extern int32_t sentinel;
|
||||||
|
extern SHashObj *tscVgroupMap;
|
||||||
|
extern SHashObj *tscTableMetaInfo;
|
||||||
|
|
||||||
extern int tscObjRef;
|
extern int tscObjRef;
|
||||||
extern void *tscTmr;
|
extern void *tscTmr;
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#include "tnote.h"
|
#include "tnote.h"
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
#include "tcache.h"
|
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
#include "tscLocalMerge.h"
|
#include "tscLocalMerge.h"
|
||||||
|
@ -57,7 +56,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
|
||||||
if (pSql->sqlstr == NULL) {
|
if (pSql->sqlstr == NULL) {
|
||||||
tscError("%p failed to malloc sql string buffer", pSql);
|
tscError("%p failed to malloc sql string buffer", pSql);
|
||||||
pSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +70,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
pSql->res.code = code;
|
pSql->res.code = code;
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +165,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo
|
||||||
pRes->code = numOfRows;
|
pRes->code = numOfRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +216,7 @@ void taos_fetch_rows_a(TAOS_RES *taosa, __async_cb_func_t fp, void *param) {
|
||||||
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
|
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
|
||||||
pSql->param = param;
|
pSql->param = param;
|
||||||
|
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +279,7 @@ void taos_fetch_row_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, TAOS_ROW),
|
||||||
pSql->param = param;
|
pSql->param = param;
|
||||||
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
|
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
|
||||||
|
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +381,7 @@ void tscQueueAsyncError(void(*fp), void *param, int32_t code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tscQueueAsyncRes(SSqlObj *pSql) {
|
void tscAsyncResultOnError(SSqlObj *pSql) {
|
||||||
if (pSql == NULL || pSql->signature != pSql) {
|
if (pSql == NULL || pSql->signature != pSql) {
|
||||||
tscDebug("%p SqlObj is freed, not add into queue async res", pSql);
|
tscDebug("%p SqlObj is freed, not add into queue async res", pSql);
|
||||||
return;
|
return;
|
||||||
|
@ -423,7 +422,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||||
|
|
||||||
// check if it is a sub-query of super table query first, if true, enter another routine
|
// check if it is a sub-query of super table query first, if true, enter another routine
|
||||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
||||||
tscDebug("%p update table meta in local cache, continue to process sql and send the corresponding query", pSql);
|
tscDebug("%p update local table meta, continue to process sql and send the corresponding query", pSql);
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||||
|
@ -440,7 +439,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||||
return;
|
return;
|
||||||
} else { // continue to process normal async query
|
} else { // continue to process normal async query
|
||||||
if (pCmd->parseFinished) {
|
if (pCmd->parseFinished) {
|
||||||
tscDebug("%p update table meta in local cache, continue to process sql and send corresponding query", pSql);
|
tscDebug("%p update local table meta, continue to process sql and send corresponding query", pSql);
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||||
|
@ -455,7 +454,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||||
if (pCmd->command == TSDB_SQL_SELECT) {
|
if (pCmd->command == TSDB_SQL_SELECT) {
|
||||||
tscDebug("%p redo parse sql string and proceed", pSql);
|
tscDebug("%p redo parse sql string and proceed", pSql);
|
||||||
pCmd->parseFinished = false;
|
pCmd->parseFinished = false;
|
||||||
tscResetSqlCmdObj(pCmd, false);
|
tscResetSqlCmdObj(pCmd);
|
||||||
|
|
||||||
code = tsParseSql(pSql, true);
|
code = tsParseSql(pSql, true);
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
|
@ -532,6 +531,6 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||||
_error:
|
_error:
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
pSql->res.code = code;
|
pSql->res.code = code;
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
|
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tcache.h"
|
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscUtil.h"
|
#include "tscUtil.h"
|
||||||
|
@ -273,7 +272,7 @@ void tscSCreateCallBack(void *param, TAOS_RES *tres, int code) {
|
||||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||||
taos_free_result(pSql);
|
taos_free_result(pSql);
|
||||||
free(builder);
|
free(builder);
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +290,7 @@ void tscSCreateCallBack(void *param, TAOS_RES *tres, int code) {
|
||||||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||||
(*pParentSql->fp)(pParentSql->param, pParentSql, code);
|
(*pParentSql->fp)(pParentSql->param, pParentSql, code);
|
||||||
} else {
|
} else {
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -571,7 +570,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch
|
||||||
|
|
||||||
char fullName[TSDB_TABLE_FNAME_LEN * 2] = {0};
|
char fullName[TSDB_TABLE_FNAME_LEN * 2] = {0};
|
||||||
extractDBName(pTableMetaInfo->name, fullName);
|
extractDBName(pTableMetaInfo->name, fullName);
|
||||||
extractTableName(pMeta->sTableId, param->sTableName);
|
extractTableName(pMeta->sTableName, param->sTableName);
|
||||||
snprintf(fullName + strlen(fullName), TSDB_TABLE_FNAME_LEN - strlen(fullName), ".%s", param->sTableName);
|
snprintf(fullName + strlen(fullName), TSDB_TABLE_FNAME_LEN - strlen(fullName), ".%s", param->sTableName);
|
||||||
extractTableName(pTableMetaInfo->name, param->buf);
|
extractTableName(pTableMetaInfo->name, param->buf);
|
||||||
|
|
||||||
|
@ -901,7 +900,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
||||||
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) {
|
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) {
|
||||||
pRes->code = tscProcessShowCreateDatabase(pSql);
|
pRes->code = tscProcessShowCreateDatabase(pSql);
|
||||||
} else if (pCmd->command == TSDB_SQL_RESET_CACHE) {
|
} else if (pCmd->command == TSDB_SQL_RESET_CACHE) {
|
||||||
taosCacheEmpty(tscMetaCache);
|
taosHashEmpty(tscTableMetaInfo);
|
||||||
pRes->code = TSDB_CODE_SUCCESS;
|
pRes->code = TSDB_CODE_SUCCESS;
|
||||||
} else if (pCmd->command == TSDB_SQL_SERV_VERSION) {
|
} else if (pCmd->command == TSDB_SQL_SERV_VERSION) {
|
||||||
pRes->code = tscProcessServerVer(pSql);
|
pRes->code = tscProcessServerVer(pSql);
|
||||||
|
@ -925,7 +924,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
||||||
(*pSql->fp)(pSql->param, pSql, code);
|
(*pSql->fp)(pSql->param, pSql, code);
|
||||||
} else if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS){
|
} else if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS){
|
||||||
} else {
|
} else {
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc
|
||||||
pCtx->startOffset = 0;
|
pCtx->startOffset = 0;
|
||||||
pCtx->size = 1;
|
pCtx->size = 1;
|
||||||
pCtx->hasNull = true;
|
pCtx->hasNull = true;
|
||||||
pCtx->currentStage = SECONDARY_STAGE_MERGE;
|
pCtx->currentStage = MERGE_STAGE;
|
||||||
|
|
||||||
// for top/bottom function, the output of timestamp is the first column
|
// for top/bottom function, the output of timestamp is the first column
|
||||||
int32_t functionId = pExpr->functionId;
|
int32_t functionId = pExpr->functionId;
|
||||||
|
@ -1067,7 +1067,7 @@ static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalReducer *pLocalReducer,
|
||||||
pCtx->param[0].i64Key = pExpr->param[0].i64Key;
|
pCtx->param[0].i64Key = pExpr->param[0].i64Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
pCtx->currentStage = SECONDARY_STAGE_MERGE;
|
pCtx->currentStage = MERGE_STAGE;
|
||||||
|
|
||||||
if (needInit) {
|
if (needInit) {
|
||||||
aAggs[pCtx->functionId].init(pCtx);
|
aAggs[pCtx->functionId].init(pCtx);
|
||||||
|
@ -1080,7 +1080,7 @@ static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalReducer *pLocalReducer,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
aAggs[functionId].distSecondaryMergeFunc(&pLocalReducer->pCtx[j]);
|
aAggs[functionId].mergeFunc(&pLocalReducer->pCtx[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1647,7 +1647,7 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
||||||
// calculate the result from several other columns
|
// calculate the result from several other columns
|
||||||
if (pSup->pArithExprInfo != NULL) {
|
if (pSup->pArithExprInfo != NULL) {
|
||||||
arithSup.pArithExpr = pSup->pArithExprInfo;
|
arithSup.pArithExpr = pSup->pArithExprInfo;
|
||||||
tExprTreeCalcTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc);
|
arithmeticTreeTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc);
|
||||||
} else {
|
} else {
|
||||||
SSqlExpr* pExpr = pSup->pSqlExpr;
|
SSqlExpr* pExpr = pSup->pSqlExpr;
|
||||||
memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, (size_t)(pExpr->resBytes * pOutput->num));
|
memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, (size_t)(pExpr->resBytes * pOutput->num));
|
||||||
|
|
|
@ -1339,7 +1339,7 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
|
||||||
if (sqlstr == NULL || pSql->parseRetry >= 1 || ret != TSDB_CODE_TSC_INVALID_SQL) {
|
if (sqlstr == NULL || pSql->parseRetry >= 1 || ret != TSDB_CODE_TSC_INVALID_SQL) {
|
||||||
free(sqlstr);
|
free(sqlstr);
|
||||||
} else {
|
} else {
|
||||||
tscResetSqlCmdObj(pCmd, true);
|
tscResetSqlCmdObj(pCmd);
|
||||||
free(pSql->sqlstr);
|
free(pSql->sqlstr);
|
||||||
pSql->sqlstr = sqlstr;
|
pSql->sqlstr = sqlstr;
|
||||||
pSql->parseRetry++;
|
pSql->parseRetry++;
|
||||||
|
@ -1351,7 +1351,7 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
|
||||||
SSqlInfo SQLInfo = qSQLParse(pSql->sqlstr);
|
SSqlInfo SQLInfo = qSQLParse(pSql->sqlstr);
|
||||||
ret = tscToSQLCmd(pSql, &SQLInfo);
|
ret = tscToSQLCmd(pSql, &SQLInfo);
|
||||||
if (ret == TSDB_CODE_TSC_INVALID_SQL && pSql->parseRetry == 0 && SQLInfo.type == TSDB_SQL_NULL) {
|
if (ret == TSDB_CODE_TSC_INVALID_SQL && pSql->parseRetry == 0 && SQLInfo.type == TSDB_SQL_NULL) {
|
||||||
tscResetSqlCmdObj(pCmd, true);
|
tscResetSqlCmdObj(pCmd);
|
||||||
pSql->parseRetry++;
|
pSql->parseRetry++;
|
||||||
ret = tscToSQLCmd(pSql, &SQLInfo);
|
ret = tscToSQLCmd(pSql, &SQLInfo);
|
||||||
}
|
}
|
||||||
|
@ -1429,7 +1429,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int code) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
pParentSql->res.code = code;
|
pParentSql->res.code = code;
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
return;
|
return;
|
||||||
} while (0);
|
} while (0);
|
||||||
}
|
}
|
||||||
|
@ -1451,7 +1451,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int code) {
|
||||||
int32_t count = 0;
|
int32_t count = 0;
|
||||||
int32_t maxRows = 0;
|
int32_t maxRows = 0;
|
||||||
|
|
||||||
tfree(pCmd->pTableMetaList);
|
tfree(pCmd->pTableNameList);
|
||||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||||
|
|
||||||
if (pCmd->pTableBlockHashList == NULL) {
|
if (pCmd->pTableBlockHashList == NULL) {
|
||||||
|
@ -1500,7 +1500,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int code) {
|
||||||
code = doPackSendDataBlock(pSql, count, pTableDataBlock);
|
code = doPackSendDataBlock(pSql, count, pTableDataBlock);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
pParentSql->res.code = code;
|
pParentSql->res.code = code;
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1535,7 +1535,7 @@ void tscProcessMultiVnodesImportFromFile(SSqlObj *pSql) {
|
||||||
tscError("%p failed to open file %s to load data from file, code:%s", pSql, pCmd->payload, tstrerror(pSql->res.code));
|
tscError("%p failed to open file %s to load data from file, code:%s", pSql, pCmd->payload, tstrerror(pSql->res.code));
|
||||||
|
|
||||||
tfree(pSupporter);
|
tfree(pSupporter);
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -910,7 +910,7 @@ int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableNa
|
||||||
* that are corresponding to the old name for the new table name.
|
* that are corresponding to the old name for the new table name.
|
||||||
*/
|
*/
|
||||||
if (strlen(oldName) > 0 && strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
|
if (strlen(oldName) > 0 && strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
|
||||||
tscClearTableMetaInfo(pTableMetaInfo, false);
|
tscClearTableMetaInfo(pTableMetaInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -4019,6 +4019,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
|
||||||
if (pExpr->nSQLOptr == TK_LIKE) {
|
if (pExpr->nSQLOptr == TK_LIKE) {
|
||||||
char* str = taosStringBuilderGetResult(sb, NULL);
|
char* str = taosStringBuilderGetResult(sb, NULL);
|
||||||
pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
|
pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
|
||||||
|
pQueryInfo->tagCond.tbnameCond.len = (int32_t) strlen(str);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4068,6 +4069,7 @@ static int32_t setTableCondForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo,
|
||||||
|
|
||||||
char* str = taosStringBuilderGetResult(&sb1, NULL);
|
char* str = taosStringBuilderGetResult(&sb1, NULL);
|
||||||
pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
|
pQueryInfo->tagCond.tbnameCond.cond = strdup(str);
|
||||||
|
pQueryInfo->tagCond.tbnameCond.len = (int32_t) strlen(str);
|
||||||
|
|
||||||
taosStringBuilderDestroy(&sb1);
|
taosStringBuilderDestroy(&sb1);
|
||||||
tfree(segments);
|
tfree(segments);
|
||||||
|
@ -6381,6 +6383,41 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
||||||
|
const char* msg3 = "start(end) time of query range required or time range too large";
|
||||||
|
|
||||||
|
if (pQueryInfo->interval.interval == 0) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool initialWindows = TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER);
|
||||||
|
if (initialWindows) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
|
||||||
|
|
||||||
|
int64_t intervalRange = 0;
|
||||||
|
if (pQueryInfo->interval.intervalUnit == 'n' || pQueryInfo->interval.intervalUnit == 'y') {
|
||||||
|
int64_t f = 1;
|
||||||
|
if (pQueryInfo->interval.intervalUnit == 'n') {
|
||||||
|
f = 30L * MILLISECOND_PER_DAY;
|
||||||
|
} else if (pQueryInfo->interval.intervalUnit == 'y') {
|
||||||
|
f = 365L * MILLISECOND_PER_DAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
intervalRange = pQueryInfo->interval.interval * f;
|
||||||
|
} else {
|
||||||
|
intervalRange = pQueryInfo->interval.interval;
|
||||||
|
}
|
||||||
|
// number of result is not greater than 10,000,000
|
||||||
|
if ((timeRange == 0) || (timeRange / intervalRange) >= MAX_INTERVAL_TIME_WINDOW) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
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 || taosArrayGetSize(pQuerySql->from) > 0));
|
assert(pQuerySql != NULL && (pQuerySql->from == NULL || taosArrayGetSize(pQuerySql->from) > 0));
|
||||||
|
|
||||||
|
@ -6576,31 +6613,21 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||||
|
|
||||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||||
|
|
||||||
/*
|
|
||||||
* fill options are set at the end position, when all columns are set properly
|
|
||||||
* the columns may be increased due to group by operation
|
|
||||||
*/
|
|
||||||
if (pQuerySql->fillType != NULL) {
|
if (pQuerySql->fillType != NULL) {
|
||||||
if (pQueryInfo->interval.interval == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
|
if (pQueryInfo->interval.interval == 0 && (!tscIsPointInterpQuery(pQueryInfo))) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pQueryInfo->interval.interval > 0) {
|
/*
|
||||||
bool initialWindows = TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER);
|
* fill options are set at the end position, when all columns are set properly
|
||||||
if (initialWindows) {
|
* the columns may be increased due to group by operation
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
*/
|
||||||
}
|
if ((code = checkQueryRangeForFill(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey);
|
|
||||||
// number of result is not greater than 10,000,000
|
|
||||||
if ((timeRange == 0) || (timeRange / pQueryInfo->interval.interval) > MAX_INTERVAL_TIME_WINDOW) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ret = parseFillClause(pCmd, pQueryInfo, pQuerySql);
|
if ((code = parseFillClause(pCmd, pQueryInfo, pQuerySql)) != TSDB_CODE_SUCCESS) {
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
return code;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,19 +130,8 @@ SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tscInitCorVgroupInfo(SCorVgroupInfo *corVgroupInfo, SVgroupMsg *pVgroupMsg) {
|
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg) {
|
||||||
corVgroupInfo->version = 0;
|
assert(pTableMetaMsg != NULL && pTableMetaMsg->numOfColumns >= 2 && pTableMetaMsg->numOfTags >= 0);
|
||||||
corVgroupInfo->inUse = 0;
|
|
||||||
corVgroupInfo->numOfEps = pVgroupMsg->numOfEps;
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pVgroupMsg->numOfEps; i++) {
|
|
||||||
corVgroupInfo->epAddr[i].fqdn = strndup(pVgroupMsg->epAddr[i].fqdn, tListLen(pVgroupMsg->epAddr[0].fqdn));
|
|
||||||
corVgroupInfo->epAddr[i].port = pVgroupMsg->epAddr[i].port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size) {
|
|
||||||
assert(pTableMetaMsg != NULL);
|
|
||||||
|
|
||||||
int32_t schemaSize = (pTableMetaMsg->numOfColumns + pTableMetaMsg->numOfTags) * sizeof(SSchema);
|
int32_t schemaSize = (pTableMetaMsg->numOfColumns + pTableMetaMsg->numOfTags) * sizeof(SSchema);
|
||||||
STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + schemaSize);
|
STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + schemaSize);
|
||||||
|
@ -159,11 +148,9 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size
|
||||||
pTableMeta->id.tid = pTableMetaMsg->tid;
|
pTableMeta->id.tid = pTableMetaMsg->tid;
|
||||||
pTableMeta->id.uid = pTableMetaMsg->uid;
|
pTableMeta->id.uid = pTableMetaMsg->uid;
|
||||||
|
|
||||||
tscInitCorVgroupInfo(&pTableMeta->corVgroupInfo, &pTableMetaMsg->vgroup);
|
|
||||||
|
|
||||||
pTableMeta->sversion = pTableMetaMsg->sversion;
|
pTableMeta->sversion = pTableMetaMsg->sversion;
|
||||||
pTableMeta->tversion = pTableMetaMsg->tversion;
|
pTableMeta->tversion = pTableMetaMsg->tversion;
|
||||||
tstrncpy(pTableMeta->sTableId, pTableMetaMsg->sTableId, TSDB_TABLE_FNAME_LEN);
|
tstrncpy(pTableMeta->sTableName, pTableMetaMsg->sTableName, TSDB_TABLE_FNAME_LEN);
|
||||||
|
|
||||||
memcpy(pTableMeta->schema, pTableMetaMsg->schema, schemaSize);
|
memcpy(pTableMeta->schema, pTableMetaMsg->schema, schemaSize);
|
||||||
|
|
||||||
|
@ -172,13 +159,44 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size
|
||||||
pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes;
|
pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size != NULL) {
|
|
||||||
*size = sizeof(STableMeta) + schemaSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pTableMeta;
|
return pTableMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src) {
|
||||||
|
assert(pExisted != NULL && src != NULL);
|
||||||
|
if (pExisted->numOfEps != src->numOfEps) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < pExisted->numOfEps; ++i) {
|
||||||
|
if (pExisted->ep[i].port != src->epAddr[i].port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(pExisted->ep[i].fqdn, src->epAddr[i].fqdn, tListLen(pExisted->ep[i].fqdn)) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg) {
|
||||||
|
assert(pVgroupMsg != NULL);
|
||||||
|
|
||||||
|
SNewVgroupInfo info = {0};
|
||||||
|
info.numOfEps = pVgroupMsg->numOfEps;
|
||||||
|
info.vgId = pVgroupMsg->vgId;
|
||||||
|
info.inUse = 0;
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < pVgroupMsg->numOfEps; ++i) {
|
||||||
|
tstrncpy(info.ep[i].fqdn, pVgroupMsg->epAddr[i].fqdn, TSDB_FQDN_LEN);
|
||||||
|
info.ep[i].port = pVgroupMsg->epAddr[i].port;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
// todo refactor
|
// todo refactor
|
||||||
UNUSED_FUNC static FORCE_INLINE char* skipSegments(char* input, char delim, int32_t num) {
|
UNUSED_FUNC static FORCE_INLINE char* skipSegments(char* input, char delim, int32_t num) {
|
||||||
for (int32_t i = 0; i < num; ++i) {
|
for (int32_t i = 0; i < num; ++i) {
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tcache.h"
|
|
||||||
#include "tcmdtype.h"
|
#include "tcmdtype.h"
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
#include "tscLocalMerge.h"
|
#include "tscLocalMerge.h"
|
||||||
|
@ -85,7 +84,8 @@ static void tscEpSetHtons(SRpcEpSet *s) {
|
||||||
bool tscEpSetIsEqual(SRpcEpSet *s1, SRpcEpSet *s2) {
|
bool tscEpSetIsEqual(SRpcEpSet *s1, SRpcEpSet *s2) {
|
||||||
if (s1->numOfEps != s2->numOfEps || s1->inUse != s2->inUse) {
|
if (s1->numOfEps != s2->numOfEps || s1->inUse != s2->inUse) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < s1->numOfEps; i++) {
|
for (int32_t i = 0; i < s1->numOfEps; i++) {
|
||||||
if (s1->port[i] != s2->port[i]
|
if (s1->port[i] != s2->port[i]
|
||||||
|| strncmp(s1->fqdn[i], s2->fqdn[i], TSDB_FQDN_LEN) != 0)
|
|| strncmp(s1->fqdn[i], s2->fqdn[i], TSDB_FQDN_LEN) != 0)
|
||||||
|
@ -93,6 +93,7 @@ bool tscEpSetIsEqual(SRpcEpSet *s1, SRpcEpSet *s2) {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscUpdateMgmtEpSet(SSqlObj *pSql, SRpcEpSet *pEpSet) {
|
void tscUpdateMgmtEpSet(SSqlObj *pSql, SRpcEpSet *pEpSet) {
|
||||||
// no need to update if equal
|
// no need to update if equal
|
||||||
SRpcCorEpSet *pCorEpSet = pSql->pTscObj->tscCorMgmtEpSet;
|
SRpcCorEpSet *pCorEpSet = pSql->pTscObj->tscCorMgmtEpSet;
|
||||||
|
@ -101,37 +102,44 @@ void tscUpdateMgmtEpSet(SSqlObj *pSql, SRpcEpSet *pEpSet) {
|
||||||
taosCorEndWrite(&pCorEpSet->version);
|
taosCorEndWrite(&pCorEpSet->version);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tscDumpEpSetFromVgroupInfo(SRpcEpSet *pEpSet, SCorVgroupInfo *pVgroupInfo) {
|
static void tscDumpEpSetFromVgroupInfo(SRpcEpSet *pEpSet, SNewVgroupInfo *pVgroupInfo) {
|
||||||
if (pVgroupInfo == NULL) { return;}
|
if (pVgroupInfo == NULL) { return;}
|
||||||
taosCorBeginRead(&pVgroupInfo->version);
|
|
||||||
int8_t inUse = pVgroupInfo->inUse;
|
int8_t inUse = pVgroupInfo->inUse;
|
||||||
pEpSet->inUse = (inUse >= 0 && inUse < TSDB_MAX_REPLICA) ? inUse: 0;
|
pEpSet->inUse = (inUse >= 0 && inUse < TSDB_MAX_REPLICA) ? inUse: 0;
|
||||||
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) {
|
||||||
tstrncpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn, sizeof(pEpSet->fqdn[i]));
|
tstrncpy(pEpSet->fqdn[i], pVgroupInfo->ep[i].fqdn, sizeof(pEpSet->fqdn[i]));
|
||||||
pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
|
pEpSet->port[i] = pVgroupInfo->ep[i].port;
|
||||||
}
|
}
|
||||||
taosCorEndRead(&pVgroupInfo->version);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tscUpdateVgroupInfo(SSqlObj *pObj, SRpcEpSet *pEpSet) {
|
static void tscUpdateVgroupInfo(SSqlObj *pObj, SRpcEpSet *pEpSet) {
|
||||||
SSqlCmd *pCmd = &pObj->cmd;
|
SSqlCmd *pCmd = &pObj->cmd;
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||||
if (pTableMetaInfo == NULL || pTableMetaInfo->pTableMeta == NULL) { return;}
|
if (pTableMetaInfo == NULL || pTableMetaInfo->pTableMeta == NULL) {
|
||||||
SCorVgroupInfo *pVgroupInfo = &pTableMetaInfo->pTableMeta->corVgroupInfo;
|
return;
|
||||||
|
|
||||||
taosCorBeginWrite(&pVgroupInfo->version);
|
|
||||||
tscDebug("before: Endpoint in use: %d", pVgroupInfo->inUse);
|
|
||||||
pVgroupInfo->inUse = pEpSet->inUse;
|
|
||||||
pVgroupInfo->numOfEps = pEpSet->numOfEps;
|
|
||||||
for (int32_t i = 0; i < pVgroupInfo->numOfEps; i++) {
|
|
||||||
tfree(pVgroupInfo->epAddr[i].fqdn);
|
|
||||||
pVgroupInfo->epAddr[i].fqdn = strndup(pEpSet->fqdn[i], tListLen(pEpSet->fqdn[i]));
|
|
||||||
pVgroupInfo->epAddr[i].port = pEpSet->port[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("after: EndPoint in use: %d", pVgroupInfo->inUse);
|
int32_t vgId = pTableMetaInfo->pTableMeta->vgId;
|
||||||
taosCorEndWrite(&pVgroupInfo->version);
|
if (pTableMetaInfo->pTableMeta->tableType == TSDB_SUPER_TABLE) {
|
||||||
|
assert(vgId == 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNewVgroupInfo vgroupInfo = {.vgId = -1};
|
||||||
|
taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||||
|
assert(vgroupInfo.numOfEps > 0 && vgroupInfo.vgId > 0);
|
||||||
|
|
||||||
|
tscDebug("before: Endpoint in use:%d, numOfEps:%d", vgroupInfo.inUse, vgroupInfo.numOfEps);
|
||||||
|
vgroupInfo.inUse = pEpSet->inUse;
|
||||||
|
vgroupInfo.numOfEps = pEpSet->numOfEps;
|
||||||
|
for (int32_t i = 0; i < vgroupInfo.numOfEps; i++) {
|
||||||
|
strncpy(vgroupInfo.ep[i].fqdn, pEpSet->fqdn[i], TSDB_FQDN_LEN);
|
||||||
|
vgroupInfo.ep[i].port = pEpSet->port[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
tscDebug("after: EndPoint in use:%d, numOfEps:%d", vgroupInfo.inUse, vgroupInfo.numOfEps);
|
||||||
|
taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
||||||
|
@ -303,7 +311,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pEpSet) {
|
if (pEpSet) { // todo update this
|
||||||
if (!tscEpSetIsEqual(&pSql->epSet, pEpSet)) {
|
if (!tscEpSetIsEqual(&pSql->epSet, pEpSet)) {
|
||||||
if (pCmd->command < TSDB_SQL_MGMT) {
|
if (pCmd->command < TSDB_SQL_MGMT) {
|
||||||
tscUpdateVgroupInfo(pSql, pEpSet);
|
tscUpdateVgroupInfo(pSql, pEpSet);
|
||||||
|
@ -437,7 +445,7 @@ int doProcessSql(SSqlObj *pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return pRes->code;
|
return pRes->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +454,7 @@ int doProcessSql(SSqlObj *pSql) {
|
||||||
// NOTE: if code is TSDB_CODE_SUCCESS, pSql may have been released here already by other threads.
|
// NOTE: if code is TSDB_CODE_SUCCESS, pSql may have been released here already by other threads.
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
pRes->code = code;
|
pRes->code = code;
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,7 +557,10 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
|
|
||||||
// pSql->cmd.payloadLen is set during copying data into payload
|
// pSql->cmd.payloadLen is set during copying data into payload
|
||||||
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
||||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &pTableMeta->corVgroupInfo);
|
|
||||||
|
SNewVgroupInfo vgroupInfo = {0};
|
||||||
|
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||||
|
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
|
||||||
|
|
||||||
tscDebug("%p build submit msg, vgId:%d numOfTables:%d numberOfEP:%d", pSql, pTableMeta->vgId, pSql->cmd.numOfTablesInSubmit,
|
tscDebug("%p build submit msg, vgId:%d numOfTables:%d numberOfEP:%d", pSql, pTableMeta->vgId, pSql->cmd.numOfTablesInSubmit,
|
||||||
pSql->epSet.numOfEps);
|
pSql->epSet.numOfEps);
|
||||||
|
@ -559,9 +570,11 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
/*
|
/*
|
||||||
* for table query, simply return the size <= 1k
|
* for table query, simply return the size <= 1k
|
||||||
*/
|
*/
|
||||||
static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql, int32_t clauseIndex) {
|
||||||
const static int32_t MIN_QUERY_MSG_PKT_SIZE = TSDB_MAX_BYTES_PER_ROW * 5;
|
const static int32_t MIN_QUERY_MSG_PKT_SIZE = TSDB_MAX_BYTES_PER_ROW * 5;
|
||||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
|
||||||
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
||||||
|
|
||||||
int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo));
|
int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo));
|
||||||
|
|
||||||
|
@ -569,6 +582,8 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
||||||
int32_t exprSize = (int32_t)(sizeof(SSqlFuncMsg) * numOfExprs * 2);
|
int32_t exprSize = (int32_t)(sizeof(SSqlFuncMsg) * numOfExprs * 2);
|
||||||
|
|
||||||
int32_t tsBufSize = (pQueryInfo->tsBuf != NULL) ? pQueryInfo->tsBuf->fileSize : 0;
|
int32_t tsBufSize = (pQueryInfo->tsBuf != NULL) ? pQueryInfo->tsBuf->fileSize : 0;
|
||||||
|
int32_t sqlLen = (int32_t) strlen(pSql->sqlstr) + 1;
|
||||||
|
|
||||||
|
|
||||||
int32_t tableSerialize = 0;
|
int32_t tableSerialize = 0;
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
@ -585,7 +600,7 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryTableMsg) + srcColListSize + exprSize + tsBufSize +
|
return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryTableMsg) + srcColListSize + exprSize + tsBufSize +
|
||||||
tableSerialize + 4096;
|
tableSerialize + sqlLen + 4096;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char *pMsg) {
|
static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char *pMsg) {
|
||||||
|
@ -611,7 +626,10 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
||||||
tscDebug("%p query on stable, vgIndex:%d, numOfVgroups:%d", pSql, index, pTableMetaInfo->vgroupList->numOfVgroups);
|
tscDebug("%p query on stable, vgIndex:%d, numOfVgroups:%d", pSql, index, pTableMetaInfo->vgroupList->numOfVgroups);
|
||||||
} else {
|
} else {
|
||||||
vgId = pTableMeta->vgId;
|
vgId = pTableMeta->vgId;
|
||||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &pTableMeta->corVgroupInfo);
|
|
||||||
|
SNewVgroupInfo vgroupInfo = {0};
|
||||||
|
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||||
|
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
pSql->epSet.inUse = rand()%pSql->epSet.numOfEps;
|
pSql->epSet.inUse = rand()%pSql->epSet.numOfEps;
|
||||||
|
@ -662,7 +680,7 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
||||||
int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
int32_t size = tscEstimateQueryMsgSize(pCmd, pCmd->clauseIndex);
|
int32_t size = tscEstimateQueryMsgSize(pSql, pCmd->clauseIndex);
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
|
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
|
||||||
tscError("%p failed to malloc for query msg", pSql);
|
tscError("%p failed to malloc for query msg", pSql);
|
||||||
|
@ -695,7 +713,8 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
tstrncpy(pQueryMsg->version, version, tListLen(pQueryMsg->version));
|
tstrncpy(pQueryMsg->version, version, tListLen(pQueryMsg->version));
|
||||||
|
|
||||||
int32_t numOfTags = (int32_t)taosArrayGetSize(pTableMetaInfo->tagColList);
|
int32_t numOfTags = (int32_t)taosArrayGetSize(pTableMetaInfo->tagColList);
|
||||||
|
int32_t sqlLen = (int32_t) strlen(pSql->sqlstr);
|
||||||
|
|
||||||
if (pQueryInfo->order.order == TSDB_ORDER_ASC) {
|
if (pQueryInfo->order.order == TSDB_ORDER_ASC) {
|
||||||
pQueryMsg->window.skey = htobe64(pQueryInfo->window.skey);
|
pQueryMsg->window.skey = htobe64(pQueryInfo->window.skey);
|
||||||
pQueryMsg->window.ekey = htobe64(pQueryInfo->window.ekey);
|
pQueryMsg->window.ekey = htobe64(pQueryInfo->window.ekey);
|
||||||
|
@ -718,10 +737,12 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->interval.offsetUnit = pQueryInfo->interval.offsetUnit;
|
pQueryMsg->interval.offsetUnit = pQueryInfo->interval.offsetUnit;
|
||||||
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
|
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
|
||||||
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
|
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
|
||||||
|
pQueryMsg->tbnameCondLen = htonl(pQueryInfo->tagCond.tbnameCond.len);
|
||||||
pQueryMsg->numOfTags = htonl(numOfTags);
|
pQueryMsg->numOfTags = htonl(numOfTags);
|
||||||
pQueryMsg->queryType = htonl(pQueryInfo->type);
|
pQueryMsg->queryType = htonl(pQueryInfo->type);
|
||||||
pQueryMsg->vgroupLimit = htobe64(pQueryInfo->vgroupLimit);
|
pQueryMsg->vgroupLimit = htobe64(pQueryInfo->vgroupLimit);
|
||||||
|
pQueryMsg->sqlstrLen = htonl(sqlLen);
|
||||||
|
|
||||||
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number
|
pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number
|
||||||
|
|
||||||
|
@ -954,13 +975,11 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pMsg += pCond->len;
|
pMsg += pCond->len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pQueryInfo->tagCond.tbnameCond.cond == NULL) {
|
SCond* pCond = &pQueryInfo->tagCond.tbnameCond;
|
||||||
*pMsg = 0;
|
if (pCond->len > 0) {
|
||||||
pMsg++;
|
strncpy(pMsg, pCond->cond, pCond->len);
|
||||||
} else {
|
pMsg += pCond->len;
|
||||||
strcpy(pMsg, pQueryInfo->tagCond.tbnameCond.cond);
|
|
||||||
pMsg += strlen(pQueryInfo->tagCond.tbnameCond.cond) + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// compressed ts block
|
// compressed ts block
|
||||||
|
@ -981,6 +1000,9 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->tsNumOfBlocks = htonl(pQueryMsg->tsNumOfBlocks);
|
pQueryMsg->tsNumOfBlocks = htonl(pQueryMsg->tsNumOfBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(pMsg, pSql->sqlstr, sqlLen);
|
||||||
|
pMsg += sqlLen;
|
||||||
|
|
||||||
int32_t msgLen = (int32_t)(pMsg - pCmd->payload);
|
int32_t msgLen = (int32_t)(pMsg - pCmd->payload);
|
||||||
|
|
||||||
tscDebug("%p msg built success, len:%d bytes", pSql, msgLen);
|
tscDebug("%p msg built success, len:%d bytes", pSql, msgLen);
|
||||||
|
@ -1447,10 +1469,14 @@ int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) {
|
||||||
SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
|
SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
|
||||||
pCmd->payloadLen = htonl(pUpdateMsg->head.contLen);
|
pCmd->payloadLen = htonl(pUpdateMsg->head.contLen);
|
||||||
|
|
||||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMeta *pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
|
||||||
|
|
||||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &pTableMetaInfo->pTableMeta->corVgroupInfo);
|
SNewVgroupInfo vgroupInfo = {.vgId = -1};
|
||||||
|
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||||
|
assert(vgroupInfo.vgId > 0);
|
||||||
|
|
||||||
|
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1516,7 +1542,7 @@ static int tscLocalResultCommonBuilder(SSqlObj *pSql, int32_t numOfRes) {
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
(*pSql->fp)(pSql->param, pSql, pSql->res.numOfRows);
|
(*pSql->fp)(pSql->param, pSql, pSql->res.numOfRows);
|
||||||
} else {
|
} else {
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1545,7 +1571,7 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
int32_t code = pRes->code;
|
int32_t code = pRes->code;
|
||||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1564,7 +1590,7 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
|
||||||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||||
(*pSql->fp)(pSql->param, pSql, pRes->numOfRows);
|
(*pSql->fp)(pSql->param, pSql, pRes->numOfRows);
|
||||||
} else {
|
} else {
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -1808,19 +1834,46 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
||||||
pSchema++;
|
pSchema++;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = 0;
|
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg);
|
||||||
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg, &size);
|
|
||||||
|
|
||||||
// todo add one more function: taosAddDataIfNotExists();
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||||
assert(pTableMetaInfo->pTableMeta == NULL);
|
assert(pTableMetaInfo->pTableMeta == NULL);
|
||||||
|
|
||||||
pTableMetaInfo->pTableMeta = (STableMeta *) taosCachePut(tscMetaCache, pTableMetaInfo->name,
|
if (pTableMeta->tableType == TSDB_CHILD_TABLE) {
|
||||||
strlen(pTableMetaInfo->name), pTableMeta, size, tsTableMetaKeepTimer * 1000);
|
// check if super table hashmap or not
|
||||||
|
int32_t len = (int32_t) strnlen(pTableMeta->sTableName, TSDB_TABLE_FNAME_LEN);
|
||||||
|
|
||||||
if (pTableMetaInfo->pTableMeta == NULL) {
|
// super tableMeta data alreay exists, create it according to tableMeta and add it to hash map
|
||||||
free(pTableMeta);
|
STableMeta* pSupTableMeta = createSuperTableMeta(pMetaMsg);
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
||||||
|
uint32_t size = tscGetTableMetaSize(pSupTableMeta);
|
||||||
|
int32_t code = taosHashPut(tscTableMetaInfo, pTableMeta->sTableName, len, pSupTableMeta, size);
|
||||||
|
assert(code == TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
|
tfree(pSupTableMeta);
|
||||||
|
|
||||||
|
CChildTableMeta* cMeta = tscCreateChildMeta(pTableMeta);
|
||||||
|
taosHashPut(tscTableMetaInfo, pTableMetaInfo->name, strlen(pTableMetaInfo->name), cMeta, sizeof(CChildTableMeta));
|
||||||
|
tfree(cMeta);
|
||||||
|
} else {
|
||||||
|
uint32_t s = tscGetTableMetaSize(pTableMeta);
|
||||||
|
taosHashPut(tscTableMetaInfo, pTableMetaInfo->name, strlen(pTableMetaInfo->name), pTableMeta, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the vgroupInfo if needed
|
||||||
|
if (pTableMeta->vgId > 0) {
|
||||||
|
int32_t vgId = pTableMeta->vgId;
|
||||||
|
assert(pTableMeta->tableType != TSDB_SUPER_TABLE);
|
||||||
|
|
||||||
|
SNewVgroupInfo vgroupInfo = {.inUse = -1};
|
||||||
|
taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||||
|
|
||||||
|
if (((vgroupInfo.inUse >= 0) && !vgroupInfoIdentical(&vgroupInfo, &pMetaMsg->vgroup)) ||
|
||||||
|
(vgroupInfo.inUse < 0)) { // vgroup info exists, compare with it
|
||||||
|
vgroupInfo = createNewVgroupInfo(&pMetaMsg->vgroup);
|
||||||
|
taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(vgroupInfo));
|
||||||
|
tscDebug("add new VgroupInfo, vgId:%d, total:%d", vgId, (int32_t) taosHashGetSize(tscVgroupMap));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tscDebug("%p recv table meta, uid:%"PRId64 ", tid:%d, name:%s", pSql, pTableMeta->id.uid, pTableMeta->id.tid, pTableMetaInfo->name);
|
tscDebug("%p recv table meta, uid:%"PRId64 ", tid:%d, name:%s", pSql, pTableMeta->id.uid, pTableMeta->id.tid, pTableMetaInfo->name);
|
||||||
|
@ -1831,8 +1884,8 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* multi table meta rsp pkg format:
|
* multi table meta rsp pkg format:
|
||||||
* | STaosRsp | ieType | SMultiTableInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2
|
* | STaosRsp | SMultiTableInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2
|
||||||
* |...... 1B 1B 4B
|
* |...... 1B 4B
|
||||||
**/
|
**/
|
||||||
int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
|
int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -1986,14 +2039,10 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
|
||||||
return pSql->res.code;
|
return pSql->res.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* current process do not use the cache at all
|
|
||||||
*/
|
|
||||||
int tscProcessShowRsp(SSqlObj *pSql) {
|
int tscProcessShowRsp(SSqlObj *pSql) {
|
||||||
STableMetaMsg *pMetaMsg;
|
STableMetaMsg *pMetaMsg;
|
||||||
SShowRsp * pShow;
|
SShowRsp * pShow;
|
||||||
SSchema * pSchema;
|
SSchema * pSchema;
|
||||||
char key[20];
|
|
||||||
|
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
@ -2018,20 +2067,10 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
||||||
pSchema++;
|
pSchema++;
|
||||||
}
|
}
|
||||||
|
|
||||||
key[0] = pCmd->msgType + 'a';
|
tfree(pTableMetaInfo->pTableMeta);
|
||||||
strcpy(key + 1, "showlist");
|
pTableMetaInfo->pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg);
|
||||||
|
|
||||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
|
||||||
taosCacheRelease(tscMetaCache, (void *)&(pTableMetaInfo->pTableMeta), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size = 0;
|
|
||||||
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg, &size);
|
|
||||||
|
|
||||||
pTableMetaInfo->pTableMeta = taosCachePut(tscMetaCache, key, strlen(key), (char *)pTableMeta, size,
|
|
||||||
tsTableMetaKeepTimer * 1000);
|
|
||||||
SSchema *pTableSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
SSchema *pTableSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
if (pQueryInfo->colList == NULL) {
|
if (pQueryInfo->colList == NULL) {
|
||||||
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
|
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
|
||||||
}
|
}
|
||||||
|
@ -2054,12 +2093,9 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
|
pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
|
||||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||||
|
|
||||||
tfree(pTableMeta);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO multithread problem
|
|
||||||
static void createHBObj(STscObj* pObj) {
|
static void createHBObj(STscObj* pObj) {
|
||||||
if (pObj->hbrid != 0) {
|
if (pObj->hbrid != 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -2141,51 +2177,34 @@ int tscProcessUseDbRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
int tscProcessDropDbRsp(SSqlObj *pSql) {
|
int tscProcessDropDbRsp(SSqlObj *pSql) {
|
||||||
pSql->pTscObj->db[0] = 0;
|
pSql->pTscObj->db[0] = 0;
|
||||||
taosCacheEmpty(tscMetaCache);
|
taosHashEmpty(tscTableMetaInfo);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscProcessDropTableRsp(SSqlObj *pSql) {
|
int tscProcessDropTableRsp(SSqlObj *pSql) {
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||||
|
|
||||||
STableMeta *pTableMeta = taosCacheAcquireByKey(tscMetaCache, pTableMetaInfo->name, strlen(pTableMetaInfo->name));
|
//The cached tableMeta is expired in this case, so clean it in hash table
|
||||||
if (pTableMeta == NULL) { /* not in cache, abort */
|
taosHashRemove(tscTableMetaInfo, pTableMetaInfo->name, strnlen(pTableMetaInfo->name, TSDB_TABLE_FNAME_LEN));
|
||||||
return 0;
|
tscDebug("%p remove table meta after drop table:%s, numOfRemain:%d", pSql, pTableMetaInfo->name,
|
||||||
}
|
(int32_t) taosHashGetSize(tscTableMetaInfo));
|
||||||
|
|
||||||
/*
|
|
||||||
* 1. if a user drops one table, which is the only table in a vnode, remove operation will incur vnode to be removed.
|
|
||||||
* 2. Then, a user creates a new metric followed by a table with identical name of removed table but different schema,
|
|
||||||
* here the table will reside in a new vnode.
|
|
||||||
* The cached information is expired, however, we may have lost the ref of original meter. So, clear whole cache
|
|
||||||
* instead.
|
|
||||||
*/
|
|
||||||
tscDebug("%p force release table meta after drop table:%s", pSql, pTableMetaInfo->name);
|
|
||||||
taosCacheRelease(tscMetaCache, (void **)&pTableMeta, true);
|
|
||||||
assert(pTableMetaInfo->pTableMeta == NULL);
|
assert(pTableMetaInfo->pTableMeta == NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscProcessAlterTableMsgRsp(SSqlObj *pSql) {
|
int tscProcessAlterTableMsgRsp(SSqlObj *pSql) {
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||||
|
|
||||||
STableMeta *pTableMeta = taosCacheAcquireByKey(tscMetaCache, pTableMetaInfo->name, strlen(pTableMetaInfo->name));
|
char* name = pTableMetaInfo->name;
|
||||||
if (pTableMeta == NULL) { /* not in cache, abort */
|
tscDebug("%p remove tableMeta in hashMap after alter-table: %s", pSql, name);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tscDebug("%p force release metermeta in cache after alter-table: %s", pSql, pTableMetaInfo->name);
|
bool isSuperTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
||||||
taosCacheRelease(tscMetaCache, (void **)&pTableMeta, true);
|
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||||
|
tfree(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
if (pTableMetaInfo->pTableMeta) {
|
if (isSuperTable) { // if it is a super table, iterate the hashTable and remove all the childTableMeta
|
||||||
bool isSuperTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
taosHashEmpty(tscTableMetaInfo);
|
||||||
taosCacheRelease(tscMetaCache, (void **)&(pTableMetaInfo->pTableMeta), true);
|
|
||||||
|
|
||||||
if (isSuperTable) { // if it is a super table, reset whole query cache
|
|
||||||
tscDebug("%p reset query cache since table:%s is stable", pSql, pTableMetaInfo->name);
|
|
||||||
taosCacheEmpty(tscMetaCache);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2195,6 +2214,7 @@ int tscProcessAlterDbMsgRsp(SSqlObj *pSql) {
|
||||||
UNUSED(pSql);
|
UNUSED(pSql);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscProcessShowCreateRsp(SSqlObj *pSql) {
|
int tscProcessShowCreateRsp(SSqlObj *pSql) {
|
||||||
return tscLocalResultCommonBuilder(pSql, 1);
|
return tscLocalResultCommonBuilder(pSql, 1);
|
||||||
}
|
}
|
||||||
|
@ -2315,7 +2335,7 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn
|
||||||
|
|
||||||
int32_t code = tscProcessSql(pNew);
|
int32_t code = tscProcessSql(pNew);
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify upper application that current process need to be terminated
|
code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify application that current process needs to be terminated
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -2323,21 +2343,29 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn
|
||||||
|
|
||||||
int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
||||||
assert(strlen(pTableMetaInfo->name) != 0);
|
assert(strlen(pTableMetaInfo->name) != 0);
|
||||||
|
tfree(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
// If this STableMetaInfo owns a table meta, release it first
|
uint32_t size = tscGetTableMetaMaxSize();
|
||||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
pTableMetaInfo->pTableMeta = calloc(1, size);
|
||||||
taosCacheRelease(tscMetaCache, (void **)&(pTableMetaInfo->pTableMeta), false);
|
|
||||||
}
|
pTableMetaInfo->pTableMeta->tableInfo.numOfColumns = -1;
|
||||||
|
int32_t len = (int32_t) strlen(pTableMetaInfo->name);
|
||||||
pTableMetaInfo->pTableMeta = (STableMeta *)taosCacheAcquireByKey(tscMetaCache, pTableMetaInfo->name, strlen(pTableMetaInfo->name));
|
|
||||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
taosHashGetClone(tscTableMetaInfo, pTableMetaInfo->name, len, NULL, pTableMetaInfo->pTableMeta, -1);
|
||||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
|
||||||
tscDebug("%p retrieve table Meta from cache, the number of columns:%d, numOfTags:%d, %p", pSql, tinfo.numOfColumns,
|
// TODO resize the tableMeta
|
||||||
tinfo.numOfTags, pTableMetaInfo->pTableMeta);
|
STableMeta* pMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
if (pMeta->id.uid > 0) {
|
||||||
|
if (pMeta->tableType == TSDB_CHILD_TABLE) {
|
||||||
|
int32_t code = tscCreateTableMetaFromCChildMeta(pTableMetaInfo->pTableMeta, pTableMetaInfo->name);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return getTableMetaFromMnode(pSql, pTableMetaInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getTableMetaFromMnode(pSql, pTableMetaInfo);
|
return getTableMetaFromMnode(pSql, pTableMetaInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2347,7 +2375,7 @@ int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool create
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieve table meta from mnode, and update the local table meta cache.
|
* retrieve table meta from mnode, and update the local table meta hashmap.
|
||||||
* @param pSql sql object
|
* @param pSql sql object
|
||||||
* @param tableIndex table index
|
* @param tableIndex table index
|
||||||
* @return status code
|
* @return status code
|
||||||
|
@ -2355,16 +2383,18 @@ int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool create
|
||||||
int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) {
|
int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
|
||||||
|
const char* name = pTableMetaInfo->name;
|
||||||
|
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
if (pTableMetaInfo->pTableMeta) {
|
if (pTableMeta) {
|
||||||
tscDebug("%p update table meta, old meta numOfTags:%d, numOfCols:%d, uid:%" PRId64 ", addr:%p", pSql,
|
tscDebug("%p update table meta:%s, old meta numOfTags:%d, numOfCols:%d, uid:%" PRId64, pSql, name,
|
||||||
tscGetNumOfTags(pTableMeta), tscGetNumOfColumns(pTableMeta), pTableMeta->id.uid, pTableMeta);
|
tscGetNumOfTags(pTableMeta), tscGetNumOfColumns(pTableMeta), pTableMeta->id.uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosCacheRelease(tscMetaCache, (void **)&(pTableMetaInfo->pTableMeta), true);
|
// remove stored tableMeta info in hash table
|
||||||
|
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||||
return getTableMetaFromMnode(pSql, pTableMetaInfo);
|
return getTableMetaFromMnode(pSql, pTableMetaInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2405,7 +2435,7 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) {
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
||||||
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||||
STableMetaInfo *pMInfo = tscGetMetaInfo(pQueryInfo, i);
|
STableMetaInfo *pMInfo = tscGetMetaInfo(pQueryInfo, i);
|
||||||
STableMeta *pTableMeta = taosCacheAcquireByData(tscMetaCache, pMInfo->pTableMeta);
|
STableMeta* pTableMeta = tscTableMetaClone(pMInfo->pTableMeta);
|
||||||
tscAddTableMetaInfo(pNewQueryInfo, pMInfo->name, pTableMeta, NULL, pMInfo->tagColList, pMInfo->pVgroupTables);
|
tscAddTableMetaInfo(pNewQueryInfo, pMInfo->name, pTableMeta, NULL, pMInfo->tagColList, pMInfo->pVgroupTables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -709,7 +709,7 @@ static void tscKillSTableQuery(SSqlObj *pSql) {
|
||||||
pSubObj->rpcRid = -1;
|
pSubObj->rpcRid = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscQueueAsyncRes(pSubObj);
|
tscAsyncResultOnError(pSubObj);
|
||||||
taosReleaseRef(tscObjRef, pSubObj->self);
|
taosReleaseRef(tscObjRef, pSubObj->self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,7 +745,7 @@ void taos_stop_query(TAOS_RES *res) {
|
||||||
pSql->rpcRid = -1;
|
pSql->rpcRid = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -909,7 +909,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
|
|
||||||
static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t tblListLen) {
|
static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t tblListLen) {
|
||||||
// must before clean the sqlcmd object
|
// must before clean the sqlcmd object
|
||||||
tscResetSqlCmdObj(&pSql->cmd, false);
|
tscResetSqlCmdObj(&pSql->cmd);
|
||||||
|
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,9 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
|
||||||
retryDelay);
|
retryDelay);
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pStream->pSql->cmd, 0, 0);
|
||||||
taosCacheRelease(tscMetaCache, (void**)&(pTableMetaInfo->pTableMeta), true);
|
|
||||||
|
char* name = pTableMetaInfo->name;
|
||||||
|
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||||
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);
|
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);
|
||||||
|
|
||||||
tscSetRetryTimer(pStream, pStream->pSql, retryDelay);
|
tscSetRetryTimer(pStream, pStream->pSql, retryDelay);
|
||||||
|
@ -269,9 +271,8 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
||||||
tscDebug("%p stream:%p, query on:%s, fetch result completed, fetched rows:%" PRId64, pSql, pStream, pTableMetaInfo->name,
|
tscDebug("%p stream:%p, query on:%s, fetch result completed, fetched rows:%" PRId64, pSql, pStream, pTableMetaInfo->name,
|
||||||
pStream->numOfRes);
|
pStream->numOfRes);
|
||||||
|
|
||||||
// release the metric/meter meta information reference, so data in cache can be updated
|
tfree(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
taosCacheRelease(tscMetaCache, (void**)&(pTableMetaInfo->pTableMeta), false);
|
|
||||||
tscFreeSqlResult(pSql);
|
tscFreeSqlResult(pSql);
|
||||||
tfree(pSql->pSubs);
|
tfree(pSql->pSubs);
|
||||||
pSql->subState.numOfSub = 0;
|
pSql->subState.numOfSub = 0;
|
||||||
|
|
|
@ -779,7 +779,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
pParentSql->res.code = numOfRows;
|
pParentSql->res.code = numOfRows;
|
||||||
quitAllSubquery(pParentSql, pSupporter);
|
quitAllSubquery(pParentSql, pSupporter);
|
||||||
|
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,7 +796,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
||||||
quitAllSubquery(pParentSql, pSupporter);
|
quitAllSubquery(pParentSql, pSupporter);
|
||||||
|
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,7 +845,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
freeJoinSubqueryObj(pParentSql);
|
freeJoinSubqueryObj(pParentSql);
|
||||||
pParentSql->res.code = code;
|
pParentSql->res.code = code;
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
|
|
||||||
taosArrayDestroy(s1);
|
taosArrayDestroy(s1);
|
||||||
taosArrayDestroy(s2);
|
taosArrayDestroy(s2);
|
||||||
|
@ -916,7 +916,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
pParentSql->res.code = numOfRows;
|
pParentSql->res.code = numOfRows;
|
||||||
quitAllSubquery(pParentSql, pSupporter);
|
quitAllSubquery(pParentSql, pSupporter);
|
||||||
|
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -930,7 +930,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
|
||||||
tscError("%p invalid ts comp file from vnode, abort subquery, file size:%d", pSql, numOfRows);
|
tscError("%p invalid ts comp file from vnode, abort subquery, file size:%d", pSql, numOfRows);
|
||||||
|
|
||||||
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
pParentSql->res.code = TAOS_SYSTEM_ERROR(errno);
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1028,7 +1028,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
||||||
pParentSql->res.code = numOfRows;
|
pParentSql->res.code = numOfRows;
|
||||||
tscError("%p retrieve failed, index:%d, code:%s", pSql, pSupporter->subqueryIndex, tstrerror(numOfRows));
|
tscError("%p retrieve failed, index:%d, code:%s", pSql, pSupporter->subqueryIndex, tstrerror(numOfRows));
|
||||||
|
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1155,7 +1155,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) {
|
||||||
if (pSql->res.code == TSDB_CODE_SUCCESS) {
|
if (pSql->res.code == TSDB_CODE_SUCCESS) {
|
||||||
(*pSql->fp)(pSql->param, pSql, 0);
|
(*pSql->fp)(pSql->param, pSql, 0);
|
||||||
} else {
|
} else {
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1233,7 +1233,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) {
|
||||||
if (pSql->res.code == TSDB_CODE_SUCCESS) {
|
if (pSql->res.code == TSDB_CODE_SUCCESS) {
|
||||||
(*pSql->fp)(pSql->param, pSql, 0);
|
(*pSql->fp)(pSql->param, pSql, 0);
|
||||||
} else {
|
} else {
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1344,7 +1344,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
||||||
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
||||||
tscError("%p abort query due to other subquery failure. code:%d, global code:%d", pSql, code, pParentSql->res.code);
|
tscError("%p abort query due to other subquery failure. code:%d, global code:%d", pSql, code, pParentSql->res.code);
|
||||||
quitAllSubquery(pParentSql, pSupporter);
|
quitAllSubquery(pParentSql, pSupporter);
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1357,7 +1357,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
||||||
pParentSql->res.code = code;
|
pParentSql->res.code = code;
|
||||||
|
|
||||||
quitAllSubquery(pParentSql, pSupporter);
|
quitAllSubquery(pParentSql, pSupporter);
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1403,7 +1403,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
||||||
if (pParentSql->res.code == TSDB_CODE_SUCCESS) {
|
if (pParentSql->res.code == TSDB_CODE_SUCCESS) {
|
||||||
(*pParentSql->fp)(pParentSql->param, pParentSql, 0);
|
(*pParentSql->fp)(pParentSql->param, pParentSql, 0);
|
||||||
} else {
|
} else {
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1612,7 +1612,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
|
||||||
|
|
||||||
_error:
|
_error:
|
||||||
pRes->code = code;
|
pRes->code = code;
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doCleanupSubqueries(SSqlObj *pSql, int32_t numOfSubs) {
|
static void doCleanupSubqueries(SSqlObj *pSql, int32_t numOfSubs) {
|
||||||
|
@ -1666,7 +1666,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
||||||
int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, &pFinalModel, nBufferSize);
|
int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, &pFinalModel, nBufferSize);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
tfree(pMemoryBuf);
|
tfree(pMemoryBuf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1680,7 +1680,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel,pState->numOfSub);
|
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel,pState->numOfSub);
|
||||||
|
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1890,7 +1890,7 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO
|
||||||
(*pParentSql->fp)(pParentSql->param, pParentSql, pParentSql->res.code);
|
(*pParentSql->fp)(pParentSql->param, pParentSql, pParentSql->res.code);
|
||||||
} else { // regular super table query
|
} else { // regular super table query
|
||||||
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1968,7 +1968,7 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
|
||||||
if (pParentSql->res.code == TSDB_CODE_SUCCESS) {
|
if (pParentSql->res.code == TSDB_CODE_SUCCESS) {
|
||||||
(*pParentSql->fp)(pParentSql->param, pParentSql, 0);
|
(*pParentSql->fp)(pParentSql->param, pParentSql, 0);
|
||||||
} else {
|
} else {
|
||||||
tscQueueAsyncRes(pParentSql);
|
tscAsyncResultOnError(pParentSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2220,7 +2220,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
||||||
(*pParentObj->fp)(pParentObj->param, pParentObj, v);
|
(*pParentObj->fp)(pParentObj->param, pParentObj, v);
|
||||||
} else {
|
} else {
|
||||||
if (!needRetryInsert(pParentObj, numOfSub)) {
|
if (!needRetryInsert(pParentObj, numOfSub)) {
|
||||||
tscQueueAsyncRes(pParentObj);
|
tscAsyncResultOnError(pParentObj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2231,7 +2231,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
||||||
numOfFailed += 1;
|
numOfFailed += 1;
|
||||||
|
|
||||||
// clean up tableMeta in cache
|
// clean up tableMeta in cache
|
||||||
tscFreeQueryInfo(&pSql->cmd, true);
|
tscFreeQueryInfo(&pSql->cmd);
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(&pSql->cmd, 0);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(&pSql->cmd, 0);
|
||||||
STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pParentObj->cmd, pSql->cmd.clauseIndex, 0);
|
STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pParentObj->cmd, pSql->cmd.clauseIndex, 0);
|
||||||
tscAddTableMetaInfo(pQueryInfo, pMasterTableMetaInfo->name, NULL, NULL, NULL, NULL);
|
tscAddTableMetaInfo(pQueryInfo, pMasterTableMetaInfo->name, NULL, NULL, NULL, NULL);
|
||||||
|
@ -2243,15 +2243,16 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
||||||
tscError("%p Async insertion completed, total inserted:%d rows, numOfFailed:%d, numOfTotal:%d", pParentObj,
|
tscError("%p Async insertion completed, total inserted:%d rows, numOfFailed:%d, numOfTotal:%d", pParentObj,
|
||||||
pParentObj->res.numOfRows, numOfFailed, numOfSub);
|
pParentObj->res.numOfRows, numOfFailed, numOfSub);
|
||||||
|
|
||||||
tscDebug("%p cleanup %d tableMeta in cache", pParentObj, pParentObj->cmd.numOfTables);
|
tscDebug("%p cleanup %d tableMeta in hashTable", pParentObj, pParentObj->cmd.numOfTables);
|
||||||
for(int32_t i = 0; i < pParentObj->cmd.numOfTables; ++i) {
|
for(int32_t i = 0; i < pParentObj->cmd.numOfTables; ++i) {
|
||||||
taosCacheRelease(tscMetaCache, (void**)&(pParentObj->cmd.pTableMetaList[i]), true);
|
char* name = pParentObj->cmd.pTableNameList[i];
|
||||||
|
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
pParentObj->cmd.parseFinished = false;
|
pParentObj->cmd.parseFinished = false;
|
||||||
pParentObj->subState.numOfRemain = numOfFailed;
|
pParentObj->subState.numOfRemain = numOfFailed;
|
||||||
|
|
||||||
tscResetSqlCmdObj(&pParentObj->cmd, false);
|
tscResetSqlCmdObj(&pParentObj->cmd);
|
||||||
|
|
||||||
// in case of insert, redo parsing the sql string and build new submit data block for two reasons:
|
// in case of insert, redo parsing the sql string and build new submit data block for two reasons:
|
||||||
// 1. the table Id(tid & uid) may have been update, the submit block needs to be updated accordingly.
|
// 1. the table Id(tid & uid) may have been update, the submit block needs to be updated accordingly.
|
||||||
|
@ -2264,7 +2265,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
pParentObj->res.code = code;
|
pParentObj->res.code = code;
|
||||||
tscQueueAsyncRes(pParentObj);
|
tscAsyncResultOnError(pParentObj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2288,7 +2289,7 @@ int32_t tscHandleInsertRetry(SSqlObj* pParent, SSqlObj* pSql) {
|
||||||
int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock);
|
int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock);
|
||||||
|
|
||||||
if ((pRes->code = code)!= TSDB_CODE_SUCCESS) {
|
if ((pRes->code = code)!= TSDB_CODE_SUCCESS) {
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return code; // here the pSql may have been released already.
|
return code; // here the pSql may have been released already.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2481,7 +2482,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
||||||
SSqlRes* pRes = &pSql->res;
|
SSqlRes* pRes = &pSql->res;
|
||||||
|
|
||||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2496,7 +2497,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
||||||
|
|
||||||
if (pRes->tsrow == NULL || pRes->buffer == NULL || pRes->length == NULL) {
|
if (pRes->tsrow == NULL || pRes->buffer == NULL || pRes->length == NULL) {
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2508,7 +2509,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
|
||||||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||||
(*pSql->fp)(pSql->param, pSql, pRes->numOfRows);
|
(*pSql->fp)(pSql->param, pSql, pRes->numOfRows);
|
||||||
} else {
|
} else {
|
||||||
tscQueueAsyncRes(pSql);
|
tscAsyncResultOnError(pSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,15 +31,20 @@
|
||||||
#include "tlocale.h"
|
#include "tlocale.h"
|
||||||
|
|
||||||
// global, not configurable
|
// global, not configurable
|
||||||
SCacheObj *tscMetaCache; // table meta cache
|
#define TSC_VAR_NOT_RELEASE 1
|
||||||
SHashObj *tscHashMap; // hash map to keep the global vgroup info
|
#define TSC_VAR_RELEASED 0
|
||||||
int tscObjRef = -1;
|
|
||||||
void *tscTmr;
|
|
||||||
void *tscQhandle;
|
|
||||||
void *tscCheckDiskUsageTmr;
|
|
||||||
int tscRefId = -1;
|
|
||||||
int tscNumOfObj = 0; // number of sqlObj in current process.
|
|
||||||
|
|
||||||
|
int32_t sentinel = TSC_VAR_NOT_RELEASE;
|
||||||
|
|
||||||
|
SHashObj *tscVgroupMap; // hash map to keep the global vgroup info
|
||||||
|
SHashObj *tscTableMetaInfo; // table meta info
|
||||||
|
int32_t tscObjRef = -1;
|
||||||
|
void *tscTmr;
|
||||||
|
void *tscQhandle;
|
||||||
|
int32_t tscRefId = -1;
|
||||||
|
int32_t tscNumOfObj = 0; // number of sqlObj in current process.
|
||||||
|
|
||||||
|
static void *tscCheckDiskUsageTmr;
|
||||||
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
||||||
|
|
||||||
void tscCheckDiskUsage(void *UNUSED_PARAM(para), void* UNUSED_PARAM(param)) {
|
void tscCheckDiskUsage(void *UNUSED_PARAM(para), void* UNUSED_PARAM(param)) {
|
||||||
|
@ -129,11 +134,11 @@ void taos_init_imp(void) {
|
||||||
taosTmrReset(tscCheckDiskUsage, 10, NULL, tscTmr, &tscCheckDiskUsageTmr);
|
taosTmrReset(tscCheckDiskUsage, 10, NULL, tscTmr, &tscCheckDiskUsageTmr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t refreshTime = 10; // 10 seconds by default
|
if (tscTableMetaInfo == NULL) {
|
||||||
if (tscMetaCache == NULL) {
|
|
||||||
tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, tscFreeTableMetaHelper, "tableMeta");
|
|
||||||
tscObjRef = taosOpenRef(40960, tscFreeRegisteredSqlObj);
|
tscObjRef = taosOpenRef(40960, tscFreeRegisteredSqlObj);
|
||||||
tscHashMap = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
tscVgroupMap = taosHashInit(256, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||||
|
tscTableMetaInfo = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||||
|
tscDebug("TableMeta:%p", tscTableMetaInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
tscRefId = taosOpenRef(200, tscCloseTscObj);
|
tscRefId = taosOpenRef(200, tscCloseTscObj);
|
||||||
|
@ -151,30 +156,38 @@ void taos_init() { pthread_once(&tscinit, taos_init_imp); }
|
||||||
void taos_cleanup(void) {
|
void taos_cleanup(void) {
|
||||||
tscDebug("start to cleanup client environment");
|
tscDebug("start to cleanup client environment");
|
||||||
|
|
||||||
void* m = tscMetaCache;
|
if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
|
||||||
if (m != NULL && atomic_val_compare_exchange_ptr(&tscMetaCache, m, 0) == m) {
|
return;
|
||||||
taosCacheCleanup(m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int refId = atomic_exchange_32(&tscObjRef, -1);
|
taosHashCleanup(tscTableMetaInfo);
|
||||||
if (refId != -1) {
|
tscTableMetaInfo = NULL;
|
||||||
taosCloseRef(refId);
|
|
||||||
}
|
|
||||||
|
|
||||||
m = tscQhandle;
|
taosHashCleanup(tscVgroupMap);
|
||||||
if (m != NULL && atomic_val_compare_exchange_ptr(&tscQhandle, m, 0) == m) {
|
tscVgroupMap = NULL;
|
||||||
taosCleanUpScheduler(m);
|
|
||||||
}
|
int32_t id = tscObjRef;
|
||||||
|
tscObjRef = -1;
|
||||||
|
taosCloseRef(id);
|
||||||
|
|
||||||
|
void* p = tscQhandle;
|
||||||
|
tscQhandle = NULL;
|
||||||
|
taosCleanUpScheduler(p);
|
||||||
|
|
||||||
|
id = tscRefId;
|
||||||
|
tscRefId = -1;
|
||||||
|
taosCloseRef(id);
|
||||||
|
|
||||||
taosCloseRef(tscRefId);
|
|
||||||
taosCleanupKeywordsTable();
|
taosCleanupKeywordsTable();
|
||||||
taosCloseLog();
|
taosCloseLog();
|
||||||
if (tscEmbedded == 0) rpcCleanup();
|
|
||||||
|
|
||||||
m = tscTmr;
|
if (tscEmbedded == 0) {
|
||||||
if (m != NULL && atomic_val_compare_exchange_ptr(&tscTmr, m, 0) == m) {
|
rpcCleanup();
|
||||||
taosTmrCleanUp(m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p = tscTmr;
|
||||||
|
tscTmr = NULL;
|
||||||
|
taosTmrCleanUp(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
|
static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "qAst.h"
|
#include "qAst.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tcache.h"
|
|
||||||
#include "tkey.h"
|
#include "tkey.h"
|
||||||
#include "tmd5.h"
|
#include "tmd5.h"
|
||||||
#include "tscLocalMerge.h"
|
#include "tscLocalMerge.h"
|
||||||
|
@ -31,7 +30,7 @@
|
||||||
#include "ttokendef.h"
|
#include "ttokendef.h"
|
||||||
|
|
||||||
static void freeQueryInfoImpl(SQueryInfo* pQueryInfo);
|
static void freeQueryInfoImpl(SQueryInfo* pQueryInfo);
|
||||||
static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool removeFromCache);
|
static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
SCond* tsGetSTableQueryCond(STagCond* pTagCond, uint64_t uid) {
|
SCond* tsGetSTableQueryCond(STagCond* pTagCond, uint64_t uid) {
|
||||||
if (pTagCond->pCond == NULL) {
|
if (pTagCond->pCond == NULL) {
|
||||||
|
@ -379,17 +378,16 @@ static void tscDestroyResPointerInfo(SSqlRes* pRes) {
|
||||||
pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free
|
pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeFromCache) {
|
void tscFreeQueryInfo(SSqlCmd* pCmd) {
|
||||||
if (pCmd == NULL || pCmd->numOfClause == 0) {
|
if (pCmd == NULL || pCmd->numOfClause == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pCmd->numOfClause; ++i) {
|
for (int32_t i = 0; i < pCmd->numOfClause; ++i) {
|
||||||
char* addr = (char*)pCmd - offsetof(SSqlObj, cmd);
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i);
|
||||||
|
|
||||||
freeQueryInfoImpl(pQueryInfo);
|
freeQueryInfoImpl(pQueryInfo);
|
||||||
clearAllTableMetaInfo(pQueryInfo, (const char*)addr, removeFromCache);
|
clearAllTableMetaInfo(pQueryInfo);
|
||||||
tfree(pQueryInfo);
|
tfree(pQueryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,7 +395,7 @@ void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeFromCache) {
|
||||||
tfree(pCmd->pQueryInfo);
|
tfree(pCmd->pQueryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscResetSqlCmdObj(SSqlCmd* pCmd, bool removeFromCache) {
|
void tscResetSqlCmdObj(SSqlCmd* pCmd) {
|
||||||
pCmd->command = 0;
|
pCmd->command = 0;
|
||||||
pCmd->numOfCols = 0;
|
pCmd->numOfCols = 0;
|
||||||
pCmd->count = 0;
|
pCmd->count = 0;
|
||||||
|
@ -407,17 +405,17 @@ void tscResetSqlCmdObj(SSqlCmd* pCmd, bool removeFromCache) {
|
||||||
pCmd->autoCreated = 0;
|
pCmd->autoCreated = 0;
|
||||||
|
|
||||||
for(int32_t i = 0; i < pCmd->numOfTables; ++i) {
|
for(int32_t i = 0; i < pCmd->numOfTables; ++i) {
|
||||||
if (pCmd->pTableMetaList && pCmd->pTableMetaList[i]) {
|
if (pCmd->pTableNameList && pCmd->pTableNameList[i]) {
|
||||||
taosCacheRelease(tscMetaCache, (void**)&(pCmd->pTableMetaList[i]), false);
|
tfree(pCmd->pTableNameList[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pCmd->numOfTables = 0;
|
pCmd->numOfTables = 0;
|
||||||
tfree(pCmd->pTableMetaList);
|
tfree(pCmd->pTableNameList);
|
||||||
|
|
||||||
pCmd->pTableBlockHashList = tscDestroyBlockHashTable(pCmd->pTableBlockHashList);
|
pCmd->pTableBlockHashList = tscDestroyBlockHashTable(pCmd->pTableBlockHashList);
|
||||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||||
tscFreeQueryInfo(pCmd, removeFromCache);
|
tscFreeQueryInfo(pCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscFreeSqlResult(SSqlObj* pSql) {
|
void tscFreeSqlResult(SSqlObj* pSql) {
|
||||||
|
@ -468,17 +466,6 @@ void tscFreeRegisteredSqlObj(void *pSql) {
|
||||||
tscDebug("%p free SqlObj, total in tscObj:%d, total:%d", pSql, num, total);
|
tscDebug("%p free SqlObj, total in tscObj:%d, total:%d", pSql, num, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscFreeTableMetaHelper(void *pTableMeta) {
|
|
||||||
STableMeta* p = (STableMeta*) pTableMeta;
|
|
||||||
|
|
||||||
int32_t numOfEps1 = p->corVgroupInfo.numOfEps;
|
|
||||||
assert(numOfEps1 >= 0 && numOfEps1 <= TSDB_MAX_REPLICA);
|
|
||||||
|
|
||||||
for(int32_t i = 0; i < numOfEps1; ++i) {
|
|
||||||
tfree(p->corVgroupInfo.epAddr[i].fqdn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tscFreeSqlObj(SSqlObj* pSql) {
|
void tscFreeSqlObj(SSqlObj* pSql) {
|
||||||
if (pSql == NULL || pSql->signature != pSql) {
|
if (pSql == NULL || pSql->signature != pSql) {
|
||||||
return;
|
return;
|
||||||
|
@ -506,7 +493,7 @@ void tscFreeSqlObj(SSqlObj* pSql) {
|
||||||
pSql->self = 0;
|
pSql->self = 0;
|
||||||
|
|
||||||
tscFreeSqlResult(pSql);
|
tscFreeSqlResult(pSql);
|
||||||
tscResetSqlCmdObj(pCmd, false);
|
tscResetSqlCmdObj(pCmd);
|
||||||
|
|
||||||
tfree(pCmd->tagData.data);
|
tfree(pCmd->tagData.data);
|
||||||
pCmd->tagData.dataLen = 0;
|
pCmd->tagData.dataLen = 0;
|
||||||
|
@ -529,7 +516,7 @@ void tscDestroyDataBlock(STableDataBlocks* pDataBlock) {
|
||||||
|
|
||||||
// free the refcount for metermeta
|
// free the refcount for metermeta
|
||||||
if (pDataBlock->pTableMeta != NULL) {
|
if (pDataBlock->pTableMeta != NULL) {
|
||||||
taosCacheRelease(tscMetaCache, (void**)&(pDataBlock->pTableMeta), false);
|
tfree(pDataBlock->pTableMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
tfree(pDataBlock);
|
tfree(pDataBlock);
|
||||||
|
@ -600,15 +587,15 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) {
|
||||||
|
|
||||||
// set the correct table meta object, the table meta has been locked in pDataBlocks, so it must be in the cache
|
// set the correct table meta object, the table meta has been locked in pDataBlocks, so it must be in the cache
|
||||||
if (pTableMetaInfo->pTableMeta != pDataBlock->pTableMeta) {
|
if (pTableMetaInfo->pTableMeta != pDataBlock->pTableMeta) {
|
||||||
tstrncpy(pTableMetaInfo->name, pDataBlock->tableId, sizeof(pTableMetaInfo->name));
|
tstrncpy(pTableMetaInfo->name, pDataBlock->tableName, sizeof(pTableMetaInfo->name));
|
||||||
|
|
||||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
if (pTableMetaInfo->pTableMeta != NULL) {
|
||||||
taosCacheRelease(tscMetaCache, (void**)&(pTableMetaInfo->pTableMeta), false);
|
tfree(pTableMetaInfo->pTableMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
pTableMetaInfo->pTableMeta = taosCacheTransfer(tscMetaCache, (void**)&pDataBlock->pTableMeta);
|
pTableMetaInfo->pTableMeta = tscTableMetaClone(pDataBlock->pTableMeta);
|
||||||
} else {
|
} else {
|
||||||
assert(strncmp(pTableMetaInfo->name, pDataBlock->tableId, tListLen(pDataBlock->tableId)) == 0);
|
assert(strncmp(pTableMetaInfo->name, pDataBlock->tableName, tListLen(pDataBlock->tableName)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -671,14 +658,10 @@ int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOff
|
||||||
dataBuf->size = startOffset;
|
dataBuf->size = startOffset;
|
||||||
dataBuf->tsSource = -1;
|
dataBuf->tsSource = -1;
|
||||||
|
|
||||||
tstrncpy(dataBuf->tableId, name, sizeof(dataBuf->tableId));
|
tstrncpy(dataBuf->tableName, name, sizeof(dataBuf->tableName));
|
||||||
|
|
||||||
/*
|
//Here we keep the tableMeta to avoid it to be remove by other threads.
|
||||||
* The table meta may be released since the table meta cache are completed clean by other thread
|
dataBuf->pTableMeta = tscTableMetaClone(pTableMeta);
|
||||||
* due to operation such as drop database. So here we add the reference count directly instead of invoke
|
|
||||||
* taosGetDataFromCache, which may return NULL value.
|
|
||||||
*/
|
|
||||||
dataBuf->pTableMeta = taosCacheAcquireByData(tscMetaCache, pTableMeta);
|
|
||||||
assert(initialSize > 0 && pTableMeta != NULL && dataBuf->pTableMeta != NULL);
|
assert(initialSize > 0 && pTableMeta != NULL && dataBuf->pTableMeta != NULL);
|
||||||
|
|
||||||
*dataBlocks = dataBuf;
|
*dataBlocks = dataBuf;
|
||||||
|
@ -784,15 +767,15 @@ static int32_t getRowExpandSize(STableMeta* pTableMeta) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void extractTableMeta(SSqlCmd* pCmd) {
|
static void extractTableNameList(SSqlCmd* pCmd) {
|
||||||
pCmd->numOfTables = (int32_t) taosHashGetSize(pCmd->pTableBlockHashList);
|
pCmd->numOfTables = (int32_t) taosHashGetSize(pCmd->pTableBlockHashList);
|
||||||
pCmd->pTableMetaList = calloc(pCmd->numOfTables, POINTER_BYTES);
|
pCmd->pTableNameList = calloc(pCmd->numOfTables, POINTER_BYTES);
|
||||||
|
|
||||||
STableDataBlocks **p1 = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
STableDataBlocks **p1 = taosHashIterate(pCmd->pTableBlockHashList, NULL);
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
while(p1) {
|
while(p1) {
|
||||||
STableDataBlocks* pBlocks = *p1;
|
STableDataBlocks* pBlocks = *p1;
|
||||||
pCmd->pTableMetaList[i++] = taosCacheTransfer(tscMetaCache, (void**) &pBlocks->pTableMeta);
|
pCmd->pTableNameList[i++] = strndup(pBlocks->tableName, TSDB_TABLE_FNAME_LEN);
|
||||||
p1 = taosHashIterate(pCmd->pTableBlockHashList, p1);
|
p1 = taosHashIterate(pCmd->pTableBlockHashList, p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,7 +798,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql) {
|
||||||
STableDataBlocks* dataBuf = NULL;
|
STableDataBlocks* dataBuf = NULL;
|
||||||
|
|
||||||
int32_t ret = tscGetDataBlockFromList(pVnodeDataBlockHashList, pOneTableBlock->vgId, TSDB_PAYLOAD_SIZE,
|
int32_t ret = tscGetDataBlockFromList(pVnodeDataBlockHashList, pOneTableBlock->vgId, TSDB_PAYLOAD_SIZE,
|
||||||
INSERT_HEAD_SIZE, 0, pOneTableBlock->tableId, pOneTableBlock->pTableMeta, &dataBuf, pVnodeDataBlockList);
|
INSERT_HEAD_SIZE, 0, pOneTableBlock->tableName, pOneTableBlock->pTableMeta, &dataBuf, pVnodeDataBlockList);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
tscError("%p failed to prepare the data block buffer for merging table data, code:%d", pSql, ret);
|
tscError("%p failed to prepare the data block buffer for merging table data, code:%d", pSql, ret);
|
||||||
taosHashCleanup(pVnodeDataBlockHashList);
|
taosHashCleanup(pVnodeDataBlockHashList);
|
||||||
|
@ -849,7 +832,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql) {
|
||||||
tscSortRemoveDataBlockDupRows(pOneTableBlock);
|
tscSortRemoveDataBlockDupRows(pOneTableBlock);
|
||||||
char* ekey = (char*)pBlocks->data + pOneTableBlock->rowSize*(pBlocks->numOfRows-1);
|
char* ekey = (char*)pBlocks->data + pOneTableBlock->rowSize*(pBlocks->numOfRows-1);
|
||||||
|
|
||||||
tscDebug("%p tableId:%s, sid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql, pOneTableBlock->tableId,
|
tscDebug("%p name:%s, sid:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql, pOneTableBlock->tableName,
|
||||||
pBlocks->tid, pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->data), GET_INT64_VAL(ekey));
|
pBlocks->tid, pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->data), GET_INT64_VAL(ekey));
|
||||||
|
|
||||||
int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + expandSize) + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + expandSize) + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta);
|
||||||
|
@ -879,7 +862,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql) {
|
||||||
pOneTableBlock = *p;
|
pOneTableBlock = *p;
|
||||||
}
|
}
|
||||||
|
|
||||||
extractTableMeta(pCmd);
|
extractTableNameList(pCmd);
|
||||||
|
|
||||||
// free the table data blocks;
|
// free the table data blocks;
|
||||||
pCmd->pDataBlocks = pVnodeDataBlockList;
|
pCmd->pDataBlocks = pVnodeDataBlockList;
|
||||||
|
@ -900,6 +883,7 @@ void tscCloseTscObj(void *param) {
|
||||||
rpcClose(pObj->pDnodeConn);
|
rpcClose(pObj->pDnodeConn);
|
||||||
pObj->pDnodeConn = NULL;
|
pObj->pDnodeConn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tfree(pObj->tscCorMgmtEpSet);
|
tfree(pObj->tscCorMgmtEpSet);
|
||||||
pthread_mutex_destroy(&pObj->mutex);
|
pthread_mutex_destroy(&pObj->mutex);
|
||||||
|
|
||||||
|
@ -1528,6 +1512,7 @@ int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dest->tbnameCond.uid = src->tbnameCond.uid;
|
dest->tbnameCond.uid = src->tbnameCond.uid;
|
||||||
|
dest->tbnameCond.len = src->tbnameCond.len;
|
||||||
|
|
||||||
memcpy(&dest->joinInfo, &src->joinInfo, sizeof(SJoinInfo));
|
memcpy(&dest->joinInfo, &src->joinInfo, sizeof(SJoinInfo));
|
||||||
dest->relType = src->relType;
|
dest->relType = src->relType;
|
||||||
|
@ -1823,14 +1808,12 @@ SArray* tscVgroupTableInfoClone(SArray* pVgroupTables) {
|
||||||
return pa;
|
return pa;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool removeFromCache) {
|
void clearAllTableMetaInfo(SQueryInfo* pQueryInfo) {
|
||||||
tscDebug("%p unref %d tables in the tableMeta cache", address, pQueryInfo->numOfTables);
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
tscFreeVgroupTableInfo(pTableMetaInfo->pVgroupTables);
|
tscFreeVgroupTableInfo(pTableMetaInfo->pVgroupTables);
|
||||||
tscClearTableMetaInfo(pTableMetaInfo, removeFromCache);
|
tscClearTableMetaInfo(pTableMetaInfo);
|
||||||
free(pTableMetaInfo);
|
free(pTableMetaInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1884,14 +1867,12 @@ STableMetaInfo* tscAddEmptyMetaInfo(SQueryInfo* pQueryInfo) {
|
||||||
return tscAddTableMetaInfo(pQueryInfo, NULL, NULL, NULL, NULL, NULL);
|
return tscAddTableMetaInfo(pQueryInfo, NULL, NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache) {
|
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo) {
|
||||||
if (pTableMetaInfo == NULL) {
|
if (pTableMetaInfo == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
tfree(pTableMetaInfo->pTableMeta);
|
||||||
taosCacheRelease(tscMetaCache, (void**)&(pTableMetaInfo->pTableMeta), removeFromCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);
|
pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList);
|
||||||
tscColumnListDestroy(pTableMetaInfo->tagColList);
|
tscColumnListDestroy(pTableMetaInfo->tagColList);
|
||||||
|
@ -2015,7 +1996,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
||||||
|
|
||||||
pNew->pTscObj = pSql->pTscObj;
|
pNew->pTscObj = pSql->pTscObj;
|
||||||
pNew->signature = pNew;
|
pNew->signature = pNew;
|
||||||
pNew->sqlstr = NULL;
|
pNew->sqlstr = strdup(pSql->sqlstr);
|
||||||
|
|
||||||
SSqlCmd* pnCmd = &pNew->cmd;
|
SSqlCmd* pnCmd = &pNew->cmd;
|
||||||
memcpy(pnCmd, pCmd, sizeof(SSqlCmd));
|
memcpy(pnCmd, pCmd, sizeof(SSqlCmd));
|
||||||
|
@ -2031,7 +2012,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
||||||
|
|
||||||
pnCmd->numOfTables = 0;
|
pnCmd->numOfTables = 0;
|
||||||
pnCmd->parseFinished = 1;
|
pnCmd->parseFinished = 1;
|
||||||
pnCmd->pTableMetaList = NULL;
|
pnCmd->pTableNameList = NULL;
|
||||||
pnCmd->pTableBlockHashList = NULL;
|
pnCmd->pTableBlockHashList = NULL;
|
||||||
|
|
||||||
if (tscAddSubqueryInfo(pnCmd) != TSDB_CODE_SUCCESS) {
|
if (tscAddSubqueryInfo(pnCmd) != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -2113,8 +2094,8 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
||||||
char* name = pTableMetaInfo->name;
|
char* name = pTableMetaInfo->name;
|
||||||
STableMetaInfo* pFinalInfo = NULL;
|
STableMetaInfo* pFinalInfo = NULL;
|
||||||
|
|
||||||
if (pPrevSql == NULL) { // get by name may failed due to the cache cleanup
|
if (pPrevSql == NULL) {
|
||||||
STableMeta* pTableMeta = taosCacheAcquireByData(tscMetaCache, pTableMetaInfo->pTableMeta);
|
STableMeta* pTableMeta = tscTableMetaClone(pTableMetaInfo->pTableMeta);
|
||||||
assert(pTableMeta != NULL);
|
assert(pTableMeta != NULL);
|
||||||
|
|
||||||
pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pTableMeta, pTableMetaInfo->vgroupList,
|
pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pTableMeta, pTableMetaInfo->vgroupList,
|
||||||
|
@ -2122,15 +2103,15 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
||||||
} else { // transfer the ownership of pTableMeta to the newly create sql object.
|
} else { // transfer the ownership of pTableMeta to the newly create sql object.
|
||||||
STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex, 0);
|
STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex, 0);
|
||||||
|
|
||||||
STableMeta* pPrevTableMeta = taosCacheTransfer(tscMetaCache, (void**)&pPrevInfo->pTableMeta);
|
STableMeta* pPrevTableMeta = tscTableMetaClone(pPrevInfo->pTableMeta);
|
||||||
|
|
||||||
SVgroupsInfo* pVgroupsInfo = pPrevInfo->vgroupList;
|
SVgroupsInfo* pVgroupsInfo = pPrevInfo->vgroupList;
|
||||||
pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pPrevTableMeta, pVgroupsInfo, pTableMetaInfo->tagColList,
|
pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pPrevTableMeta, pVgroupsInfo, pTableMetaInfo->tagColList,
|
||||||
pTableMetaInfo->pVgroupTables);
|
pTableMetaInfo->pVgroupTables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this case cannot be happened
|
||||||
if (pFinalInfo->pTableMeta == NULL) {
|
if (pFinalInfo->pTableMeta == NULL) {
|
||||||
tscError("%p new subquery failed since no tableMeta in cache, name:%s", pSql, name);
|
tscError("%p new subquery failed since no tableMeta, name:%s", pSql, name);
|
||||||
|
|
||||||
if (pPrevSql != NULL) { // pass the previous error to client
|
if (pPrevSql != NULL) { // pass the previous error to client
|
||||||
assert(pPrevSql->res.code != TSDB_CODE_SUCCESS);
|
assert(pPrevSql->res.code != TSDB_CODE_SUCCESS);
|
||||||
|
@ -2557,6 +2538,7 @@ void* tscVgroupInfoClear(SVgroupsInfo *vgroupList) {
|
||||||
for(int32_t j = 0; j < pVgroupInfo->numOfEps; ++j) {
|
for(int32_t j = 0; j < pVgroupInfo->numOfEps; ++j) {
|
||||||
tfree(pVgroupInfo->epAddr[j].fqdn);
|
tfree(pVgroupInfo->epAddr[j].fqdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int32_t j = pVgroupInfo->numOfEps; j < TSDB_MAX_REPLICA; j++) {
|
for(int32_t j = pVgroupInfo->numOfEps; j < TSDB_MAX_REPLICA; j++) {
|
||||||
assert( pVgroupInfo->epAddr[j].fqdn == NULL );
|
assert( pVgroupInfo->epAddr[j].fqdn == NULL );
|
||||||
}
|
}
|
||||||
|
@ -2610,3 +2592,87 @@ int32_t copyTagData(STagData* dst, const STagData* src) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STableMeta* createSuperTableMeta(STableMetaMsg* pChild) {
|
||||||
|
assert(pChild != NULL);
|
||||||
|
int32_t total = pChild->numOfColumns + pChild->numOfTags;
|
||||||
|
|
||||||
|
STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + sizeof(SSchema) * total);
|
||||||
|
pTableMeta->tableType = TSDB_SUPER_TABLE;
|
||||||
|
pTableMeta->tableInfo.numOfTags = pChild->numOfTags;
|
||||||
|
pTableMeta->tableInfo.numOfColumns = pChild->numOfColumns;
|
||||||
|
pTableMeta->tableInfo.precision = pChild->precision;
|
||||||
|
|
||||||
|
pTableMeta->id.tid = 0;
|
||||||
|
pTableMeta->id.uid = pChild->suid;
|
||||||
|
pTableMeta->tversion = pChild->tversion;
|
||||||
|
pTableMeta->sversion = pChild->sversion;
|
||||||
|
|
||||||
|
memcpy(pTableMeta->schema, pChild->schema, sizeof(SSchema) * total);
|
||||||
|
|
||||||
|
int32_t num = pTableMeta->tableInfo.numOfColumns;
|
||||||
|
for(int32_t i = 0; i < num; ++i) {
|
||||||
|
pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pTableMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tscGetTableMetaSize(STableMeta* pTableMeta) {
|
||||||
|
assert(pTableMeta != NULL);
|
||||||
|
|
||||||
|
int32_t totalCols = pTableMeta->tableInfo.numOfColumns + pTableMeta->tableInfo.numOfTags;
|
||||||
|
return sizeof(STableMeta) + totalCols * sizeof(SSchema);
|
||||||
|
}
|
||||||
|
|
||||||
|
CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta) {
|
||||||
|
assert(pTableMeta != NULL);
|
||||||
|
|
||||||
|
CChildTableMeta* cMeta = calloc(1, sizeof(CChildTableMeta));
|
||||||
|
cMeta->tableType = TSDB_CHILD_TABLE;
|
||||||
|
cMeta->vgId = pTableMeta->vgId;
|
||||||
|
cMeta->id = pTableMeta->id;
|
||||||
|
tstrncpy(cMeta->sTableName, pTableMeta->sTableName, TSDB_TABLE_FNAME_LEN);
|
||||||
|
|
||||||
|
return cMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name) {
|
||||||
|
assert(pChild != NULL);
|
||||||
|
|
||||||
|
uint32_t size = tscGetTableMetaMaxSize();
|
||||||
|
STableMeta* p = calloc(1, size);
|
||||||
|
|
||||||
|
taosHashGetClone(tscTableMetaInfo, pChild->sTableName, strnlen(pChild->sTableName, TSDB_TABLE_FNAME_LEN), NULL, p, -1);
|
||||||
|
if (p->id.uid > 0) { // tableMeta exists, build child table meta and return
|
||||||
|
pChild->sversion = p->sversion;
|
||||||
|
pChild->tversion = p->tversion;
|
||||||
|
|
||||||
|
memcpy(&pChild->tableInfo, &p->tableInfo, sizeof(STableInfo));
|
||||||
|
int32_t total = pChild->tableInfo.numOfColumns + pChild->tableInfo.numOfTags;
|
||||||
|
|
||||||
|
memcpy(pChild->schema, p->schema, sizeof(SSchema) *total);
|
||||||
|
|
||||||
|
tfree(p);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
} else { // super table has been removed, current tableMeta is also expired. remove it here
|
||||||
|
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||||
|
|
||||||
|
tfree(p);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tscGetTableMetaMaxSize() {
|
||||||
|
return sizeof(STableMeta) + TSDB_MAX_COLUMNS * sizeof(SSchema);
|
||||||
|
}
|
||||||
|
|
||||||
|
STableMeta* tscTableMetaClone(STableMeta* pTableMeta) {
|
||||||
|
assert(pTableMeta != NULL);
|
||||||
|
uint32_t size = tscGetTableMetaSize(pTableMeta);
|
||||||
|
STableMeta* p = calloc(1, size);
|
||||||
|
memcpy(p, pTableMeta, size);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,19 @@ void dnodeReprocessMWriteMsg(void *pMsg) {
|
||||||
dDebug("msg:%p, app:%p type:%s is redirected for mnode not running, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
dDebug("msg:%p, app:%p type:%s is redirected for mnode not running, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
||||||
taosMsg[pWrite->rpcMsg.msgType], pWrite->retry);
|
taosMsg[pWrite->rpcMsg.msgType], pWrite->retry);
|
||||||
|
|
||||||
dnodeSendRedirectMsg(pMsg, true);
|
if (pWrite->pBatchMasterMsg) {
|
||||||
|
++pWrite->pBatchMasterMsg->received;
|
||||||
|
if (pWrite->pBatchMasterMsg->successed + pWrite->pBatchMasterMsg->received
|
||||||
|
>= pWrite->pBatchMasterMsg->expected) {
|
||||||
|
dnodeSendRedirectMsg(&pWrite->rpcMsg, true);
|
||||||
|
dnodeFreeMWriteMsg(pWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeDestroySubMsg(pWrite);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dnodeSendRedirectMsg(&pWrite->rpcMsg, true);
|
||||||
dnodeFreeMWriteMsg(pWrite);
|
dnodeFreeMWriteMsg(pWrite);
|
||||||
} else {
|
} else {
|
||||||
dDebug("msg:%p, app:%p type:%s is reput into mwrite queue:%p, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
dDebug("msg:%p, app:%p type:%s is reput into mwrite queue:%p, retry times:%d", pWrite, pWrite->rpcMsg.ahandle,
|
||||||
|
|
|
@ -73,7 +73,8 @@ static int32_t dnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
|
||||||
|
|
||||||
if (*numOfVnodes >= TSDB_MAX_VNODES) {
|
if (*numOfVnodes >= TSDB_MAX_VNODES) {
|
||||||
dError("vgId:%d, too many vnode directory in disk, exist:%d max:%d", vnode, *numOfVnodes, TSDB_MAX_VNODES);
|
dError("vgId:%d, too many vnode directory in disk, exist:%d max:%d", vnode, *numOfVnodes, TSDB_MAX_VNODES);
|
||||||
continue;
|
closedir(dir);
|
||||||
|
return TSDB_CODE_DND_TOO_MANY_VNODES;
|
||||||
} else {
|
} else {
|
||||||
vnodeList[*numOfVnodes - 1] = vnode;
|
vnodeList[*numOfVnodes - 1] = vnode;
|
||||||
}
|
}
|
||||||
|
@ -288,4 +289,4 @@ void dnodeSendStatusMsgToMnode() {
|
||||||
dInfo("force send status msg to mnode");
|
dInfo("force send status msg to mnode");
|
||||||
taosTmrReset(dnodeSendStatusMsg, 3, NULL, tsDnodeTmr, &tsStatusTimer);
|
taosTmrReset(dnodeSendStatusMsg, 3, NULL, tsDnodeTmr, &tsStatusTimer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,11 +42,12 @@ typedef struct SMnodeMsg {
|
||||||
struct SVgObj * pVgroup;
|
struct SVgObj * pVgroup;
|
||||||
struct STableObj *pTable;
|
struct STableObj *pTable;
|
||||||
struct SSTableObj*pSTable;
|
struct SSTableObj*pSTable;
|
||||||
|
struct SMnodeMsg *pBatchMasterMsg;
|
||||||
SMnodeRsp rpcRsp;
|
SMnodeRsp rpcRsp;
|
||||||
int8_t received;
|
int16_t received;
|
||||||
int8_t successed;
|
int16_t successed;
|
||||||
int8_t expected;
|
int16_t expected;
|
||||||
int8_t retry;
|
int16_t retry;
|
||||||
int32_t incomingTs;
|
int32_t incomingTs;
|
||||||
int32_t code;
|
int32_t code;
|
||||||
void * pObj;
|
void * pObj;
|
||||||
|
@ -57,6 +58,7 @@ typedef struct SMnodeMsg {
|
||||||
void * mnodeCreateMsg(SRpcMsg *pRpcMsg);
|
void * mnodeCreateMsg(SRpcMsg *pRpcMsg);
|
||||||
int32_t mnodeInitMsg(SMnodeMsg *pMsg);
|
int32_t mnodeInitMsg(SMnodeMsg *pMsg);
|
||||||
void mnodeCleanupMsg(SMnodeMsg *pMsg);
|
void mnodeCleanupMsg(SMnodeMsg *pMsg);
|
||||||
|
void mnodeDestroySubMsg(SMnodeMsg *pSubMsg);
|
||||||
|
|
||||||
int32_t mnodeInitSystem();
|
int32_t mnodeInitSystem();
|
||||||
int32_t mnodeStartSystem();
|
int32_t mnodeStartSystem();
|
||||||
|
|
|
@ -194,6 +194,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_DND_OUT_OF_MEMORY, 0, 0x0401, "Dnode out
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_NO_WRITE_ACCESS, 0, 0x0402, "No permission for disk files in dnode")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_NO_WRITE_ACCESS, 0, 0x0402, "No permission for disk files in dnode")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_INVALID_MSG_LEN, 0, 0x0403, "Invalid message length")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_INVALID_MSG_LEN, 0, 0x0403, "Invalid message length")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_ACTION_IN_PROGRESS, 0, 0x0404, "Action in progress")
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_ACTION_IN_PROGRESS, 0, 0x0404, "Action in progress")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_DND_TOO_MANY_VNODES, 0, 0x0405, "Too many vnode directories")
|
||||||
|
|
||||||
// vnode
|
// vnode
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_ACTION_IN_PROGRESS, 0, 0x0500, "Action in progress")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_ACTION_IN_PROGRESS, 0, 0x0500, "Action in progress")
|
||||||
|
|
|
@ -476,6 +476,7 @@ typedef struct {
|
||||||
int16_t numOfCols; // the number of columns will be load from vnode
|
int16_t numOfCols; // the number of columns will be load from vnode
|
||||||
SInterval interval;
|
SInterval interval;
|
||||||
uint16_t tagCondLen; // tag length in current query
|
uint16_t tagCondLen; // tag length in current query
|
||||||
|
uint32_t tbnameCondLen; // table name filter condition string length
|
||||||
int16_t numOfGroupCols; // num of group by columns
|
int16_t numOfGroupCols; // num of group by columns
|
||||||
int16_t orderByIdx;
|
int16_t orderByIdx;
|
||||||
int16_t orderType; // used in group by xx order by xxx
|
int16_t orderType; // used in group by xx order by xxx
|
||||||
|
@ -494,6 +495,7 @@ typedef struct {
|
||||||
int32_t tsNumOfBlocks; // ts comp block numbers
|
int32_t tsNumOfBlocks; // ts comp block numbers
|
||||||
int32_t tsOrder; // ts comp block order
|
int32_t tsOrder; // ts comp block order
|
||||||
int32_t numOfTags; // number of tags columns involved
|
int32_t numOfTags; // number of tags columns involved
|
||||||
|
int32_t sqlstrLen; // sql query string
|
||||||
SColumnInfo colList[];
|
SColumnInfo colList[];
|
||||||
} SQueryTableMsg;
|
} SQueryTableMsg;
|
||||||
|
|
||||||
|
@ -725,7 +727,6 @@ typedef struct {
|
||||||
typedef struct STableMetaMsg {
|
typedef struct STableMetaMsg {
|
||||||
int32_t contLen;
|
int32_t contLen;
|
||||||
char tableId[TSDB_TABLE_FNAME_LEN]; // table id
|
char tableId[TSDB_TABLE_FNAME_LEN]; // table id
|
||||||
char sTableId[TSDB_TABLE_FNAME_LEN];
|
|
||||||
uint8_t numOfTags;
|
uint8_t numOfTags;
|
||||||
uint8_t precision;
|
uint8_t precision;
|
||||||
uint8_t tableType;
|
uint8_t tableType;
|
||||||
|
@ -735,6 +736,9 @@ typedef struct STableMetaMsg {
|
||||||
int32_t tid;
|
int32_t tid;
|
||||||
uint64_t uid;
|
uint64_t uid;
|
||||||
SVgroupMsg vgroup;
|
SVgroupMsg vgroup;
|
||||||
|
|
||||||
|
char sTableName[TSDB_TABLE_FNAME_LEN];
|
||||||
|
uint64_t suid;
|
||||||
SSchema schema[];
|
SSchema schema[];
|
||||||
} STableMetaMsg;
|
} STableMetaMsg;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
#include "tdataformat.h"
|
#include "tdataformat.h"
|
||||||
#include "tgrant.h"
|
#include "tgrant.h"
|
||||||
|
#include "tqueue.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "mnode.h"
|
#include "mnode.h"
|
||||||
#include "dnode.h"
|
#include "dnode.h"
|
||||||
|
@ -720,6 +721,133 @@ static void mnodeExtractTableName(char* tableId, char* name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SMnodeMsg *mnodeCreateSubMsg(SMnodeMsg *pBatchMasterMsg, int32_t contSize) {
|
||||||
|
SMnodeMsg *pSubMsg = taosAllocateQitem(sizeof(*pBatchMasterMsg) + contSize);
|
||||||
|
*pSubMsg = *pBatchMasterMsg;
|
||||||
|
|
||||||
|
//pSubMsg->pCont = (char *) pSubMsg + sizeof(SMnodeMsg);
|
||||||
|
pSubMsg->rpcMsg.pCont = pSubMsg->pCont;
|
||||||
|
pSubMsg->successed = 0;
|
||||||
|
pSubMsg->expected = 0;
|
||||||
|
SCMCreateTableMsg *pCM = pSubMsg->rpcMsg.pCont;
|
||||||
|
pCM->numOfTables = htonl(1);
|
||||||
|
pCM->contLen = htonl(contSize);
|
||||||
|
|
||||||
|
return pSubMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mnodeDestroySubMsg(SMnodeMsg *pSubMsg) {
|
||||||
|
if (pSubMsg) {
|
||||||
|
// pUser is retained in batch master msg
|
||||||
|
if (pSubMsg->pDb) mnodeDecDbRef(pSubMsg->pDb);
|
||||||
|
if (pSubMsg->pVgroup) mnodeDecVgroupRef(pSubMsg->pVgroup);
|
||||||
|
if (pSubMsg->pTable) mnodeDecTableRef(pSubMsg->pTable);
|
||||||
|
if (pSubMsg->pSTable) mnodeDecTableRef(pSubMsg->pSTable);
|
||||||
|
if (pSubMsg->pAcct) mnodeDecAcctRef(pSubMsg->pAcct);
|
||||||
|
if (pSubMsg->pDnode) mnodeDecDnodeRef(pSubMsg->pDnode);
|
||||||
|
|
||||||
|
taosFreeQitem(pSubMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeValidateCreateTableMsg(SCreateTableMsg *pCreateTable, SMnodeMsg *pMsg) {
|
||||||
|
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pCreateTable->db);
|
||||||
|
if (pMsg->pDb == NULL) {
|
||||||
|
mError("msg:%p, app:%p table:%s, failed to create, db not selected", pMsg, pMsg->rpcMsg.ahandle, pCreateTable->tableId);
|
||||||
|
return TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
||||||
|
mError("db:%s, status:%d, in dropping", pMsg->pDb->name, pMsg->pDb->status);
|
||||||
|
return TSDB_CODE_MND_DB_IN_DROPPING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pCreateTable->tableId);
|
||||||
|
if (pMsg->pTable != NULL && pMsg->retry == 0) {
|
||||||
|
if (pCreateTable->getMeta) {
|
||||||
|
mDebug("msg:%p, app:%p table:%s, continue to get meta", pMsg, pMsg->rpcMsg.ahandle, pCreateTable->tableId);
|
||||||
|
return mnodeGetChildTableMeta(pMsg);
|
||||||
|
} else if (pCreateTable->igExists) {
|
||||||
|
mDebug("msg:%p, app:%p table:%s, is already exist", pMsg, pMsg->rpcMsg.ahandle, pCreateTable->tableId);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
} else {
|
||||||
|
mError("msg:%p, app:%p table:%s, failed to create, table already exist", pMsg, pMsg->rpcMsg.ahandle,
|
||||||
|
pCreateTable->tableId);
|
||||||
|
return TSDB_CODE_MND_TABLE_ALREADY_EXIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCreateTable->numOfTags != 0) {
|
||||||
|
mDebug("msg:%p, app:%p table:%s, create stable msg is received from thandle:%p", pMsg, pMsg->rpcMsg.ahandle,
|
||||||
|
pCreateTable->tableId, pMsg->rpcMsg.handle);
|
||||||
|
return mnodeProcessCreateSuperTableMsg(pMsg);
|
||||||
|
} else {
|
||||||
|
mDebug("msg:%p, app:%p table:%s, create ctable msg is received from thandle:%p", pMsg, pMsg->rpcMsg.ahandle,
|
||||||
|
pCreateTable->tableId, pMsg->rpcMsg.handle);
|
||||||
|
return mnodeProcessCreateChildTableMsg(pMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeProcessBatchCreateTableMsg(SMnodeMsg *pMsg) {
|
||||||
|
if (pMsg->pBatchMasterMsg == NULL) { // batch master first round
|
||||||
|
pMsg->pBatchMasterMsg = pMsg;
|
||||||
|
|
||||||
|
SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont;
|
||||||
|
int32_t numOfTables = htonl(pCreate->numOfTables);
|
||||||
|
int32_t contentLen = htonl(pCreate->contLen);
|
||||||
|
pMsg->expected = numOfTables;
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SCreateTableMsg *pCreateTable = (SCreateTableMsg*) ((char*) pCreate + sizeof(SCMCreateTableMsg));
|
||||||
|
for (SCreateTableMsg *p = pCreateTable; p < (SCreateTableMsg *) ((char *) pCreate + contentLen); p = (SCreateTableMsg *) ((char *) p + htonl(p->len))) {
|
||||||
|
SMnodeMsg *pSubMsg = mnodeCreateSubMsg(pMsg, sizeof(SCMCreateTableMsg) + htonl(p->len));
|
||||||
|
memcpy(pSubMsg->pCont + sizeof(SCMCreateTableMsg), p, htonl(p->len));
|
||||||
|
code = mnodeValidateCreateTableMsg(p, pSubMsg);
|
||||||
|
|
||||||
|
if (code == TSDB_CODE_SUCCESS || code == TSDB_CODE_MND_TABLE_ALREADY_EXIST) {
|
||||||
|
++pSubMsg->pBatchMasterMsg->successed;
|
||||||
|
mnodeDestroySubMsg(pSubMsg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||||
|
mnodeDestroySubMsg(pSubMsg);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMsg->successed >= pMsg->expected) {
|
||||||
|
return code;
|
||||||
|
} else {
|
||||||
|
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pMsg->pBatchMasterMsg != pMsg) { // batch sub replay
|
||||||
|
SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont;
|
||||||
|
SCreateTableMsg *pCreateTable = (SCreateTableMsg*) ((char*) pCreate + sizeof(SCMCreateTableMsg));
|
||||||
|
int32_t code = mnodeValidateCreateTableMsg(pCreateTable, pMsg);
|
||||||
|
if (code == TSDB_CODE_SUCCESS || code == TSDB_CODE_MND_TABLE_ALREADY_EXIST) {
|
||||||
|
++pMsg->pBatchMasterMsg->successed;
|
||||||
|
mnodeDestroySubMsg(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||||
|
mnodeDestroySubMsg(pMsg);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received
|
||||||
|
>= pMsg->pBatchMasterMsg->expected) {
|
||||||
|
return code;
|
||||||
|
} else {
|
||||||
|
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
} else { // batch master replay, reprocess the whole batch
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t mnodeProcessCreateTableMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessCreateTableMsg(SMnodeMsg *pMsg) {
|
||||||
SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont;
|
SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont;
|
||||||
|
|
||||||
|
@ -729,6 +857,11 @@ static int32_t mnodeProcessCreateTableMsg(SMnodeMsg *pMsg) {
|
||||||
// todo return error
|
// todo return error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// batch master msg first round or reprocessing and batch sub msg reprocessing
|
||||||
|
if (numOfTables > 1 || pMsg->pBatchMasterMsg != NULL) {
|
||||||
|
return mnodeProcessBatchCreateTableMsg(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
SCreateTableMsg *p = (SCreateTableMsg*)((char*) pCreate + sizeof(SCMCreateTableMsg));
|
SCreateTableMsg *p = (SCreateTableMsg*)((char*) pCreate + sizeof(SCMCreateTableMsg));
|
||||||
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(p->db);
|
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(p->db);
|
||||||
if (pMsg->pDb == NULL) {
|
if (pMsg->pDb == NULL) {
|
||||||
|
@ -1737,6 +1870,18 @@ static int32_t mnodeDoCreateChildTableCb(SMnodeMsg *pMsg, int32_t code) {
|
||||||
mDebug("msg:%p, app:%p table:%s, created in dnode, thandle:%p", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId,
|
mDebug("msg:%p, app:%p table:%s, created in dnode, thandle:%p", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId,
|
||||||
pMsg->rpcMsg.handle);
|
pMsg->rpcMsg.handle);
|
||||||
|
|
||||||
|
if (pMsg->pBatchMasterMsg) {
|
||||||
|
++pMsg->pBatchMasterMsg->successed;
|
||||||
|
if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received
|
||||||
|
>= pMsg->pBatchMasterMsg->expected) {
|
||||||
|
dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeDestroySubMsg(pMsg);
|
||||||
|
|
||||||
|
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
dnodeSendRpcMWriteRsp(pMsg, TSDB_CODE_SUCCESS);
|
dnodeSendRpcMWriteRsp(pMsg, TSDB_CODE_SUCCESS);
|
||||||
}
|
}
|
||||||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
|
@ -2171,11 +2316,12 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) {
|
||||||
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_FNAME_LEN);
|
tstrncpy(pMeta->tableId, pTable->info.tableId, TSDB_TABLE_FNAME_LEN);
|
||||||
if (pTable->superTable != NULL) {
|
|
||||||
tstrncpy(pMeta->sTableId, pTable->superTable->info.tableId, TSDB_TABLE_FNAME_LEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pTable->info.type == TSDB_CHILD_TABLE && pTable->superTable != NULL) {
|
if (pTable->info.type == TSDB_CHILD_TABLE) {
|
||||||
|
assert(pTable->superTable != NULL);
|
||||||
|
tstrncpy(pMeta->sTableName, pTable->superTable->info.tableId, TSDB_TABLE_FNAME_LEN);
|
||||||
|
|
||||||
|
pMeta->suid = pTable->superTable->uid;
|
||||||
pMeta->sversion = htons(pTable->superTable->sversion);
|
pMeta->sversion = htons(pTable->superTable->sversion);
|
||||||
pMeta->tversion = htons(pTable->superTable->tversion);
|
pMeta->tversion = htons(pTable->superTable->tversion);
|
||||||
pMeta->numOfTags = (int8_t)pTable->superTable->numOfTags;
|
pMeta->numOfTags = (int8_t)pTable->superTable->numOfTags;
|
||||||
|
@ -2477,6 +2623,19 @@ static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg) {
|
||||||
|
|
||||||
mnodeSendDropChildTableMsg(pMsg, false);
|
mnodeSendDropChildTableMsg(pMsg, false);
|
||||||
rpcMsg->code = TSDB_CODE_SUCCESS;
|
rpcMsg->code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
if (pMsg->pBatchMasterMsg) {
|
||||||
|
++pMsg->pBatchMasterMsg->successed;
|
||||||
|
if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received
|
||||||
|
>= pMsg->pBatchMasterMsg->expected) {
|
||||||
|
dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, rpcMsg->code);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeDestroySubMsg(pMsg);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dnodeSendRpcMWriteRsp(pMsg, rpcMsg->code);
|
dnodeSendRpcMWriteRsp(pMsg, rpcMsg->code);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2494,6 +2653,19 @@ static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg) {
|
||||||
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||||
pMsg->pTable = NULL;
|
pMsg->pTable = NULL;
|
||||||
mnodeDestroyChildTable(pTable);
|
mnodeDestroyChildTable(pTable);
|
||||||
|
|
||||||
|
if (pMsg->pBatchMasterMsg) {
|
||||||
|
++pMsg->pBatchMasterMsg->received;
|
||||||
|
if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received
|
||||||
|
>= pMsg->pBatchMasterMsg->expected) {
|
||||||
|
dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeDestroySubMsg(pMsg);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dnodeSendRpcMWriteRsp(pMsg, code);
|
dnodeSendRpcMWriteRsp(pMsg, code);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2519,6 +2691,19 @@ static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg) {
|
||||||
//Avoid retry again in client
|
//Avoid retry again in client
|
||||||
rpcMsg->code = TSDB_CODE_MND_VGROUP_NOT_READY;
|
rpcMsg->code = TSDB_CODE_MND_VGROUP_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pMsg->pBatchMasterMsg) {
|
||||||
|
++pMsg->pBatchMasterMsg->received;
|
||||||
|
if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received
|
||||||
|
>= pMsg->pBatchMasterMsg->expected) {
|
||||||
|
dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, rpcMsg->code);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeDestroySubMsg(pMsg);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dnodeSendRpcMWriteRsp(pMsg, rpcMsg->code);
|
dnodeSendRpcMWriteRsp(pMsg, rpcMsg->code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,9 +50,16 @@ static void httpSendErrorRespImp(HttpContext *pContext, int32_t httpCode, char *
|
||||||
char head[512] = {0};
|
char head[512] = {0};
|
||||||
char body[512] = {0};
|
char body[512] = {0};
|
||||||
|
|
||||||
|
int8_t httpVersion = 0;
|
||||||
|
int8_t keepAlive = 0;
|
||||||
|
if (pContext->parser != NULL) {
|
||||||
|
httpVersion = pContext->parser->httpVersion;
|
||||||
|
keepAlive = pContext->parser->keepAlive;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_ERROR], errNo, desc);
|
int32_t bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_ERROR], errNo, desc);
|
||||||
int32_t headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_ERROR], httpVersionStr[pContext->parser->httpVersion],
|
int32_t headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_ERROR], httpVersionStr[httpVersion], httpCode,
|
||||||
httpCode, httpCodeStr, httpKeepAliveStr[pContext->parser->keepAlive], bodyLen);
|
httpCodeStr, httpKeepAliveStr[keepAlive], bodyLen);
|
||||||
|
|
||||||
httpWriteBuf(pContext, head, headLen);
|
httpWriteBuf(pContext, head, headLen);
|
||||||
httpWriteBuf(pContext, body, bodyLen);
|
httpWriteBuf(pContext, body, bodyLen);
|
||||||
|
@ -164,9 +171,16 @@ void httpSendSuccResp(HttpContext *pContext, char *desc) {
|
||||||
char head[1024] = {0};
|
char head[1024] = {0};
|
||||||
char body[1024] = {0};
|
char body[1024] = {0};
|
||||||
|
|
||||||
|
int8_t httpVersion = 0;
|
||||||
|
int8_t keepAlive = 0;
|
||||||
|
if (pContext->parser != NULL) {
|
||||||
|
httpVersion = pContext->parser->httpVersion;
|
||||||
|
keepAlive = pContext->parser->keepAlive;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_OK], TSDB_CODE_SUCCESS, desc);
|
int32_t bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_OK], TSDB_CODE_SUCCESS, desc);
|
||||||
int32_t headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_OK], httpVersionStr[pContext->parser->httpVersion],
|
int32_t headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_OK], httpVersionStr[httpVersion],
|
||||||
httpKeepAliveStr[pContext->parser->keepAlive], bodyLen);
|
httpKeepAliveStr[keepAlive], bodyLen);
|
||||||
|
|
||||||
httpWriteBuf(pContext, head, headLen);
|
httpWriteBuf(pContext, head, headLen);
|
||||||
httpWriteBuf(pContext, body, bodyLen);
|
httpWriteBuf(pContext, body, bodyLen);
|
||||||
|
@ -177,9 +191,16 @@ void httpSendOptionResp(HttpContext *pContext, char *desc) {
|
||||||
char head[1024] = {0};
|
char head[1024] = {0};
|
||||||
char body[1024] = {0};
|
char body[1024] = {0};
|
||||||
|
|
||||||
|
int8_t httpVersion = 0;
|
||||||
|
int8_t keepAlive = 0;
|
||||||
|
if (pContext->parser != NULL) {
|
||||||
|
httpVersion = pContext->parser->httpVersion;
|
||||||
|
keepAlive = pContext->parser->keepAlive;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_OK], TSDB_CODE_SUCCESS, desc);
|
int32_t bodyLen = sprintf(body, httpRespTemplate[HTTP_RESPONSE_JSON_OK], TSDB_CODE_SUCCESS, desc);
|
||||||
int32_t headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_OPTIONS], httpVersionStr[pContext->parser->httpVersion],
|
int32_t headLen = sprintf(head, httpRespTemplate[HTTP_RESPONSE_OPTIONS], httpVersionStr[httpVersion],
|
||||||
httpKeepAliveStr[pContext->parser->keepAlive], bodyLen);
|
httpKeepAliveStr[keepAlive], bodyLen);
|
||||||
|
|
||||||
httpWriteBuf(pContext, head, headLen);
|
httpWriteBuf(pContext, head, headLen);
|
||||||
httpWriteBuf(pContext, body, bodyLen);
|
httpWriteBuf(pContext, body, bodyLen);
|
||||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
||||||
typedef void (*_bi_consumer_fn_t)(void *left, void *right, int32_t numOfLeft, int32_t numOfRight, void *output,
|
typedef void (*_bi_consumer_fn_t)(void *left, void *right, int32_t numOfLeft, int32_t numOfRight, void *output,
|
||||||
int32_t order);
|
int32_t order);
|
||||||
|
|
||||||
_bi_consumer_fn_t tGetBiConsumerFn(int32_t leftType, int32_t rightType, int32_t optr);
|
_bi_consumer_fn_t getArithmeticOperatorFn(int32_t leftType, int32_t rightType, int32_t optr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
|
@ -74,9 +74,7 @@ typedef struct tExprNode {
|
||||||
};
|
};
|
||||||
} tExprNode;
|
} tExprNode;
|
||||||
|
|
||||||
void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SExprTraverseSupp *param);
|
void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
||||||
|
|
||||||
void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
|
||||||
char *(*cb)(void *, const char*, int32_t));
|
char *(*cb)(void *, const char*, int32_t));
|
||||||
|
|
||||||
tExprNode* exprTreeFromBinary(const void* data, size_t size);
|
tExprNode* exprTreeFromBinary(const void* data, size_t size);
|
||||||
|
@ -87,6 +85,8 @@ void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
|
||||||
void tExprNodeDestroy(tExprNode *pNode, void (*fp)(void *));
|
void tExprNodeDestroy(tExprNode *pNode, void (*fp)(void *));
|
||||||
void tExprTreeDestroy(tExprNode **pExprs, void (*fp)(void*));
|
void tExprTreeDestroy(tExprNode **pExprs, void (*fp)(void*));
|
||||||
|
|
||||||
|
bool exprTreeApplayFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -190,7 +190,7 @@ typedef struct SQueryRuntimeEnv {
|
||||||
void* pSecQueryHandle; // another thread for
|
void* pSecQueryHandle; // another thread for
|
||||||
bool stableQuery; // super table query or not
|
bool stableQuery; // super table query or not
|
||||||
bool topBotQuery; // TODO used bitwise flag
|
bool topBotQuery; // TODO used bitwise flag
|
||||||
bool groupbyNormalCol; // denote if this is a groupby normal column query
|
bool groupbyColumn; // denote if this is a groupby normal column query
|
||||||
bool hasTagResults; // if there are tag values in final result or not
|
bool hasTagResults; // if there are tag values in final result or not
|
||||||
bool timeWindowInterpo;// if the time window start/end required interpolation
|
bool timeWindowInterpo;// if the time window start/end required interpolation
|
||||||
bool queryWindowIdentical; // all query time windows are identical for all tables in one group
|
bool queryWindowIdentical; // all query time windows are identical for all tables in one group
|
||||||
|
@ -204,6 +204,8 @@ typedef struct SQueryRuntimeEnv {
|
||||||
int32_t* rowCellInfoOffset;// offset value for each row result cell info
|
int32_t* rowCellInfoOffset;// offset value for each row result cell info
|
||||||
char** prevRow;
|
char** prevRow;
|
||||||
char** nextRow;
|
char** nextRow;
|
||||||
|
|
||||||
|
SArithmeticSupport *sasArray;
|
||||||
} SQueryRuntimeEnv;
|
} SQueryRuntimeEnv;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -237,6 +239,7 @@ typedef struct SQInfo {
|
||||||
int32_t dataReady; // denote if query result is ready or not
|
int32_t dataReady; // denote if query result is ready or not
|
||||||
void* rspContext; // response context
|
void* rspContext; // response context
|
||||||
int64_t startExecTs; // start to exec timestamp
|
int64_t startExecTs; // start to exec timestamp
|
||||||
|
char* sql; // query sql string
|
||||||
} SQInfo;
|
} SQInfo;
|
||||||
|
|
||||||
#endif // TDENGINE_QUERYEXECUTOR_H
|
#endif // TDENGINE_QUERYEXECUTOR_H
|
||||||
|
|
|
@ -112,11 +112,10 @@ extern "C" {
|
||||||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MASTER_SCAN = 0x0u,
|
MASTER_SCAN = 0x0u,
|
||||||
REVERSE_SCAN = 0x1u,
|
REVERSE_SCAN = 0x1u,
|
||||||
REPEAT_SCAN = 0x2u, //repeat scan belongs to the master scan
|
REPEAT_SCAN = 0x2u, //repeat scan belongs to the master scan
|
||||||
FIRST_STAGE_MERGE = 0x10u,
|
MERGE_STAGE = 0x20u,
|
||||||
SECONDARY_STAGE_MERGE = 0x20u,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define QUERY_IS_STABLE_QUERY(type) (((type)&TSDB_QUERY_TYPE_STABLE_QUERY) != 0)
|
#define QUERY_IS_STABLE_QUERY(type) (((type)&TSDB_QUERY_TYPE_STABLE_QUERY) != 0)
|
||||||
|
@ -191,8 +190,8 @@ typedef struct SQLFunctionCtx {
|
||||||
int64_t nStartQueryTimestamp; // timestamp range of current query when function is executed on a specific data block
|
int64_t nStartQueryTimestamp; // timestamp range of current query when function is executed on a specific data block
|
||||||
int32_t numOfParams;
|
int32_t numOfParams;
|
||||||
tVariant param[4]; // input parameter, e.g., top(k, 20), the number of results for top query is kept in param */
|
tVariant param[4]; // input parameter, e.g., top(k, 20), the number of results for top query is kept in param */
|
||||||
int64_t * ptsList; // corresponding timestamp array list
|
int64_t *ptsList; // corresponding timestamp array list
|
||||||
void * ptsOutputBuf; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/
|
void *ptsOutputBuf; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/
|
||||||
SQLPreAggVal preAggVals;
|
SQLPreAggVal preAggVals;
|
||||||
tVariant tag;
|
tVariant tag;
|
||||||
|
|
||||||
|
@ -215,18 +214,12 @@ typedef struct SQLAggFuncElem {
|
||||||
void (*xFunction)(SQLFunctionCtx *pCtx); // blocks version function
|
void (*xFunction)(SQLFunctionCtx *pCtx); // blocks version function
|
||||||
void (*xFunctionF)(SQLFunctionCtx *pCtx, int32_t position); // single-row function version
|
void (*xFunctionF)(SQLFunctionCtx *pCtx, int32_t position); // single-row function version
|
||||||
|
|
||||||
// some sql function require scan data twice or more, e.g.,stddev
|
// some sql function require scan data twice or more, e.g.,stddev, percentile
|
||||||
void (*xNextStep)(SQLFunctionCtx *pCtx);
|
void (*xNextStep)(SQLFunctionCtx *pCtx);
|
||||||
|
|
||||||
/*
|
// finalizer must be called after all xFunction has been executed to generated final result.
|
||||||
* finalizer must be called after all xFunction has been executed to
|
|
||||||
* generated final result. Otherwise, the value in aOutputBuf is a intern result.
|
|
||||||
*/
|
|
||||||
void (*xFinalize)(SQLFunctionCtx *pCtx);
|
void (*xFinalize)(SQLFunctionCtx *pCtx);
|
||||||
|
void (*mergeFunc)(SQLFunctionCtx *pCtx);
|
||||||
void (*distMergeFunc)(SQLFunctionCtx *pCtx);
|
|
||||||
|
|
||||||
void (*distSecondaryMergeFunc)(SQLFunctionCtx *pCtx);
|
|
||||||
|
|
||||||
int32_t (*dataReqFunc)(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId);
|
int32_t (*dataReqFunc)(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId);
|
||||||
} SQLAggFuncElem;
|
} SQLAggFuncElem;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "qSyntaxtreefunction.h"
|
#include "qArithmeticOperator.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
|
@ -1234,7 +1234,7 @@ _bi_consumer_fn_t rem_function_arraylist[8][10] = {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
_bi_consumer_fn_t tGetBiConsumerFn(int32_t leftType, int32_t rightType, int32_t optr) {
|
_bi_consumer_fn_t getArithmeticOperatorFn(int32_t leftType, int32_t rightType, int32_t optr) {
|
||||||
switch (optr) {
|
switch (optr) {
|
||||||
case TSDB_BINARY_OP_ADD:
|
case TSDB_BINARY_OP_ADD:
|
||||||
return add_function_arraylist[leftType][rightType];
|
return add_function_arraylist[leftType][rightType];
|
|
@ -16,29 +16,18 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
#include "qArithmeticOperator.h"
|
||||||
#include "qAst.h"
|
#include "qAst.h"
|
||||||
#include "qSyntaxtreefunction.h"
|
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "tbuffer.h"
|
#include "tbuffer.h"
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
|
#include "tschemautil.h"
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
#include "tskiplist.h"
|
#include "tskiplist.h"
|
||||||
#include "tsqlfunction.h"
|
#include "tsqlfunction.h"
|
||||||
#include "tstoken.h"
|
|
||||||
#include "tschemautil.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char* v;
|
|
||||||
int32_t optr;
|
|
||||||
} SEndPoint;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
SEndPoint* start;
|
|
||||||
SEndPoint* end;
|
|
||||||
} SQueryCond;
|
|
||||||
|
|
||||||
static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) {
|
static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) {
|
||||||
if (pLeft->nodeType == TSQL_NODE_COL) {
|
if (pLeft->nodeType == TSQL_NODE_COL) {
|
||||||
|
@ -53,323 +42,6 @@ static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tExprNodeDestroy(tExprNode *pNode, void (*fp)(void *)) {
|
|
||||||
if (pNode == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pNode->nodeType == TSQL_NODE_EXPR) {
|
|
||||||
tExprTreeDestroy(&pNode, fp);
|
|
||||||
} else if (pNode->nodeType == TSQL_NODE_VALUE) {
|
|
||||||
tVariantDestroy(pNode->pVal);
|
|
||||||
} else if (pNode->nodeType == TSQL_NODE_COL) {
|
|
||||||
free(pNode->pSchema);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
|
|
||||||
if (*pExpr == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*pExpr)->nodeType == TSQL_NODE_EXPR) {
|
|
||||||
tExprTreeDestroy(&(*pExpr)->_node.pLeft, fp);
|
|
||||||
tExprTreeDestroy(&(*pExpr)->_node.pRight, fp);
|
|
||||||
|
|
||||||
if (fp != NULL) {
|
|
||||||
fp((*pExpr)->_node.info);
|
|
||||||
}
|
|
||||||
} else if ((*pExpr)->nodeType == TSQL_NODE_VALUE) {
|
|
||||||
tVariantDestroy((*pExpr)->pVal);
|
|
||||||
free((*pExpr)->pVal);
|
|
||||||
} else if ((*pExpr)->nodeType == TSQL_NODE_COL) {
|
|
||||||
free((*pExpr)->pSchema);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(*pExpr);
|
|
||||||
*pExpr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo check for malloc failure
|
|
||||||
static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
|
|
||||||
int32_t optr = queryColInfo->optr;
|
|
||||||
|
|
||||||
if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL ||
|
|
||||||
optr == TSDB_RELATION_EQUAL || optr == TSDB_RELATION_NOT_EQUAL) {
|
|
||||||
pCond->start = calloc(1, sizeof(SEndPoint));
|
|
||||||
pCond->start->optr = queryColInfo->optr;
|
|
||||||
pCond->start->v = queryColInfo->q;
|
|
||||||
} else if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
|
||||||
pCond->end = calloc(1, sizeof(SEndPoint));
|
|
||||||
pCond->end->optr = queryColInfo->optr;
|
|
||||||
pCond->end->v = queryColInfo->q;
|
|
||||||
} else if (optr == TSDB_RELATION_IN || optr == TSDB_RELATION_LIKE) {
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* result) {
|
|
||||||
SSkipListIterator* iter = NULL;
|
|
||||||
|
|
||||||
SQueryCond cond = {0};
|
|
||||||
if (setQueryCond(pQueryInfo, &cond) != TSDB_CODE_SUCCESS) {
|
|
||||||
//todo handle error
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cond.start != NULL) {
|
|
||||||
iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.start->v, pSkipList->type, TSDB_ORDER_ASC);
|
|
||||||
} else {
|
|
||||||
iter = tSkipListCreateIterFromVal(pSkipList, (char*)(cond.end ? cond.end->v: NULL), pSkipList->type, TSDB_ORDER_DESC);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cond.start != NULL) {
|
|
||||||
int32_t optr = cond.start->optr;
|
|
||||||
|
|
||||||
if (optr == TSDB_RELATION_EQUAL) { // equals
|
|
||||||
while(tSkipListIterNext(iter)) {
|
|
||||||
SSkipListNode* pNode = tSkipListIterGet(iter);
|
|
||||||
|
|
||||||
int32_t ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
|
|
||||||
if (ret != 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
bool comp = true;
|
|
||||||
int32_t ret = 0;
|
|
||||||
|
|
||||||
while(tSkipListIterNext(iter)) {
|
|
||||||
SSkipListNode* pNode = tSkipListIterGet(iter);
|
|
||||||
|
|
||||||
if (comp) {
|
|
||||||
ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
|
|
||||||
assert(ret >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0 && optr == TSDB_RELATION_GREATER) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
|
|
||||||
taosArrayPush(result, &info);
|
|
||||||
comp = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (optr == TSDB_RELATION_NOT_EQUAL) { // not equal
|
|
||||||
bool comp = true;
|
|
||||||
|
|
||||||
while(tSkipListIterNext(iter)) {
|
|
||||||
SSkipListNode* pNode = tSkipListIterGet(iter);
|
|
||||||
comp = comp && (pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v) == 0);
|
|
||||||
if (comp) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
|
|
||||||
taosArrayPush(result, &info);
|
|
||||||
}
|
|
||||||
|
|
||||||
tSkipListDestroyIter(iter);
|
|
||||||
|
|
||||||
comp = true;
|
|
||||||
iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.start->v, pSkipList->type, TSDB_ORDER_DESC);
|
|
||||||
while(tSkipListIterNext(iter)) {
|
|
||||||
SSkipListNode* pNode = tSkipListIterGet(iter);
|
|
||||||
comp = comp && (pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v) == 0);
|
|
||||||
if (comp) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
|
|
||||||
taosArrayPush(result, &info);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int32_t optr = cond.end ? cond.end->optr : TSDB_RELATION_INVALID;
|
|
||||||
if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
|
||||||
bool comp = true;
|
|
||||||
int32_t ret = 0;
|
|
||||||
|
|
||||||
while (tSkipListIterNext(iter)) {
|
|
||||||
SSkipListNode *pNode = tSkipListIterGet(iter);
|
|
||||||
|
|
||||||
if (comp) {
|
|
||||||
ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.end->v);
|
|
||||||
assert(ret <= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0 && optr == TSDB_RELATION_LESS) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
STableKeyInfo info = {.pTable = (void *)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
|
|
||||||
taosArrayPush(result, &info);
|
|
||||||
comp = false; // no need to compare anymore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
assert(pQueryInfo->optr == TSDB_RELATION_ISNULL || pQueryInfo->optr == TSDB_RELATION_NOTNULL);
|
|
||||||
|
|
||||||
while (tSkipListIterNext(iter)) {
|
|
||||||
SSkipListNode *pNode = tSkipListIterGet(iter);
|
|
||||||
|
|
||||||
bool isnull = isNull(SL_GET_NODE_KEY(pSkipList, pNode), pQueryInfo->sch.type);
|
|
||||||
if ((pQueryInfo->optr == TSDB_RELATION_ISNULL && isnull) ||
|
|
||||||
(pQueryInfo->optr == TSDB_RELATION_NOTNULL && (!isnull))) {
|
|
||||||
STableKeyInfo info = {.pTable = (void *)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
|
|
||||||
taosArrayPush(result, &info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(cond.start);
|
|
||||||
free(cond.end);
|
|
||||||
tSkipListDestroyIter(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool filterItem(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param) {
|
|
||||||
tExprNode *pLeft = pExpr->_node.pLeft;
|
|
||||||
tExprNode *pRight = pExpr->_node.pRight;
|
|
||||||
|
|
||||||
//non-leaf nodes, recursively traverse the expression tree in the post-root order
|
|
||||||
if (pLeft->nodeType == TSQL_NODE_EXPR && pRight->nodeType == TSQL_NODE_EXPR) {
|
|
||||||
if (pExpr->_node.optr == TSDB_RELATION_OR) { // or
|
|
||||||
if (filterItem(pLeft, pItem, param)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// left child does not satisfy the query condition, try right child
|
|
||||||
return filterItem(pRight, pItem, param);
|
|
||||||
} else { // and
|
|
||||||
if (!filterItem(pLeft, pItem, param)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return filterItem(pRight, pItem, param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle the leaf node
|
|
||||||
param->setupInfoFn(pExpr, param->pExtInfo);
|
|
||||||
return param->nodeFilterFn(pItem, pExpr->_node.info);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tSQLBinaryTraverseOnSkipList(tExprNode *pExpr, SArray *pResult, SSkipList *pSkipList, SExprTraverseSupp *param ) {
|
|
||||||
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
|
|
||||||
|
|
||||||
while (tSkipListIterNext(iter)) {
|
|
||||||
SSkipListNode *pNode = tSkipListIterGet(iter);
|
|
||||||
if (filterItem(pExpr, pNode, param)) {
|
|
||||||
taosArrayPush(pResult, &(SL_GET_NODE_DATA(pNode)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tSkipListDestroyIter(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tQueryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* res, __result_filter_fn_t filterFp) {
|
|
||||||
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
|
|
||||||
|
|
||||||
while (tSkipListIterNext(iter)) {
|
|
||||||
bool addToResult = false;
|
|
||||||
|
|
||||||
SSkipListNode *pNode = tSkipListIterGet(iter);
|
|
||||||
char * pData = SL_GET_NODE_DATA(pNode);
|
|
||||||
|
|
||||||
tstr *name = (tstr*) tsdbGetTableName((void*) pData);
|
|
||||||
|
|
||||||
// todo speed up by using hash
|
|
||||||
if (pQueryInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
|
|
||||||
if (pQueryInfo->optr == TSDB_RELATION_IN) {
|
|
||||||
addToResult = pQueryInfo->compare(name, pQueryInfo->q);
|
|
||||||
} else if (pQueryInfo->optr == TSDB_RELATION_LIKE) {
|
|
||||||
addToResult = !pQueryInfo->compare(name, pQueryInfo->q);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addToResult = filterFp(pNode, pQueryInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addToResult) {
|
|
||||||
STableKeyInfo info = {.pTable = (void*)pData, .lastKey = TSKEY_INITIAL_VAL};
|
|
||||||
taosArrayPush(res, &info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tSkipListDestroyIter(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// post-root order traverse syntax tree
|
|
||||||
void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SExprTraverseSupp *param) {
|
|
||||||
if (pExpr == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tExprNode *pLeft = pExpr->_node.pLeft;
|
|
||||||
tExprNode *pRight = pExpr->_node.pRight;
|
|
||||||
|
|
||||||
// column project
|
|
||||||
if (pLeft->nodeType != TSQL_NODE_EXPR && pRight->nodeType != TSQL_NODE_EXPR) {
|
|
||||||
assert(pLeft->nodeType == TSQL_NODE_COL && (pRight->nodeType == TSQL_NODE_VALUE || pRight->nodeType == TSQL_NODE_DUMMY));
|
|
||||||
|
|
||||||
param->setupInfoFn(pExpr, param->pExtInfo);
|
|
||||||
|
|
||||||
tQueryInfo *pQueryInfo = pExpr->_node.info;
|
|
||||||
if (pQueryInfo->indexed && pQueryInfo->optr != TSDB_RELATION_LIKE) {
|
|
||||||
tQueryIndexColumn(pSkipList, pQueryInfo, result);
|
|
||||||
} else {
|
|
||||||
tQueryIndexlessColumn(pSkipList, pQueryInfo, result, param->nodeFilterFn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The value of hasPK is always 0.
|
|
||||||
uint8_t weight = pLeft->_node.hasPK + pRight->_node.hasPK;
|
|
||||||
assert(weight == 0 && pSkipList != NULL && taosArrayGetSize(result) == 0);
|
|
||||||
|
|
||||||
//apply the hierarchical expression to every node in skiplist for find the qualified nodes
|
|
||||||
tSQLBinaryTraverseOnSkipList(pExpr, result, pSkipList, param);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* (weight == 1 && pExpr->nSQLBinaryOptr == TSDB_RELATION_AND) is handled here
|
|
||||||
*
|
|
||||||
* first, we filter results based on the skiplist index, which is the initial filter stage,
|
|
||||||
* then, we conduct the secondary filter operation based on the result from the initial filter stage.
|
|
||||||
*/
|
|
||||||
assert(pExpr->_node.optr == TSDB_RELATION_AND);
|
|
||||||
|
|
||||||
tExprNode *pFirst = NULL;
|
|
||||||
tExprNode *pSecond = NULL;
|
|
||||||
if (pLeft->_node.hasPK == 1) {
|
|
||||||
pFirst = pLeft;
|
|
||||||
pSecond = pRight;
|
|
||||||
} else {
|
|
||||||
pFirst = pRight;
|
|
||||||
pSecond = pLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(pFirst != pSecond && pFirst != NULL && pSecond != NULL);
|
|
||||||
|
|
||||||
// we filter the result based on the skiplist index in the first place
|
|
||||||
tExprTreeTraverse(pFirst, pSkipList, result, param);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* recursively perform the filter operation based on the initial results,
|
|
||||||
* So, we do not set the skip list index as a parameter
|
|
||||||
*/
|
|
||||||
tExprTreeTraverse(pSecond, NULL, result, param);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) {
|
static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case TSDB_DATA_TYPE_TINYINT: {
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
@ -430,7 +102,73 @@ static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
void tExprNodeDestroy(tExprNode *pNode, void (*fp)(void *)) {
|
||||||
|
if (pNode == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pNode->nodeType == TSQL_NODE_EXPR) {
|
||||||
|
tExprTreeDestroy(&pNode, fp);
|
||||||
|
} else if (pNode->nodeType == TSQL_NODE_VALUE) {
|
||||||
|
tVariantDestroy(pNode->pVal);
|
||||||
|
} else if (pNode->nodeType == TSQL_NODE_COL) {
|
||||||
|
free(pNode->pSchema);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
|
||||||
|
if (*pExpr == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*pExpr)->nodeType == TSQL_NODE_EXPR) {
|
||||||
|
tExprTreeDestroy(&(*pExpr)->_node.pLeft, fp);
|
||||||
|
tExprTreeDestroy(&(*pExpr)->_node.pRight, fp);
|
||||||
|
|
||||||
|
if (fp != NULL) {
|
||||||
|
fp((*pExpr)->_node.info);
|
||||||
|
}
|
||||||
|
} else if ((*pExpr)->nodeType == TSQL_NODE_VALUE) {
|
||||||
|
tVariantDestroy((*pExpr)->pVal);
|
||||||
|
free((*pExpr)->pVal);
|
||||||
|
} else if ((*pExpr)->nodeType == TSQL_NODE_COL) {
|
||||||
|
free((*pExpr)->pSchema);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(*pExpr);
|
||||||
|
*pExpr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exprTreeApplayFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param) {
|
||||||
|
tExprNode *pLeft = pExpr->_node.pLeft;
|
||||||
|
tExprNode *pRight = pExpr->_node.pRight;
|
||||||
|
|
||||||
|
//non-leaf nodes, recursively traverse the expression tree in the post-root order
|
||||||
|
if (pLeft->nodeType == TSQL_NODE_EXPR && pRight->nodeType == TSQL_NODE_EXPR) {
|
||||||
|
if (pExpr->_node.optr == TSDB_RELATION_OR) { // or
|
||||||
|
if (exprTreeApplayFilter(pLeft, pItem, param)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// left child does not satisfy the query condition, try right child
|
||||||
|
return exprTreeApplayFilter(pRight, pItem, param);
|
||||||
|
} else { // and
|
||||||
|
if (!exprTreeApplayFilter(pLeft, pItem, param)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return exprTreeApplayFilter(pRight, pItem, param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle the leaf node
|
||||||
|
param->setupInfoFn(pExpr, param->pExtInfo);
|
||||||
|
return param->nodeFilterFn(pItem, pExpr->_node.info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
||||||
char *(*getSourceDataBlock)(void *, const char*, int32_t)) {
|
char *(*getSourceDataBlock)(void *, const char*, int32_t)) {
|
||||||
if (pExprs == NULL) {
|
if (pExprs == NULL) {
|
||||||
return;
|
return;
|
||||||
|
@ -442,7 +180,7 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
|
||||||
/* the left output has result from the left child syntax tree */
|
/* the left output has result from the left child syntax tree */
|
||||||
char *pLeftOutput = (char*)malloc(sizeof(int64_t) * numOfRows);
|
char *pLeftOutput = (char*)malloc(sizeof(int64_t) * numOfRows);
|
||||||
if (pLeft->nodeType == TSQL_NODE_EXPR) {
|
if (pLeft->nodeType == TSQL_NODE_EXPR) {
|
||||||
tExprTreeCalcTraverse(pLeft, numOfRows, pLeftOutput, param, order, getSourceDataBlock);
|
arithmeticTreeTraverse(pLeft, numOfRows, pLeftOutput, param, order, getSourceDataBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the right output has result from the right child syntax tree */
|
/* the right output has result from the right child syntax tree */
|
||||||
|
@ -450,7 +188,7 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
|
||||||
char *pdata = malloc(sizeof(int64_t) * numOfRows);
|
char *pdata = malloc(sizeof(int64_t) * numOfRows);
|
||||||
|
|
||||||
if (pRight->nodeType == TSQL_NODE_EXPR) {
|
if (pRight->nodeType == TSQL_NODE_EXPR) {
|
||||||
tExprTreeCalcTraverse(pRight, numOfRows, pRightOutput, param, order, getSourceDataBlock);
|
arithmeticTreeTraverse(pRight, numOfRows, pRightOutput, param, order, getSourceDataBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pLeft->nodeType == TSQL_NODE_EXPR) {
|
if (pLeft->nodeType == TSQL_NODE_EXPR) {
|
||||||
|
@ -459,11 +197,11 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
|
||||||
* exprLeft + exprRight
|
* exprLeft + exprRight
|
||||||
* the type of returned value of one expression is always double float precious
|
* the type of returned value of one expression is always double float precious
|
||||||
*/
|
*/
|
||||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(TSDB_DATA_TYPE_DOUBLE, TSDB_DATA_TYPE_DOUBLE, pExprs->_node.optr);
|
_bi_consumer_fn_t fp = getArithmeticOperatorFn(TSDB_DATA_TYPE_DOUBLE, TSDB_DATA_TYPE_DOUBLE, pExprs->_node.optr);
|
||||||
fp(pLeftOutput, pRightOutput, numOfRows, numOfRows, pOutput, TSDB_ORDER_ASC);
|
fp(pLeftOutput, pRightOutput, numOfRows, numOfRows, pOutput, TSDB_ORDER_ASC);
|
||||||
|
|
||||||
} else if (pRight->nodeType == TSQL_NODE_COL) { // exprLeft + columnRight
|
} else if (pRight->nodeType == TSQL_NODE_COL) { // exprLeft + columnRight
|
||||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(TSDB_DATA_TYPE_DOUBLE, pRight->pSchema->type, pExprs->_node.optr);
|
_bi_consumer_fn_t fp = getArithmeticOperatorFn(TSDB_DATA_TYPE_DOUBLE, pRight->pSchema->type, pExprs->_node.optr);
|
||||||
|
|
||||||
// set input buffer
|
// set input buffer
|
||||||
char *pInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
char *pInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
||||||
|
@ -475,14 +213,14 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // exprLeft + 12
|
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // exprLeft + 12
|
||||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(TSDB_DATA_TYPE_DOUBLE, pRight->pVal->nType, pExprs->_node.optr);
|
_bi_consumer_fn_t fp = getArithmeticOperatorFn(TSDB_DATA_TYPE_DOUBLE, pRight->pVal->nType, pExprs->_node.optr);
|
||||||
fp(pLeftOutput, &pRight->pVal->i64Key, numOfRows, 1, pOutput, TSDB_ORDER_ASC);
|
fp(pLeftOutput, &pRight->pVal->i64Key, numOfRows, 1, pOutput, TSDB_ORDER_ASC);
|
||||||
}
|
}
|
||||||
} else if (pLeft->nodeType == TSQL_NODE_COL) {
|
} else if (pLeft->nodeType == TSQL_NODE_COL) {
|
||||||
// column data specified on left-hand-side
|
// column data specified on left-hand-side
|
||||||
char *pLeftInputData = getSourceDataBlock(param, pLeft->pSchema->name, pLeft->pSchema->colId);
|
char *pLeftInputData = getSourceDataBlock(param, pLeft->pSchema->name, pLeft->pSchema->colId);
|
||||||
if (pRight->nodeType == TSQL_NODE_EXPR) { // columnLeft + expr2
|
if (pRight->nodeType == TSQL_NODE_EXPR) { // columnLeft + expr2
|
||||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pSchema->type, TSDB_DATA_TYPE_DOUBLE, pExprs->_node.optr);
|
_bi_consumer_fn_t fp = getArithmeticOperatorFn(pLeft->pSchema->type, TSDB_DATA_TYPE_DOUBLE, pExprs->_node.optr);
|
||||||
|
|
||||||
if (order == TSDB_ORDER_DESC) {
|
if (order == TSDB_ORDER_DESC) {
|
||||||
reverseCopy(pdata, pLeftInputData, pLeft->pSchema->type, numOfRows);
|
reverseCopy(pdata, pLeftInputData, pLeft->pSchema->type, numOfRows);
|
||||||
|
@ -494,12 +232,12 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
|
||||||
} else if (pRight->nodeType == TSQL_NODE_COL) { // columnLeft + columnRight
|
} else if (pRight->nodeType == TSQL_NODE_COL) { // columnLeft + columnRight
|
||||||
// column data specified on right-hand-side
|
// column data specified on right-hand-side
|
||||||
char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
||||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pSchema->type, pRight->pSchema->type, pExprs->_node.optr);
|
_bi_consumer_fn_t fp = getArithmeticOperatorFn(pLeft->pSchema->type, pRight->pSchema->type, pExprs->_node.optr);
|
||||||
|
|
||||||
// both columns are descending order, do not reverse the source data
|
// both columns are descending order, do not reverse the source data
|
||||||
fp(pLeftInputData, pRightInputData, numOfRows, numOfRows, pOutput, order);
|
fp(pLeftInputData, pRightInputData, numOfRows, numOfRows, pOutput, order);
|
||||||
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // columnLeft + 12
|
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // columnLeft + 12
|
||||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pSchema->type, pRight->pVal->nType, pExprs->_node.optr);
|
_bi_consumer_fn_t fp = getArithmeticOperatorFn(pLeft->pSchema->type, pRight->pVal->nType, pExprs->_node.optr);
|
||||||
|
|
||||||
if (order == TSDB_ORDER_DESC) {
|
if (order == TSDB_ORDER_DESC) {
|
||||||
reverseCopy(pdata, pLeftInputData, pLeft->pSchema->type, numOfRows);
|
reverseCopy(pdata, pLeftInputData, pLeft->pSchema->type, numOfRows);
|
||||||
|
@ -511,13 +249,13 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
|
||||||
} else {
|
} else {
|
||||||
// column data specified on left-hand-side
|
// column data specified on left-hand-side
|
||||||
if (pRight->nodeType == TSQL_NODE_EXPR) { // 12 + expr2
|
if (pRight->nodeType == TSQL_NODE_EXPR) { // 12 + expr2
|
||||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pVal->nType, TSDB_DATA_TYPE_DOUBLE, pExprs->_node.optr);
|
_bi_consumer_fn_t fp = getArithmeticOperatorFn(pLeft->pVal->nType, TSDB_DATA_TYPE_DOUBLE, pExprs->_node.optr);
|
||||||
fp(&pLeft->pVal->i64Key, pRightOutput, 1, numOfRows, pOutput, TSDB_ORDER_ASC);
|
fp(&pLeft->pVal->i64Key, pRightOutput, 1, numOfRows, pOutput, TSDB_ORDER_ASC);
|
||||||
|
|
||||||
} else if (pRight->nodeType == TSQL_NODE_COL) { // 12 + columnRight
|
} else if (pRight->nodeType == TSQL_NODE_COL) { // 12 + columnRight
|
||||||
// column data specified on right-hand-side
|
// column data specified on right-hand-side
|
||||||
char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
||||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pVal->nType, pRight->pSchema->type, pExprs->_node.optr);
|
_bi_consumer_fn_t fp = getArithmeticOperatorFn(pLeft->pVal->nType, pRight->pSchema->type, pExprs->_node.optr);
|
||||||
|
|
||||||
if (order == TSDB_ORDER_DESC) {
|
if (order == TSDB_ORDER_DESC) {
|
||||||
reverseCopy(pdata, pRightInputData, pRight->pSchema->type, numOfRows);
|
reverseCopy(pdata, pRightInputData, pRight->pSchema->type, numOfRows);
|
||||||
|
@ -527,7 +265,7 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // 12 + 12
|
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // 12 + 12
|
||||||
_bi_consumer_fn_t fp = tGetBiConsumerFn(pLeft->pVal->nType, pRight->pVal->nType, pExprs->_node.optr);
|
_bi_consumer_fn_t fp = getArithmeticOperatorFn(pLeft->pVal->nType, pRight->pVal->nType, pExprs->_node.optr);
|
||||||
fp(&pLeft->pVal->i64Key, &pRight->pVal->i64Key, 1, 1, pOutput, TSDB_ORDER_ASC);
|
fp(&pLeft->pVal->i64Key, &pRight->pVal->i64Key, 1, 1, pOutput, TSDB_ORDER_ASC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -174,7 +174,7 @@ int32_t tHistogramAdd(SHistogramInfo** pHisto, double val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((*pHisto)->elems[idx].val > val);
|
assert((*pHisto)->elems[idx].val > val);
|
||||||
} else {
|
} else if ((*pHisto)->numOfElems > 0) {
|
||||||
assert((*pHisto)->elems[(*pHisto)->numOfEntries].val < val);
|
assert((*pHisto)->elems[(*pHisto)->numOfEntries].val < val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -503,9 +503,10 @@ void *syncRetrieveData(void *param) {
|
||||||
taosClose(pPeer->syncFd);
|
taosClose(pPeer->syncFd);
|
||||||
|
|
||||||
// The ref is obtained in both the create thread and the current thread, so it is released twice
|
// The ref is obtained in both the create thread and the current thread, so it is released twice
|
||||||
|
sInfo("%s, sync retrieve data over, sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||||
|
|
||||||
syncReleasePeer(pPeer);
|
syncReleasePeer(pPeer);
|
||||||
syncReleasePeer(pPeer);
|
syncReleasePeer(pPeer);
|
||||||
|
|
||||||
sInfo("%s, sync retrieve data over, sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2645,13 +2645,12 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC
|
||||||
return pTableGroup;
|
return pTableGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool indexedNodeFilterFp(const void* pNode, void* param) {
|
static bool tableFilterFp(const void* pNode, void* param) {
|
||||||
tQueryInfo* pInfo = (tQueryInfo*) param;
|
tQueryInfo* pInfo = (tQueryInfo*) param;
|
||||||
|
|
||||||
STable* pTable = (STable*)(SL_GET_NODE_DATA((SSkipListNode*)pNode));
|
STable* pTable = (STable*)(SL_GET_NODE_DATA((SSkipListNode*)pNode));
|
||||||
|
|
||||||
char* val = NULL;
|
char* val = NULL;
|
||||||
|
|
||||||
if (pInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
|
if (pInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
val = (char*) TABLE_NAME(pTable);
|
val = (char*) TABLE_NAME(pTable);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2706,15 +2705,17 @@ static bool indexedNodeFilterFp(const void* pNode, void* param) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SExprTraverseSupp *param);
|
||||||
|
|
||||||
static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr) {
|
static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr) {
|
||||||
// query according to the expression tree
|
// query according to the expression tree
|
||||||
SExprTraverseSupp supp = {
|
SExprTraverseSupp supp = {
|
||||||
.nodeFilterFn = (__result_filter_fn_t) indexedNodeFilterFp,
|
.nodeFilterFn = (__result_filter_fn_t) tableFilterFp,
|
||||||
.setupInfoFn = filterPrepare,
|
.setupInfoFn = filterPrepare,
|
||||||
.pExtInfo = pSTable->tagSchema,
|
.pExtInfo = pSTable->tagSchema,
|
||||||
};
|
};
|
||||||
|
|
||||||
tExprTreeTraverse(pExpr, pSTable->pIndex, pRes, &supp);
|
getTableListfromSkipList(pExpr, pSTable->pIndex, pRes, &supp);
|
||||||
tExprTreeDestroy(&pExpr, destroyHelper);
|
tExprTreeDestroy(&pExpr, destroyHelper);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2956,3 +2957,235 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList) {
|
||||||
taosArrayDestroy(pGroupList->pGroupList);
|
taosArrayDestroy(pGroupList->pGroupList);
|
||||||
pGroupList->numOfTables = 0;
|
pGroupList->numOfTables = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void applyFilterToSkipListNode(SSkipList *pSkipList, tExprNode *pExpr, SArray *pResult, SExprTraverseSupp *param) {
|
||||||
|
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
|
||||||
|
|
||||||
|
// Scan each node in the skiplist by using iterator
|
||||||
|
while (tSkipListIterNext(iter)) {
|
||||||
|
SSkipListNode *pNode = tSkipListIterGet(iter);
|
||||||
|
if (exprTreeApplayFilter(pExpr, pNode, param)) {
|
||||||
|
taosArrayPush(pResult, &(SL_GET_NODE_DATA(pNode)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tSkipListDestroyIter(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* v;
|
||||||
|
int32_t optr;
|
||||||
|
} SEndPoint;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SEndPoint* start;
|
||||||
|
SEndPoint* end;
|
||||||
|
} SQueryCond;
|
||||||
|
|
||||||
|
// todo check for malloc failure
|
||||||
|
static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
|
||||||
|
int32_t optr = queryColInfo->optr;
|
||||||
|
|
||||||
|
if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL ||
|
||||||
|
optr == TSDB_RELATION_EQUAL || optr == TSDB_RELATION_NOT_EQUAL) {
|
||||||
|
pCond->start = calloc(1, sizeof(SEndPoint));
|
||||||
|
pCond->start->optr = queryColInfo->optr;
|
||||||
|
pCond->start->v = queryColInfo->q;
|
||||||
|
} else if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
||||||
|
pCond->end = calloc(1, sizeof(SEndPoint));
|
||||||
|
pCond->end->optr = queryColInfo->optr;
|
||||||
|
pCond->end->v = queryColInfo->q;
|
||||||
|
} else if (optr == TSDB_RELATION_IN || optr == TSDB_RELATION_LIKE) {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void queryIndexedColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* result) {
|
||||||
|
SSkipListIterator* iter = NULL;
|
||||||
|
|
||||||
|
SQueryCond cond = {0};
|
||||||
|
if (setQueryCond(pQueryInfo, &cond) != TSDB_CODE_SUCCESS) {
|
||||||
|
//todo handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond.start != NULL) {
|
||||||
|
iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.start->v, pSkipList->type, TSDB_ORDER_ASC);
|
||||||
|
} else {
|
||||||
|
iter = tSkipListCreateIterFromVal(pSkipList, (char*)(cond.end ? cond.end->v: NULL), pSkipList->type, TSDB_ORDER_DESC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond.start != NULL) {
|
||||||
|
int32_t optr = cond.start->optr;
|
||||||
|
|
||||||
|
if (optr == TSDB_RELATION_EQUAL) { // equals
|
||||||
|
while(tSkipListIterNext(iter)) {
|
||||||
|
SSkipListNode* pNode = tSkipListIterGet(iter);
|
||||||
|
|
||||||
|
int32_t ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
|
||||||
|
if (ret != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
bool comp = true;
|
||||||
|
int32_t ret = 0;
|
||||||
|
|
||||||
|
while(tSkipListIterNext(iter)) {
|
||||||
|
SSkipListNode* pNode = tSkipListIterGet(iter);
|
||||||
|
|
||||||
|
if (comp) {
|
||||||
|
ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v);
|
||||||
|
assert(ret >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0 && optr == TSDB_RELATION_GREATER) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
|
||||||
|
taosArrayPush(result, &info);
|
||||||
|
comp = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (optr == TSDB_RELATION_NOT_EQUAL) { // not equal
|
||||||
|
bool comp = true;
|
||||||
|
|
||||||
|
while(tSkipListIterNext(iter)) {
|
||||||
|
SSkipListNode* pNode = tSkipListIterGet(iter);
|
||||||
|
comp = comp && (pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v) == 0);
|
||||||
|
if (comp) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
|
||||||
|
taosArrayPush(result, &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
tSkipListDestroyIter(iter);
|
||||||
|
|
||||||
|
comp = true;
|
||||||
|
iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.start->v, pSkipList->type, TSDB_ORDER_DESC);
|
||||||
|
while(tSkipListIterNext(iter)) {
|
||||||
|
SSkipListNode* pNode = tSkipListIterGet(iter);
|
||||||
|
comp = comp && (pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.start->v) == 0);
|
||||||
|
if (comp) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
STableKeyInfo info = {.pTable = (void*)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
|
||||||
|
taosArrayPush(result, &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int32_t optr = cond.end ? cond.end->optr : TSDB_RELATION_INVALID;
|
||||||
|
if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
||||||
|
bool comp = true;
|
||||||
|
int32_t ret = 0;
|
||||||
|
|
||||||
|
while (tSkipListIterNext(iter)) {
|
||||||
|
SSkipListNode *pNode = tSkipListIterGet(iter);
|
||||||
|
|
||||||
|
if (comp) {
|
||||||
|
ret = pQueryInfo->compare(SL_GET_NODE_KEY(pSkipList, pNode), cond.end->v);
|
||||||
|
assert(ret <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0 && optr == TSDB_RELATION_LESS) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
STableKeyInfo info = {.pTable = (void *)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
|
||||||
|
taosArrayPush(result, &info);
|
||||||
|
comp = false; // no need to compare anymore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(pQueryInfo->optr == TSDB_RELATION_ISNULL || pQueryInfo->optr == TSDB_RELATION_NOTNULL);
|
||||||
|
|
||||||
|
while (tSkipListIterNext(iter)) {
|
||||||
|
SSkipListNode *pNode = tSkipListIterGet(iter);
|
||||||
|
|
||||||
|
bool isnull = isNull(SL_GET_NODE_KEY(pSkipList, pNode), pQueryInfo->sch.type);
|
||||||
|
if ((pQueryInfo->optr == TSDB_RELATION_ISNULL && isnull) ||
|
||||||
|
(pQueryInfo->optr == TSDB_RELATION_NOTNULL && (!isnull))) {
|
||||||
|
STableKeyInfo info = {.pTable = (void *)SL_GET_NODE_DATA(pNode), .lastKey = TSKEY_INITIAL_VAL};
|
||||||
|
taosArrayPush(result, &info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(cond.start);
|
||||||
|
free(cond.end);
|
||||||
|
tSkipListDestroyIter(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void queryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* res, __result_filter_fn_t filterFp) {
|
||||||
|
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
|
||||||
|
|
||||||
|
while (tSkipListIterNext(iter)) {
|
||||||
|
bool addToResult = false;
|
||||||
|
|
||||||
|
SSkipListNode *pNode = tSkipListIterGet(iter);
|
||||||
|
|
||||||
|
char *pData = SL_GET_NODE_DATA(pNode);
|
||||||
|
tstr *name = (tstr*) tsdbGetTableName((void*) pData);
|
||||||
|
|
||||||
|
// todo speed up by using hash
|
||||||
|
if (pQueryInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
|
if (pQueryInfo->optr == TSDB_RELATION_IN) {
|
||||||
|
addToResult = pQueryInfo->compare(name, pQueryInfo->q);
|
||||||
|
} else if (pQueryInfo->optr == TSDB_RELATION_LIKE) {
|
||||||
|
addToResult = !pQueryInfo->compare(name, pQueryInfo->q);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addToResult = filterFp(pNode, pQueryInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addToResult) {
|
||||||
|
STableKeyInfo info = {.pTable = (void*)pData, .lastKey = TSKEY_INITIAL_VAL};
|
||||||
|
taosArrayPush(res, &info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tSkipListDestroyIter(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the filter expression to each node in the skiplist to acquire the qualified nodes in skip list
|
||||||
|
void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SExprTraverseSupp *param) {
|
||||||
|
if (pExpr == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tExprNode *pLeft = pExpr->_node.pLeft;
|
||||||
|
tExprNode *pRight = pExpr->_node.pRight;
|
||||||
|
|
||||||
|
// column project
|
||||||
|
if (pLeft->nodeType != TSQL_NODE_EXPR && pRight->nodeType != TSQL_NODE_EXPR) {
|
||||||
|
assert(pLeft->nodeType == TSQL_NODE_COL && (pRight->nodeType == TSQL_NODE_VALUE || pRight->nodeType == TSQL_NODE_DUMMY));
|
||||||
|
|
||||||
|
param->setupInfoFn(pExpr, param->pExtInfo);
|
||||||
|
|
||||||
|
tQueryInfo *pQueryInfo = pExpr->_node.info;
|
||||||
|
if (pQueryInfo->indexed && pQueryInfo->optr != TSDB_RELATION_LIKE) {
|
||||||
|
queryIndexedColumn(pSkipList, pQueryInfo, result);
|
||||||
|
} else {
|
||||||
|
queryIndexlessColumn(pSkipList, pQueryInfo, result, param->nodeFilterFn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The value of hasPK is always 0.
|
||||||
|
uint8_t weight = pLeft->_node.hasPK + pRight->_node.hasPK;
|
||||||
|
assert(weight == 0 && pSkipList != NULL && taosArrayGetSize(result) == 0);
|
||||||
|
|
||||||
|
//apply the hierarchical filter expression to every node in skiplist to find the qualified nodes
|
||||||
|
applyFilterToSkipListNode(pSkipList, pExpr, result, param);
|
||||||
|
}
|
||||||
|
|
|
@ -130,16 +130,14 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe
|
||||||
|
|
||||||
int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), void *param);
|
int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), void *param);
|
||||||
|
|
||||||
|
void taosHashEmpty(SHashObj *pHashObj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clean up hash table
|
* clean up hash table
|
||||||
* @param handle
|
* @param handle
|
||||||
*/
|
*/
|
||||||
void taosHashCleanup(SHashObj *pHashObj);
|
void taosHashCleanup(SHashObj *pHashObj);
|
||||||
|
|
||||||
/*
|
|
||||||
void *SHashMutableIterator* taosHashCreateIter(SHashObj *pHashObj, void *);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param pHashObj
|
* @param pHashObj
|
||||||
|
|
|
@ -313,10 +313,10 @@ void* taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d != NULL) {
|
if (d != NULL) {
|
||||||
memcpy(d, GET_HASH_NODE_DATA(pNode), dsize);
|
memcpy(d, GET_HASH_NODE_DATA(pNode), pNode->dataLen);
|
||||||
} else {
|
|
||||||
data = GET_HASH_NODE_DATA(pNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data = GET_HASH_NODE_DATA(pNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pHashObj->type == HASH_ENTRY_LOCK) {
|
if (pHashObj->type == HASH_ENTRY_LOCK) {
|
||||||
|
@ -472,38 +472,49 @@ int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), voi
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosHashCleanup(SHashObj *pHashObj) {
|
void taosHashEmpty(SHashObj *pHashObj) {
|
||||||
if (pHashObj == NULL) {
|
if (pHashObj == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uDebug("hash:%p cleanup hash table", pHashObj);
|
||||||
|
|
||||||
SHashNode *pNode, *pNext;
|
SHashNode *pNode, *pNext;
|
||||||
|
|
||||||
__wr_lock(&pHashObj->lock, pHashObj->type);
|
__wr_lock(&pHashObj->lock, pHashObj->type);
|
||||||
|
|
||||||
if (pHashObj->hashList) {
|
for (int32_t i = 0; i < pHashObj->capacity; ++i) {
|
||||||
for (int32_t i = 0; i < pHashObj->capacity; ++i) {
|
SHashEntry *pEntry = pHashObj->hashList[i];
|
||||||
SHashEntry *pEntry = pHashObj->hashList[i];
|
if (pEntry->num == 0) {
|
||||||
if (pEntry->num == 0) {
|
assert(pEntry->next == 0);
|
||||||
assert(pEntry->next == 0);
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
pNode = pEntry->next;
|
|
||||||
assert(pNode != NULL);
|
|
||||||
|
|
||||||
while (pNode) {
|
|
||||||
pNext = pNode->next;
|
|
||||||
FREE_HASH_NODE(pHashObj, pNode);
|
|
||||||
|
|
||||||
pNode = pNext;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(pHashObj->hashList);
|
pNode = pEntry->next;
|
||||||
|
assert(pNode != NULL);
|
||||||
|
|
||||||
|
while (pNode) {
|
||||||
|
pNext = pNode->next;
|
||||||
|
FREE_HASH_NODE(pHashObj, pNode);
|
||||||
|
|
||||||
|
pNode = pNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
pEntry->num = 0;
|
||||||
|
pEntry->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pHashObj->size = 0;
|
||||||
__wr_unlock(&pHashObj->lock, pHashObj->type);
|
__wr_unlock(&pHashObj->lock, pHashObj->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void taosHashCleanup(SHashObj *pHashObj) {
|
||||||
|
if (pHashObj == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosHashEmpty(pHashObj);
|
||||||
|
tfree(pHashObj->hashList);
|
||||||
|
|
||||||
// destroy mem block
|
// destroy mem block
|
||||||
size_t memBlock = taosArrayGetSize(pHashObj->pMemBlock);
|
size_t memBlock = taosArrayGetSize(pHashObj->pMemBlock);
|
||||||
|
|
|
@ -101,8 +101,7 @@ int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rpara
|
||||||
return syncCode;
|
return syncCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t vnodeCheckWrite(void *vparam) {
|
static int32_t vnodeCheckWrite(SVnodeObj *pVnode) {
|
||||||
SVnodeObj *pVnode = vparam;
|
|
||||||
if (!(pVnode->accessState & TSDB_VN_WRITE_ACCCESS)) {
|
if (!(pVnode->accessState & TSDB_VN_WRITE_ACCCESS)) {
|
||||||
vDebug("vgId:%d, no write auth, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
|
vDebug("vgId:%d, no write auth, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
|
||||||
return TSDB_CODE_VND_NO_WRITE_AUTH;
|
return TSDB_CODE_VND_NO_WRITE_AUTH;
|
||||||
|
@ -216,29 +215,21 @@ static int32_t vnodeProcessUpdateTagValMsg(SVnodeObj *pVnode, void *pCont, SRspR
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t vnodeWriteToWQueue(void *vparam, void *wparam, int32_t qtype, void *rparam) {
|
static SVWriteMsg *vnodeBuildVWriteMsg(SVnodeObj *pVnode, SWalHead *pHead, int32_t qtype, SRpcMsg *pRpcMsg) {
|
||||||
SVnodeObj *pVnode = vparam;
|
|
||||||
SWalHead * pHead = wparam;
|
|
||||||
int32_t code = 0;
|
|
||||||
|
|
||||||
if (qtype == TAOS_QTYPE_RPC) {
|
|
||||||
code = vnodeCheckWrite(pVnode);
|
|
||||||
if (code != TSDB_CODE_SUCCESS) return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pHead->len > TSDB_MAX_WAL_SIZE) {
|
if (pHead->len > TSDB_MAX_WAL_SIZE) {
|
||||||
vError("vgId:%d, wal len:%d exceeds limit, hver:%" PRIu64, pVnode->vgId, pHead->len, pHead->version);
|
vError("vgId:%d, wal len:%d exceeds limit, hver:%" PRIu64, pVnode->vgId, pHead->len, pHead->version);
|
||||||
return TSDB_CODE_WAL_SIZE_LIMIT;
|
terrno = TSDB_CODE_WAL_SIZE_LIMIT;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t size = sizeof(SVWriteMsg) + sizeof(SWalHead) + pHead->len;
|
int32_t size = sizeof(SVWriteMsg) + sizeof(SWalHead) + pHead->len;
|
||||||
SVWriteMsg *pWrite = taosAllocateQitem(size);
|
SVWriteMsg *pWrite = taosAllocateQitem(size);
|
||||||
if (pWrite == NULL) {
|
if (pWrite == NULL) {
|
||||||
return TSDB_CODE_VND_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_VND_OUT_OF_MEMORY;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rparam != NULL) {
|
if (pRpcMsg != NULL) {
|
||||||
SRpcMsg *pRpcMsg = rparam;
|
|
||||||
pWrite->rpcMsg = *pRpcMsg;
|
pWrite->rpcMsg = *pRpcMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,6 +239,21 @@ int32_t vnodeWriteToWQueue(void *vparam, void *wparam, int32_t qtype, void *rpar
|
||||||
|
|
||||||
atomic_add_fetch_32(&pVnode->refCount, 1);
|
atomic_add_fetch_32(&pVnode->refCount, 1);
|
||||||
|
|
||||||
|
return pWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t vnodeWriteToWQueueImp(SVWriteMsg *pWrite) {
|
||||||
|
SVnodeObj *pVnode = pWrite->pVnode;
|
||||||
|
|
||||||
|
if (pWrite->qtype == TAOS_QTYPE_RPC) {
|
||||||
|
int32_t code = vnodeCheckWrite(pVnode);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosFreeQitem(pWrite);
|
||||||
|
vnodeRelease(pVnode);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t queued = atomic_add_fetch_32(&pVnode->queuedWMsg, 1);
|
int32_t queued = atomic_add_fetch_32(&pVnode->queuedWMsg, 1);
|
||||||
if (queued > MAX_QUEUED_MSG_NUM) {
|
if (queued > MAX_QUEUED_MSG_NUM) {
|
||||||
int32_t ms = (queued / MAX_QUEUED_MSG_NUM) * 10 + 3;
|
int32_t ms = (queued / MAX_QUEUED_MSG_NUM) * 10 + 3;
|
||||||
|
@ -256,15 +262,25 @@ int32_t vnodeWriteToWQueue(void *vparam, void *wparam, int32_t qtype, void *rpar
|
||||||
taosMsleep(ms);
|
taosMsleep(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
code = vnodePerformFlowCtrl(pWrite);
|
|
||||||
if (code != 0) return 0;
|
|
||||||
|
|
||||||
vTrace("vgId:%d, write into vwqueue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedWMsg);
|
vTrace("vgId:%d, write into vwqueue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedWMsg);
|
||||||
|
|
||||||
taosWriteQitem(pVnode->wqueue, qtype, pWrite);
|
taosWriteQitem(pVnode->wqueue, pWrite->qtype, pWrite);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t vnodeWriteToWQueue(void *vparam, void *wparam, int32_t qtype, void *rparam) {
|
||||||
|
SVWriteMsg *pWrite = vnodeBuildVWriteMsg(vparam, wparam, qtype, rparam);
|
||||||
|
if (pWrite == NULL) {
|
||||||
|
assert(terrno != 0);
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = vnodePerformFlowCtrl(pWrite);
|
||||||
|
if (code != 0) return 0;
|
||||||
|
|
||||||
|
return vnodeWriteToWQueueImp(pWrite);
|
||||||
|
}
|
||||||
|
|
||||||
void vnodeFreeFromWQueue(void *vparam, SVWriteMsg *pWrite) {
|
void vnodeFreeFromWQueue(void *vparam, SVWriteMsg *pWrite) {
|
||||||
SVnodeObj *pVnode = vparam;
|
SVnodeObj *pVnode = vparam;
|
||||||
|
|
||||||
|
@ -294,7 +310,10 @@ static void vnodeFlowCtrlMsgToWQueue(void *param, void *tmrId) {
|
||||||
vDebug("vgId:%d, msg:%p, write into vwqueue after flowctrl, retry:%d", pVnode->vgId, pWrite,
|
vDebug("vgId:%d, msg:%p, write into vwqueue after flowctrl, retry:%d", pVnode->vgId, pWrite,
|
||||||
pWrite->processedCount);
|
pWrite->processedCount);
|
||||||
pWrite->processedCount = 0;
|
pWrite->processedCount = 0;
|
||||||
taosWriteQitem(pVnode->wqueue, pWrite->qtype, pWrite);
|
code = vnodeWriteToWQueueImp(pWrite);
|
||||||
|
if (code != 0) {
|
||||||
|
dnodeSendRpcVWriteRsp(pWrite->pVnode, pWrite, code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,4 +337,4 @@ static int32_t vnodePerformFlowCtrl(SVWriteMsg *pWrite) {
|
||||||
pWrite->processedCount);
|
pWrite->processedCount);
|
||||||
return TSDB_CODE_VND_ACTION_IN_PROGRESS;
|
return TSDB_CODE_VND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,6 +28,7 @@ class TDTestCase:
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
time.sleep(5)
|
||||||
tdSql.execute("use log")
|
tdSql.execute("use log")
|
||||||
|
|
||||||
tdSql.execute("create table cpustrm as select count(*), avg(cpu_taosd), max(cpu_taosd), min(cpu_taosd), avg(cpu_system), max(cpu_cores), min(cpu_cores), last(cpu_cores) from log.dn1 interval(4s)")
|
tdSql.execute("create table cpustrm as select count(*), avg(cpu_taosd), max(cpu_taosd), min(cpu_taosd), avg(cpu_system), max(cpu_cores), min(cpu_cores), last(cpu_cores) from log.dn1 interval(4s)")
|
||||||
|
|
|
@ -106,7 +106,7 @@ while $x < 5000
|
||||||
endw
|
endw
|
||||||
|
|
||||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||||
sleep 3000
|
sleep 1000
|
||||||
system sh/exec.sh -n dnode1 -s start
|
system sh/exec.sh -n dnode1 -s start
|
||||||
print ================== server restart completed
|
print ================== server restart completed
|
||||||
sql connect
|
sql connect
|
||||||
|
|
|
@ -244,3 +244,120 @@ if $data00 != -2.000000000 then
|
||||||
print expect -2.000000000, actual: $data00
|
print expect -2.000000000, actual: $data00
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql create table tm1 (ts timestamp, k int);
|
||||||
|
sql insert into tm1 values('2020-10-30 18:11:56.680', -1000);
|
||||||
|
sql insert into tm1 values('2020-11-19 18:11:45.773', NULL);
|
||||||
|
sql insert into tm1 values('2020-12-09 18:11:17.098', NULL);
|
||||||
|
sql insert into tm1 values('2020-12-20 18:11:49.412', 1);
|
||||||
|
sql insert into tm1 values('2020-12-23 18:11:50.412', 2);
|
||||||
|
sql insert into tm1 values('2020-12-28 18:11:52.412', 3);
|
||||||
|
|
||||||
|
print =====================> td-2610
|
||||||
|
sql select twa(k)from tm1 where ts>='2020-11-19 18:11:45.773' and ts<='2020-12-9 18:11:17.098'
|
||||||
|
if $rows != 0 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
print =====================> td-2609
|
||||||
|
sql select apercentile(k, 50) from tm1 where ts>='2020-10-30 18:11:56.680' and ts<='2020-12-09 18:11:17.098'
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != -1000.000000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||||
|
sleep 1000
|
||||||
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
print ================== server restart completed
|
||||||
|
sql connect
|
||||||
|
sleep 500
|
||||||
|
|
||||||
|
sql use m_func_db0
|
||||||
|
|
||||||
|
print =====================> td-2583
|
||||||
|
sql select min(k) from tm1 where ts>='2020-11-19 18:11:45.773' and ts<='2020-12-20 18:11:49.412'
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 1 then
|
||||||
|
print expect 1, actual: $data00
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
print =====================> td-2601
|
||||||
|
sql select count(*) from tm1 where ts<='2020-6-1 00:00:00' and ts>='2020-1-1 00:00:00' interval(1n) fill(NULL)
|
||||||
|
if $rows != 0 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
print =====================> td-2615
|
||||||
|
sql select last(ts) from tm1 interval(17a) limit 776 offset 3
|
||||||
|
if $rows != 3 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql select last(ts) from tm1 interval(17a) limit 1000 offset 4
|
||||||
|
if $rows != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql select last(ts) from tm1 interval(17a) order by ts desc limit 1000 offset 0
|
||||||
|
if $rows != 6 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
print ==================> td-2624
|
||||||
|
sql create table tm2(ts timestamp, k int, b binary(12));
|
||||||
|
sql insert into tm2 values('2011-01-02 18:42:45.326', -1,'abc');
|
||||||
|
sql insert into tm2 values('2020-07-30 17:44:06.283', 0, null);
|
||||||
|
sql insert into tm2 values('2020-07-30 17:44:19.578', 9999999, null);
|
||||||
|
sql insert into tm2 values('2020-07-30 17:46:06.417', NULL, null);
|
||||||
|
sql insert into tm2 values('2020-11-09 18:42:25.538', 0, null);
|
||||||
|
sql insert into tm2 values('2020-12-29 17:43:11.641', 0, null);
|
||||||
|
sql insert into tm2 values('2020-12-29 18:43:17.129', 0, null);
|
||||||
|
sql insert into tm2 values('2020-12-29 18:46:19.109', NULL, null);
|
||||||
|
sql insert into tm2 values('2021-01-03 18:40:40.065', 0, null);
|
||||||
|
|
||||||
|
sql select twa(k),first(ts) from tm2 where k <50 interval(17s);
|
||||||
|
if $rows != 6 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != @11-01-02 18:42:42.000@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data02 != @11-01-02 18:42:45.326@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data10 != @20-07-30 17:43:59.000@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data21 != 0.000000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql select twa(k),first(ts) from tm2 where k <50 interval(17s) order by ts desc;
|
||||||
|
if $rows != 6 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql select twa(k),first(ts),count(k),first(k) from tm2 interval(17s) limit 20 offset 0;
|
||||||
|
if $rows != 9 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != @11-01-02 18:42:42.000@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data10 != @20-07-30 17:43:59.000@ then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
|
@ -99,9 +99,11 @@ print ========= step2 alter db
|
||||||
sql_error alter database d1 replica 1
|
sql_error alter database d1 replica 1
|
||||||
sql_error alter database d2 replica 1
|
sql_error alter database d2 replica 1
|
||||||
sql_error alter database d3 replica 1
|
sql_error alter database d3 replica 1
|
||||||
|
sql_error alter database d4 replica 1
|
||||||
sql alter database d1 replica 2
|
sql alter database d1 replica 2
|
||||||
sql alter database d2 replica 2
|
sql alter database d2 replica 2
|
||||||
sql alter database d3 replica 2
|
sql alter database d3 replica 2
|
||||||
|
sql alter database d4 replica 2
|
||||||
|
|
||||||
$x = 0
|
$x = 0
|
||||||
a2:
|
a2:
|
||||||
|
@ -129,9 +131,16 @@ if $data03 != 2 then
|
||||||
goto a2
|
goto a2
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql show d4.vgroups
|
||||||
|
print online vnodes $data03
|
||||||
|
if $data03 != 2 then
|
||||||
|
goto a2
|
||||||
|
endi
|
||||||
|
|
||||||
sql alter database d1 replica 1
|
sql alter database d1 replica 1
|
||||||
sql alter database d2 replica 1
|
sql alter database d2 replica 1
|
||||||
sql alter database d3 replica 1
|
sql alter database d3 replica 1
|
||||||
|
sql alter database d4 replica 1
|
||||||
|
|
||||||
$x = 0
|
$x = 0
|
||||||
a1:
|
a1:
|
||||||
|
@ -159,6 +168,27 @@ if $data03 != 1 then
|
||||||
goto a1
|
goto a1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql show d4.vgroups
|
||||||
|
print online vnodes $data03
|
||||||
|
if $data03 != 1 then
|
||||||
|
goto a1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql show dnodes
|
||||||
|
print $data00 $data01 $data02 $data03
|
||||||
|
print $data10 $data11 $data12 $data13
|
||||||
|
print $data20 $data21 $data22 $data23
|
||||||
|
|
||||||
|
if $data02 != 0 then
|
||||||
|
goto a1
|
||||||
|
endi
|
||||||
|
if $data12 != 2 then
|
||||||
|
goto a1
|
||||||
|
endi
|
||||||
|
if $data22 != 2 then
|
||||||
|
goto a1
|
||||||
|
endi
|
||||||
|
|
||||||
print ========= step3
|
print ========= step3
|
||||||
sql reset query cache
|
sql reset query cache
|
||||||
sleep 100
|
sleep 100
|
||||||
|
@ -192,6 +222,7 @@ print ========= step4 alter db
|
||||||
sql alter database d1 replica 2
|
sql alter database d1 replica 2
|
||||||
sql alter database d2 replica 2
|
sql alter database d2 replica 2
|
||||||
sql alter database d3 replica 2
|
sql alter database d3 replica 2
|
||||||
|
sql alter database d4 replica 2
|
||||||
|
|
||||||
$x = 0
|
$x = 0
|
||||||
step4:
|
step4:
|
||||||
|
@ -219,6 +250,12 @@ if $data03 != 2 then
|
||||||
goto step4
|
goto step4
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
sql show d4.vgroups
|
||||||
|
print online vnodes $data03
|
||||||
|
if $data03 != 2 then
|
||||||
|
goto step4
|
||||||
|
endi
|
||||||
|
|
||||||
sql insert into d1.t1 values(now, 3)
|
sql insert into d1.t1 values(now, 3)
|
||||||
sql insert into d2.t2 values(now, 3)
|
sql insert into d2.t2 values(now, 3)
|
||||||
sql insert into d3.t3 values(now, 3)
|
sql insert into d3.t3 values(now, 3)
|
||||||
|
@ -286,4 +323,5 @@ sql select * from d4.t4
|
||||||
|
|
||||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||||
system sh/exec.sh -n dnode2 -s stop -x SIGINT
|
system sh/exec.sh -n dnode2 -s stop -x SIGINT
|
||||||
system sh/exec.sh -n dnode3 -s stop -x SIGINT
|
system sh/exec.sh -n dnode3 -s stop -x SIGINT
|
||||||
|
system sh/exec.sh -n dnode4 -s stop -x SIGINT
|
Loading…
Reference in New Issue