Merge branch 'develop' into feature/alter
This commit is contained in:
commit
55aa897397
|
@ -64,7 +64,7 @@ matrix:
|
||||||
memError=`grep -m 1 'ERROR SUMMARY' mem-error-out.txt | awk '{print $4}'`
|
memError=`grep -m 1 'ERROR SUMMARY' mem-error-out.txt | awk '{print $4}'`
|
||||||
|
|
||||||
if [ -n "$memError" ]; then
|
if [ -n "$memError" ]; then
|
||||||
if [ "$memError" -gt 16 ] && [ "$defiMemError" -gt 0 ]; then
|
if [ "$memError" -gt 16 ] || [ "$defiMemError" -gt 0 ]; then
|
||||||
echo -e "${RED} ## Memory errors number valgrind reports is $memError.\
|
echo -e "${RED} ## Memory errors number valgrind reports is $memError.\
|
||||||
Definitely lost is $defiMemError. More than our threshold! ## ${NC}"
|
Definitely lost is $defiMemError. More than our threshold! ## ${NC}"
|
||||||
travis_terminate $memError
|
travis_terminate $memError
|
||||||
|
|
|
@ -196,14 +196,14 @@ STableMetaInfo* tscGetMetaInfo(SQueryInfo *pQueryInfo, int32_t tableIndex);
|
||||||
SQueryInfo *tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex);
|
SQueryInfo *tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex);
|
||||||
int32_t tscGetQueryInfoDetailSafely(SSqlCmd *pCmd, int32_t subClauseIndex, SQueryInfo** pQueryInfo);
|
int32_t tscGetQueryInfoDetailSafely(SSqlCmd *pCmd, int32_t subClauseIndex, SQueryInfo** pQueryInfo);
|
||||||
|
|
||||||
void tscClearMeterMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache);
|
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache);
|
||||||
|
|
||||||
STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pTableMeta,
|
STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pTableMeta,
|
||||||
SVgroupsInfo* vgroupList, SArray* pTagCols);
|
SVgroupsInfo* vgroupList, SArray* pTagCols);
|
||||||
|
|
||||||
STableMetaInfo* tscAddEmptyMetaInfo(SQueryInfo *pQueryInfo);
|
STableMetaInfo* tscAddEmptyMetaInfo(SQueryInfo *pQueryInfo);
|
||||||
int32_t tscAddSubqueryInfo(SSqlCmd *pCmd);
|
int32_t tscAddSubqueryInfo(SSqlCmd *pCmd);
|
||||||
void tscFreeSubqueryInfo(SSqlCmd* pCmd);
|
void tscFreeQueryInfo(SSqlCmd* pCmd);
|
||||||
void tscClearSubqueryInfo(SSqlCmd* pCmd);
|
void tscClearSubqueryInfo(SSqlCmd* pCmd);
|
||||||
|
|
||||||
int tscGetSTableVgroupInfo(SSqlObj* pSql, int32_t clauseIndex);
|
int tscGetSTableVgroupInfo(SSqlObj* pSql, int32_t clauseIndex);
|
||||||
|
|
|
@ -298,6 +298,7 @@ typedef struct STscObj {
|
||||||
char sversion[TSDB_VERSION_LEN];
|
char sversion[TSDB_VERSION_LEN];
|
||||||
char writeAuth : 1;
|
char writeAuth : 1;
|
||||||
char superAuth : 1;
|
char superAuth : 1;
|
||||||
|
void* pMgmtConn;
|
||||||
struct SSqlObj * pSql;
|
struct SSqlObj * pSql;
|
||||||
struct SSqlObj * pHb;
|
struct SSqlObj * pHb;
|
||||||
struct SSqlObj * sqlList;
|
struct SSqlObj * sqlList;
|
||||||
|
@ -359,7 +360,7 @@ typedef struct SSqlStream {
|
||||||
struct SSqlStream *prev, *next;
|
struct SSqlStream *prev, *next;
|
||||||
} SSqlStream;
|
} SSqlStream;
|
||||||
|
|
||||||
int32_t tscInitRpc(const char *user, const char *secret);
|
int32_t tscInitRpc(const char *user, const char *secret, void** pMgmtConn);
|
||||||
void tscInitMsgsFp();
|
void tscInitMsgsFp();
|
||||||
|
|
||||||
int tsParseSql(SSqlObj *pSql, bool multiVnodeInsertion);
|
int tsParseSql(SSqlObj *pSql, bool multiVnodeInsertion);
|
||||||
|
@ -427,9 +428,7 @@ int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
||||||
char * tscGetResultColumnChr(SSqlRes *pRes, SQueryInfo *pQueryInfo, int32_t column);
|
char * tscGetResultColumnChr(SSqlRes *pRes, SQueryInfo *pQueryInfo, int32_t column);
|
||||||
|
|
||||||
extern void * pVnodeConn;
|
extern void * pVnodeConn;
|
||||||
extern void * pTscMgmtConn;
|
|
||||||
extern void * tscCacheHandle;
|
extern void * tscCacheHandle;
|
||||||
extern int slaveIndex;
|
|
||||||
extern void * tscTmr;
|
extern void * tscTmr;
|
||||||
extern void * tscQhandle;
|
extern void * tscQhandle;
|
||||||
extern int tscKeepConn[];
|
extern int tscKeepConn[];
|
||||||
|
|
|
@ -46,7 +46,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const
|
||||||
pSql->signature = pSql;
|
pSql->signature = pSql;
|
||||||
pSql->param = param;
|
pSql->param = param;
|
||||||
pSql->pTscObj = pObj;
|
pSql->pTscObj = pObj;
|
||||||
pSql->maxRetry = 1;
|
pSql->maxRetry = TSDB_REPLICA_MAX_NUM;
|
||||||
pSql->fp = fp;
|
pSql->fp = fp;
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
||||||
|
|
|
@ -733,7 +733,7 @@ int32_t tscSetTableId(STableMetaInfo* pTableMetaInfo, SSQLToken* pzTableName, SS
|
||||||
*/
|
*/
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
if (strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
|
if (strncasecmp(oldName, pTableMetaInfo->name, tListLen(pTableMetaInfo->name)) != 0) {
|
||||||
tscClearMeterMetaInfo(pTableMetaInfo, false);
|
tscClearTableMetaInfo(pTableMetaInfo, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(pTableMetaInfo->pTableMeta == NULL);
|
assert(pTableMetaInfo->pTableMeta == NULL);
|
||||||
|
@ -2477,6 +2477,10 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd*
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pQueryInfo->colList == NULL) {
|
||||||
|
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
|
pQueryInfo->groupbyExpr.numOfGroupCols = pList->nExpr;
|
||||||
if (pList->nExpr > TSDB_MAX_TAGS) {
|
if (pList->nExpr > TSDB_MAX_TAGS) {
|
||||||
return invalidSqlErrMsg(pQueryInfo->msg, msg1);
|
return invalidSqlErrMsg(pQueryInfo->msg, msg1);
|
||||||
|
@ -3545,7 +3549,7 @@ static int32_t setTableCondForSTableQuery(SQueryInfo* pQueryInfo, const char* ac
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SStringBuilder sb1;
|
SStringBuilder sb1 = { 0 };
|
||||||
taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
|
taosStringBuilderAppendStringLen(&sb1, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN);
|
||||||
|
|
||||||
char db[TSDB_TABLE_ID_LEN] = {0};
|
char db[TSDB_TABLE_ID_LEN] = {0};
|
||||||
|
@ -4915,7 +4919,7 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
|
||||||
list.num = 1;
|
list.num = 1;
|
||||||
list.ids[0] = colIndex;
|
list.ids[0] = colIndex;
|
||||||
|
|
||||||
insertResultField(pQueryInfo, size - 1, &list, pSchema->bytes, pSchema->type, pSchema->name, pExpr);
|
insertResultField(pQueryInfo, size, &list, pSchema->bytes, pSchema->type, pSchema->name, pExpr);
|
||||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, size - 1);
|
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, size - 1);
|
||||||
pInfo->visible = false;
|
pInfo->visible = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,6 +190,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscSendMsgToServer(SSqlObj *pSql) {
|
int tscSendMsgToServer(SSqlObj *pSql) {
|
||||||
|
STscObj* pObj = pSql->pTscObj;
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
|
||||||
char *pMsg = rpcMallocCont(pCmd->payloadLen);
|
char *pMsg = rpcMallocCont(pCmd->payloadLen);
|
||||||
|
@ -223,7 +224,7 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
||||||
.handle = pSql,
|
.handle = pSql,
|
||||||
.code = 0
|
.code = 0
|
||||||
};
|
};
|
||||||
rpcSendRequest(pTscMgmtConn, &pSql->ipList, &rpcMsg);
|
rpcSendRequest(pObj->pMgmtConn, &pSql->ipList, &rpcMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -696,7 +697,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->slidingTimeUnit = pQueryInfo->slidingTimeUnit;
|
pQueryMsg->slidingTimeUnit = pQueryInfo->slidingTimeUnit;
|
||||||
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
|
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
|
||||||
pQueryMsg->numOfTags = htonl(numOfTags);
|
pQueryMsg->numOfTags = htonl(numOfTags);
|
||||||
|
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
|
||||||
pQueryMsg->queryType = htons(pQueryInfo->type);
|
pQueryMsg->queryType = htons(pQueryInfo->type);
|
||||||
|
|
||||||
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
|
@ -915,6 +916,14 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pQueryInfo->tagCond.tbnameCond.cond == NULL) {
|
||||||
|
*pMsg = 0;
|
||||||
|
pMsg++;
|
||||||
|
} else {
|
||||||
|
strcpy(pMsg, pQueryInfo->tagCond.tbnameCond.cond);
|
||||||
|
pMsg += strlen(pQueryInfo->tagCond.tbnameCond.cond) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
// tbname in/like query expression should be sent to mgmt node
|
// tbname in/like query expression should be sent to mgmt node
|
||||||
msgLen = pMsg - pStart;
|
msgLen = pMsg - pStart;
|
||||||
|
|
||||||
|
@ -1847,7 +1856,7 @@ int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pCmd->msgType = TSDB_MSG_TYPE_CM_HEARTBEAT;
|
pCmd->msgType = TSDB_MSG_TYPE_CM_HEARTBEAT;
|
||||||
|
|
||||||
assert(msgLen + minMsgSize() <= size);
|
assert(msgLen + minMsgSize() <= size);
|
||||||
return msgLen;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
||||||
|
@ -2599,7 +2608,7 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) {
|
||||||
|
|
||||||
// if (pSql->fp != NULL && pSql->pStream == NULL) {
|
// if (pSql->fp != NULL && pSql->pStream == NULL) {
|
||||||
// pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
// pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||||
// tscFreeSubqueryInfo(pCmd);
|
// tscFreeQueryInfo(pCmd);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
tscTrace("%p allocate new pSqlObj:%p to get stable vgroupInfo", pSql, pNew);
|
tscTrace("%p allocate new pSqlObj:%p to get stable vgroupInfo", pSql, pNew);
|
||||||
|
|
|
@ -66,7 +66,8 @@ STscObj *taosConnectImpl(const char *ip, const char *user, const char *pass, con
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tscInitRpc(user, pass) != 0) {
|
void* pMgmtConn = NULL;
|
||||||
|
if (tscInitRpc(user, pass, &pMgmtConn) != 0) {
|
||||||
terrno = TSDB_CODE_NETWORK_UNAVAIL;
|
terrno = TSDB_CODE_NETWORK_UNAVAIL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -118,6 +119,7 @@ STscObj *taosConnectImpl(const char *ip, const char *user, const char *pass, con
|
||||||
strtolower(pObj->db, tmp);
|
strtolower(pObj->db, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pObj->pMgmtConn = pMgmtConn;
|
||||||
pthread_mutex_init(&pObj->mutex, NULL);
|
pthread_mutex_init(&pObj->mutex, NULL);
|
||||||
|
|
||||||
SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
|
SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
|
||||||
|
|
|
@ -147,7 +147,7 @@ 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);
|
||||||
tscClearMeterMetaInfo(pTableMetaInfo, true);
|
tscClearTableMetaInfo(pTableMetaInfo, true);
|
||||||
|
|
||||||
tscSetRetryTimer(pStream, pStream->pSql, retryDelay);
|
tscSetRetryTimer(pStream, pStream->pSql, retryDelay);
|
||||||
return;
|
return;
|
||||||
|
@ -177,7 +177,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
||||||
if (pSql == NULL || numOfRows < 0) {
|
if (pSql == NULL || numOfRows < 0) {
|
||||||
int64_t retryDelayTime = tscGetRetryDelayTime(pStream->slidingTime, pStream->precision);
|
int64_t retryDelayTime = tscGetRetryDelayTime(pStream->slidingTime, pStream->precision);
|
||||||
tscError("%p stream:%p, retrieve data failed, code:%d, retry in %" PRId64 "ms", pSql, pStream, numOfRows, retryDelayTime);
|
tscError("%p stream:%p, retrieve data failed, code:%d, retry in %" PRId64 "ms", pSql, pStream, numOfRows, retryDelayTime);
|
||||||
tscClearMeterMetaInfo(pTableMetaInfo, true);
|
tscClearTableMetaInfo(pTableMetaInfo, true);
|
||||||
|
|
||||||
tscSetRetryTimer(pStream, pStream->pSql, retryDelayTime);
|
tscSetRetryTimer(pStream, pStream->pSql, retryDelayTime);
|
||||||
return;
|
return;
|
||||||
|
@ -259,7 +259,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
||||||
pStream->numOfRes);
|
pStream->numOfRes);
|
||||||
|
|
||||||
// release the metric/meter meta information reference, so data in cache can be updated
|
// release the metric/meter meta information reference, so data in cache can be updated
|
||||||
tscClearMeterMetaInfo(pTableMetaInfo, false);
|
tscClearTableMetaInfo(pTableMetaInfo, false);
|
||||||
tscSetNextLaunchTimer(pStream, pSql);
|
tscSetNextLaunchTimer(pStream, pSql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,6 @@
|
||||||
|
|
||||||
// global, not configurable
|
// global, not configurable
|
||||||
void * pVnodeConn;
|
void * pVnodeConn;
|
||||||
void * pVMeterConn;
|
|
||||||
void * pTscMgmtConn;
|
|
||||||
void * pSlaveConn;
|
|
||||||
void * tscCacheHandle;
|
void * tscCacheHandle;
|
||||||
int slaveIndex;
|
int slaveIndex;
|
||||||
void * tscTmr;
|
void * tscTmr;
|
||||||
|
@ -54,7 +51,7 @@ void tscCheckDiskUsage(void *para, void *unused) {
|
||||||
taosTmrReset(tscCheckDiskUsage, 1000, NULL, tscTmr, &tscCheckDiskUsageTmr);
|
taosTmrReset(tscCheckDiskUsage, 1000, NULL, tscTmr, &tscCheckDiskUsageTmr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tscInitRpc(const char *user, const char *secret) {
|
int32_t tscInitRpc(const char *user, const char *secret, void** pMgmtConn) {
|
||||||
SRpcInit rpcInit;
|
SRpcInit rpcInit;
|
||||||
char secretEncrypt[32] = {0};
|
char secretEncrypt[32] = {0};
|
||||||
taosEncryptPass((uint8_t *)secret, strlen(secret), secretEncrypt);
|
taosEncryptPass((uint8_t *)secret, strlen(secret), secretEncrypt);
|
||||||
|
@ -80,7 +77,7 @@ int32_t tscInitRpc(const char *user, const char *secret) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTscMgmtConn == NULL) {
|
if (*pMgmtConn == NULL) {
|
||||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||||
rpcInit.localIp = tsLocalIp;
|
rpcInit.localIp = tsLocalIp;
|
||||||
rpcInit.localPort = 0;
|
rpcInit.localPort = 0;
|
||||||
|
@ -96,8 +93,8 @@ int32_t tscInitRpc(const char *user, const char *secret) {
|
||||||
rpcInit.spi = 1;
|
rpcInit.spi = 1;
|
||||||
rpcInit.secret = secretEncrypt;
|
rpcInit.secret = secretEncrypt;
|
||||||
|
|
||||||
pTscMgmtConn = rpcOpen(&rpcInit);
|
*pMgmtConn = rpcOpen(&rpcInit);
|
||||||
if (pTscMgmtConn == NULL) {
|
if (*pMgmtConn == NULL) {
|
||||||
tscError("failed to init connection to mgmt");
|
tscError("failed to init connection to mgmt");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -211,11 +208,6 @@ void taos_cleanup() {
|
||||||
pVnodeConn = NULL;
|
pVnodeConn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTscMgmtConn != NULL) {
|
|
||||||
rpcClose(pTscMgmtConn);
|
|
||||||
pTscMgmtConn = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
taosTmrCleanUp(tscTmr);
|
taosTmrCleanUp(tscTmr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -337,7 +337,7 @@ void tscResetSqlCmdObj(SSqlCmd* pCmd) {
|
||||||
pCmd->pTableList= NULL;
|
pCmd->pTableList= NULL;
|
||||||
|
|
||||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||||
tscFreeSubqueryInfo(pCmd);
|
tscFreeQueryInfo(pCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -761,6 +761,8 @@ void tscCloseTscObj(STscObj* pObj) {
|
||||||
tscFreeSqlObj(pSql);
|
tscFreeSqlObj(pSql);
|
||||||
|
|
||||||
sem_destroy(&pSql->rspSem);
|
sem_destroy(&pSql->rspSem);
|
||||||
|
rpcClose(pObj->pMgmtConn);
|
||||||
|
|
||||||
pthread_mutex_destroy(&pObj->mutex);
|
pthread_mutex_destroy(&pObj->mutex);
|
||||||
|
|
||||||
tscTrace("%p DB connection is closed", pObj);
|
tscTrace("%p DB connection is closed", pObj);
|
||||||
|
@ -1459,7 +1461,7 @@ bool tscShouldFreeHeatBeat(SSqlObj* pHb) {
|
||||||
|
|
||||||
void tscCleanSqlCmd(SSqlCmd* pCmd) {
|
void tscCleanSqlCmd(SSqlCmd* pCmd) {
|
||||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||||
tscFreeSubqueryInfo(pCmd);
|
tscFreeQueryInfo(pCmd);
|
||||||
|
|
||||||
uint32_t allocSize = pCmd->allocSize;
|
uint32_t allocSize = pCmd->allocSize;
|
||||||
char* allocPtr = pCmd->payload;
|
char* allocPtr = pCmd->payload;
|
||||||
|
@ -1601,7 +1603,7 @@ int32_t tscAddSubqueryInfo(SSqlCmd* pCmd) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doClearSubqueryInfo(SQueryInfo* pQueryInfo) {
|
static void freeQueryInfoImpl(SQueryInfo* pQueryInfo) {
|
||||||
tscTagCondRelease(&pQueryInfo->tagCond);
|
tscTagCondRelease(&pQueryInfo->tagCond);
|
||||||
tscFieldInfoClear(&pQueryInfo->fieldsInfo);
|
tscFieldInfoClear(&pQueryInfo->fieldsInfo);
|
||||||
|
|
||||||
|
@ -1611,6 +1613,11 @@ static void doClearSubqueryInfo(SQueryInfo* pQueryInfo) {
|
||||||
tscColumnListDestroy(pQueryInfo->colList);
|
tscColumnListDestroy(pQueryInfo->colList);
|
||||||
memset(&pQueryInfo->colList, 0, sizeof(pQueryInfo->colList));
|
memset(&pQueryInfo->colList, 0, sizeof(pQueryInfo->colList));
|
||||||
|
|
||||||
|
if (pQueryInfo->groupbyExpr.columnInfo != NULL) {
|
||||||
|
taosArrayDestroy(pQueryInfo->groupbyExpr.columnInfo);
|
||||||
|
pQueryInfo->groupbyExpr.columnInfo = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pQueryInfo->tsBuf = tsBufDestory(pQueryInfo->tsBuf);
|
pQueryInfo->tsBuf = tsBufDestory(pQueryInfo->tsBuf);
|
||||||
|
|
||||||
tfree(pQueryInfo->defaultVal);
|
tfree(pQueryInfo->defaultVal);
|
||||||
|
@ -1619,11 +1626,11 @@ static void doClearSubqueryInfo(SQueryInfo* pQueryInfo) {
|
||||||
void tscClearSubqueryInfo(SSqlCmd* pCmd) {
|
void tscClearSubqueryInfo(SSqlCmd* pCmd) {
|
||||||
for (int32_t i = 0; i < pCmd->numOfClause; ++i) {
|
for (int32_t i = 0; i < pCmd->numOfClause; ++i) {
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i);
|
||||||
doClearSubqueryInfo(pQueryInfo);
|
freeQueryInfoImpl(pQueryInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscFreeSubqueryInfo(SSqlCmd* pCmd) {
|
void tscFreeQueryInfo(SSqlCmd* pCmd) {
|
||||||
if (pCmd == NULL || pCmd->numOfClause == 0) {
|
if (pCmd == NULL || pCmd->numOfClause == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1632,7 +1639,7 @@ void tscFreeSubqueryInfo(SSqlCmd* pCmd) {
|
||||||
char* addr = (char*)pCmd - offsetof(SSqlObj, cmd);
|
char* addr = (char*)pCmd - offsetof(SSqlObj, cmd);
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i);
|
||||||
|
|
||||||
doClearSubqueryInfo(pQueryInfo);
|
freeQueryInfoImpl(pQueryInfo);
|
||||||
tscClearAllTableMetaInfo(pQueryInfo, (const char*)addr, false);
|
tscClearAllTableMetaInfo(pQueryInfo, (const char*)addr, false);
|
||||||
tfree(pQueryInfo);
|
tfree(pQueryInfo);
|
||||||
}
|
}
|
||||||
|
@ -1691,7 +1698,7 @@ void doRemoveTableMetaInfo(SQueryInfo* pQueryInfo, int32_t index, bool removeFro
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index);
|
||||||
|
|
||||||
tscClearMeterMetaInfo(pTableMetaInfo, removeFromCache);
|
tscClearTableMetaInfo(pTableMetaInfo, removeFromCache);
|
||||||
free(pTableMetaInfo);
|
free(pTableMetaInfo);
|
||||||
|
|
||||||
int32_t after = pQueryInfo->numOfTables - index - 1;
|
int32_t after = pQueryInfo->numOfTables - index - 1;
|
||||||
|
@ -1713,13 +1720,18 @@ void tscClearAllTableMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool
|
||||||
tfree(pQueryInfo->pTableMetaInfo);
|
tfree(pQueryInfo->pTableMetaInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscClearMeterMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache) {
|
void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache) {
|
||||||
if (pTableMetaInfo == NULL) {
|
if (pTableMetaInfo == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
taosCacheRelease(tscCacheHandle, (void**)&(pTableMetaInfo->pTableMeta), removeFromCache);
|
taosCacheRelease(tscCacheHandle, (void**)&(pTableMetaInfo->pTableMeta), removeFromCache);
|
||||||
tfree(pTableMetaInfo->vgroupList);
|
tfree(pTableMetaInfo->vgroupList);
|
||||||
|
|
||||||
|
if (pTableMetaInfo->tagColList != NULL) {
|
||||||
|
taosArrayDestroy(pTableMetaInfo->tagColList);
|
||||||
|
pTableMetaInfo->tagColList = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscResetForNextRetrieve(SSqlRes* pRes) {
|
void tscResetForNextRetrieve(SSqlRes* pRes) {
|
||||||
|
|
|
@ -32,6 +32,9 @@ extern "C" {
|
||||||
#define TSKEY int64_t
|
#define TSKEY int64_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// this data type is internally used only in 'in' query to hold the values
|
||||||
|
#define TSDB_DATA_TYPE_ARRAY (TSDB_DATA_TYPE_NCHAR + 1)
|
||||||
|
|
||||||
// Bytes for each type.
|
// Bytes for each type.
|
||||||
extern const int32_t TYPE_BYTES[11];
|
extern const int32_t TYPE_BYTES[11];
|
||||||
// TODO: replace and remove code below
|
// TODO: replace and remove code below
|
||||||
|
@ -141,16 +144,17 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
||||||
#define TSDB_RELATION_GREATER_EQUAL 5
|
#define TSDB_RELATION_GREATER_EQUAL 5
|
||||||
#define TSDB_RELATION_NOT_EQUAL 6
|
#define TSDB_RELATION_NOT_EQUAL 6
|
||||||
#define TSDB_RELATION_LIKE 7
|
#define TSDB_RELATION_LIKE 7
|
||||||
|
#define TSDB_RELATION_IN 8
|
||||||
|
|
||||||
#define TSDB_RELATION_AND 8
|
#define TSDB_RELATION_AND 9
|
||||||
#define TSDB_RELATION_OR 9
|
#define TSDB_RELATION_OR 10
|
||||||
#define TSDB_RELATION_NOT 10
|
#define TSDB_RELATION_NOT 11
|
||||||
|
|
||||||
#define TSDB_BINARY_OP_ADD 11
|
#define TSDB_BINARY_OP_ADD 12
|
||||||
#define TSDB_BINARY_OP_SUBTRACT 12
|
#define TSDB_BINARY_OP_SUBTRACT 13
|
||||||
#define TSDB_BINARY_OP_MULTIPLY 13
|
#define TSDB_BINARY_OP_MULTIPLY 14
|
||||||
#define TSDB_BINARY_OP_DIVIDE 14
|
#define TSDB_BINARY_OP_DIVIDE 15
|
||||||
#define TSDB_BINARY_OP_REMAINDER 15
|
#define TSDB_BINARY_OP_REMAINDER 16
|
||||||
#define TSDB_USERID_LEN 9
|
#define TSDB_USERID_LEN 9
|
||||||
#define TS_PATH_DELIMITER_LEN 1
|
#define TS_PATH_DELIMITER_LEN 1
|
||||||
|
|
||||||
|
|
|
@ -469,6 +469,7 @@ typedef struct {
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
uint16_t queryType; // denote another query process
|
uint16_t queryType; // denote another query process
|
||||||
int16_t numOfOutput; // final output columns numbers
|
int16_t numOfOutput; // final output columns numbers
|
||||||
|
int16_t tagNameRelType; // relation of tag criteria and tbname criteria
|
||||||
int16_t interpoType; // interpolate type
|
int16_t interpoType; // interpolate type
|
||||||
uint64_t defaultVal; // default value array list
|
uint64_t defaultVal; // default value array list
|
||||||
|
|
||||||
|
|
|
@ -279,8 +279,17 @@ SArray *tsdbGetTableList(TsdbQueryHandleT *pQueryHandle);
|
||||||
* @param pTagCond. tag query condition
|
* @param pTagCond. tag query condition
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int32_t tsdbQueryByTagsCond(TsdbRepoT *tsdb, int64_t uid, const char *pTagCond, size_t len, STableGroupInfo *pGroupList,
|
int32_t tsdbQueryByTagsCond(
|
||||||
SColIndex *pColIndex, int32_t numOfCols);
|
TsdbRepoT *tsdb,
|
||||||
|
int64_t uid,
|
||||||
|
const char *pTagCond,
|
||||||
|
size_t len,
|
||||||
|
int16_t tagNameRelType,
|
||||||
|
const char* tbnameCond,
|
||||||
|
STableGroupInfo *pGroupList,
|
||||||
|
SColIndex *pColIndex,
|
||||||
|
int32_t numOfCols
|
||||||
|
);
|
||||||
|
|
||||||
int32_t tsdbGetOneTableGroup(TsdbRepoT *tsdb, int64_t uid, STableGroupInfo *pGroupInfo);
|
int32_t tsdbGetOneTableGroup(TsdbRepoT *tsdb, int64_t uid, STableGroupInfo *pGroupInfo);
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,8 @@ uint8_t getBinaryExprOptr(SSQLToken *pToken);
|
||||||
|
|
||||||
SBuffer exprTreeToBinary(tExprNode* pExprTree);
|
SBuffer exprTreeToBinary(tExprNode* pExprTree);
|
||||||
|
|
||||||
int32_t exprTreeFromBinary(const void* pBuf, size_t size, tExprNode** pExprNode);
|
tExprNode* exprTreeFromBinary(const void* pBuf, size_t size);
|
||||||
|
tExprNode* exprTreeFromTableName(const char* tbnameCond);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#define TDENGINE_TVARIANT_H
|
#define TDENGINE_TVARIANT_H
|
||||||
|
|
||||||
#include "tstoken.h"
|
#include "tstoken.h"
|
||||||
|
#include "tarray.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -31,6 +32,7 @@ typedef struct tVariant {
|
||||||
double dKey;
|
double dKey;
|
||||||
char * pz;
|
char * pz;
|
||||||
wchar_t *wpz;
|
wchar_t *wpz;
|
||||||
|
SArray *arr; // only for 'in' query to hold value list, not value for a field
|
||||||
};
|
};
|
||||||
} tVariant;
|
} tVariant;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "tskiplist.h"
|
#include "tskiplist.h"
|
||||||
#include "queryLog.h"
|
#include "queryLog.h"
|
||||||
|
#include "tsdbMain.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -521,38 +522,48 @@ static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
|
||||||
if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL ||
|
if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL ||
|
||||||
optr == TSDB_RELATION_EQUAL || optr == TSDB_RELATION_NOT_EQUAL) {
|
optr == TSDB_RELATION_EQUAL || optr == TSDB_RELATION_NOT_EQUAL) {
|
||||||
pCond->start = calloc(1, sizeof(tVariant));
|
pCond->start = calloc(1, sizeof(tVariant));
|
||||||
|
|
||||||
tVariantAssign(&pCond->start->v, &queryColInfo->q);
|
tVariantAssign(&pCond->start->v, &queryColInfo->q);
|
||||||
pCond->start->optr = queryColInfo->optr;
|
pCond->start->optr = queryColInfo->optr;
|
||||||
|
|
||||||
} else if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
} else if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
||||||
pCond->end = calloc(1, sizeof(tVariant));
|
pCond->end = calloc(1, sizeof(tVariant));
|
||||||
|
|
||||||
tVariantAssign(&pCond->end->v, &queryColInfo->q);
|
tVariantAssign(&pCond->end->v, &queryColInfo->q);
|
||||||
pCond->end->optr = queryColInfo->optr;
|
pCond->end->optr = queryColInfo->optr;
|
||||||
|
|
||||||
|
} else if (optr == TSDB_RELATION_IN) {
|
||||||
|
printf("relation is in\n");
|
||||||
|
|
||||||
|
} else if (optr == TSDB_RELATION_LIKE) {
|
||||||
|
printf("relation is like\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t type, SArray* result) {
|
static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* result) {
|
||||||
SSkipListIterator* iter = NULL;
|
SSkipListIterator* iter = NULL;
|
||||||
|
int32_t type = pQueryInfo->q.nType;
|
||||||
if (pCond->start != NULL) {
|
|
||||||
iter = tSkipListCreateIterFromVal(pSkipList, (char*) &pCond->start->v.i64Key, type, TSDB_ORDER_ASC);
|
SQueryCond cond = { 0 };
|
||||||
|
setQueryCond(pQueryInfo, &cond);
|
||||||
|
|
||||||
|
if (cond.start != NULL) {
|
||||||
|
iter = tSkipListCreateIterFromVal(pSkipList, (char*) &cond.start->v.i64Key, type, TSDB_ORDER_ASC);
|
||||||
} else {
|
} else {
|
||||||
iter = tSkipListCreateIterFromVal(pSkipList, (char*) &pCond->end->v.i64Key, type, TSDB_ORDER_DESC);
|
iter = tSkipListCreateIterFromVal(pSkipList, (char*) &cond.end->v.i64Key, type, TSDB_ORDER_DESC);
|
||||||
}
|
}
|
||||||
|
|
||||||
__compar_fn_t func = getComparFunc(pSkipList->keyInfo.type, type, 0);
|
__compar_fn_t func = getComparFunc(pSkipList->keyInfo.type, type, 0);
|
||||||
|
|
||||||
if (pCond->start != NULL) {
|
if (cond.start != NULL) {
|
||||||
int32_t optr = pCond->start->optr;
|
int32_t optr = cond.start->optr;
|
||||||
|
|
||||||
if (optr == TSDB_RELATION_EQUAL) {
|
if (optr == TSDB_RELATION_EQUAL) {
|
||||||
while(tSkipListIterNext(iter)) {
|
while(tSkipListIterNext(iter)) {
|
||||||
SSkipListNode* pNode = tSkipListIterGet(iter);
|
SSkipListNode* pNode = tSkipListIterGet(iter);
|
||||||
|
|
||||||
int32_t ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &pCond->start->v.i64Key);
|
int32_t ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &cond.start->v.i64Key);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
taosArrayPush(result, SL_GET_NODE_DATA(pNode));
|
taosArrayPush(result, SL_GET_NODE_DATA(pNode));
|
||||||
} else {
|
} else {
|
||||||
|
@ -567,7 +578,7 @@ static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t ty
|
||||||
SSkipListNode* pNode = tSkipListIterGet(iter);
|
SSkipListNode* pNode = tSkipListIterGet(iter);
|
||||||
|
|
||||||
if (comp) {
|
if (comp) {
|
||||||
ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &pCond->start->v.i64Key);
|
ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &cond.start->v.i64Key);
|
||||||
assert(ret >= 0);
|
assert(ret >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +595,7 @@ static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t ty
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int32_t optr = pCond->end->optr;
|
int32_t optr = cond.end->optr;
|
||||||
|
|
||||||
if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
||||||
bool comp = true;
|
bool comp = true;
|
||||||
|
@ -594,7 +605,7 @@ static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t ty
|
||||||
SSkipListNode* pNode = tSkipListIterGet(iter);
|
SSkipListNode* pNode = tSkipListIterGet(iter);
|
||||||
|
|
||||||
if (comp) {
|
if (comp) {
|
||||||
ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &pCond->end->v.i64Key);
|
ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &cond.end->v.i64Key);
|
||||||
assert(ret <= 0);
|
assert(ret <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,6 +631,8 @@ static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t ty
|
||||||
// DEFAULT_COMP(p1, p2);
|
// DEFAULT_COMP(p1, p2);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// develop_old mgmtSTableQuery for merge & intersect
|
||||||
|
|
||||||
int32_t merge(SArray *pLeft, SArray *pRight, SArray *pFinalRes) {
|
int32_t merge(SArray *pLeft, SArray *pRight, SArray *pFinalRes) {
|
||||||
// assert(pFinalRes->pRes == 0);
|
// assert(pFinalRes->pRes == 0);
|
||||||
//
|
//
|
||||||
|
@ -770,19 +783,55 @@ static void exprTreeTraverseImpl(tExprNode *pExpr, SArray *pResult, SBinaryFilte
|
||||||
taosArrayCopy(pResult, array);
|
taosArrayCopy(pResult, array);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tSQLBinaryTraverseOnSkipList(tExprNode *pExpr, SArray *pResult, SSkipList *pSkipList,
|
|
||||||
SBinaryFilterSupp *param) {
|
static void tSQLBinaryTraverseOnSkipList(
|
||||||
|
tExprNode *pExpr,
|
||||||
|
SArray *pResult,
|
||||||
|
SSkipList *pSkipList,
|
||||||
|
SBinaryFilterSupp *param
|
||||||
|
) {
|
||||||
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
|
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
|
||||||
|
|
||||||
while (tSkipListIterNext(iter)) {
|
while (tSkipListIterNext(iter)) {
|
||||||
SSkipListNode *pNode = tSkipListIterGet(iter);
|
SSkipListNode *pNode = tSkipListIterGet(iter);
|
||||||
|
|
||||||
if (filterItem(pExpr, pNode, param)) {
|
if (filterItem(pExpr, pNode, param)) {
|
||||||
taosArrayPush(pResult, SL_GET_NODE_DATA(pNode));
|
taosArrayPush(pResult, SL_GET_NODE_DATA(pNode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tSkipListDestroyIter(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void tQueryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArray* result) {
|
||||||
|
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
|
||||||
|
|
||||||
|
while (tSkipListIterNext(iter)) {
|
||||||
|
bool addToResult = false;
|
||||||
|
|
||||||
|
SSkipListNode *pNode = tSkipListIterGet(iter);
|
||||||
|
STable* table = *(STable**) SL_GET_NODE_DATA(pNode);
|
||||||
|
|
||||||
|
if (pQueryInfo->colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
|
if (pQueryInfo->optr == TSDB_RELATION_IN) {
|
||||||
|
addToResult = pQueryInfo->compare(table->name, pQueryInfo->q.arr);
|
||||||
|
} else if(pQueryInfo->optr == TSDB_RELATION_LIKE) {
|
||||||
|
addToResult = !pQueryInfo->compare(table->name, pQueryInfo->q.pz);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: other columns
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addToResult) {
|
||||||
|
taosArrayPush(result, (void*)&table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tSkipListDestroyIter(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// post-root order traverse syntax tree
|
// post-root order traverse syntax tree
|
||||||
void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param) {
|
void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param) {
|
||||||
if (pExpr == NULL) {
|
if (pExpr == NULL) {
|
||||||
|
@ -792,95 +841,99 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S
|
||||||
tExprNode *pLeft = pExpr->_node.pLeft;
|
tExprNode *pLeft = pExpr->_node.pLeft;
|
||||||
tExprNode *pRight = pExpr->_node.pRight;
|
tExprNode *pRight = pExpr->_node.pRight;
|
||||||
|
|
||||||
// recursive traverse left child branch
|
// column project
|
||||||
if (pLeft->nodeType == TSQL_NODE_EXPR || pRight->nodeType == TSQL_NODE_EXPR) {
|
if (pLeft->nodeType != TSQL_NODE_EXPR && pRight->nodeType != TSQL_NODE_EXPR) {
|
||||||
uint8_t weight = pLeft->_node.hasPK + pRight->_node.hasPK;
|
|
||||||
|
|
||||||
if (weight == 0 && taosArrayGetSize(result) > 0 && pSkipList == NULL) {
|
|
||||||
/**
|
|
||||||
* Perform the filter operation based on the initial filter result, which is obtained from filtering from index.
|
|
||||||
* Since no index presented, the filter operation is done by scan all elements in the result set.
|
|
||||||
*
|
|
||||||
* if the query is a high selectivity filter, only small portion of meters are retrieved.
|
|
||||||
*/
|
|
||||||
exprTreeTraverseImpl(pExpr, result, param);
|
|
||||||
} else if (weight == 0) {
|
|
||||||
/**
|
|
||||||
* apply the hierarchical expression to every node in skiplist for find the qualified nodes
|
|
||||||
*/
|
|
||||||
assert(taosArrayGetSize(result) == 0);
|
|
||||||
tSQLBinaryTraverseOnSkipList(pExpr, result, pSkipList, param);
|
|
||||||
} else if (weight == 2 || (weight == 1 && pExpr->_node.optr == TSDB_RELATION_OR)) {
|
|
||||||
SArray* rLeft = taosArrayInit(10, POINTER_BYTES);
|
|
||||||
SArray* rRight = taosArrayInit(10, POINTER_BYTES);
|
|
||||||
|
|
||||||
tExprTreeTraverse(pLeft, pSkipList, rLeft, param);
|
|
||||||
tExprTreeTraverse(pRight, pSkipList, rRight, param);
|
|
||||||
|
|
||||||
if (pExpr->_node.optr == TSDB_RELATION_AND) { // CROSS
|
|
||||||
intersect(rLeft, rRight, result);
|
|
||||||
} else if (pExpr->_node.optr == TSDB_RELATION_OR) { // or
|
|
||||||
merge(rLeft, rRight, result);
|
|
||||||
} else {
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
taosArrayDestroy(rLeft);
|
|
||||||
taosArrayDestroy(rRight);
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* (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);
|
|
||||||
}
|
|
||||||
} else { // column project
|
|
||||||
assert(pLeft->nodeType == TSQL_NODE_COL && pRight->nodeType == TSQL_NODE_VALUE);
|
assert(pLeft->nodeType == TSQL_NODE_COL && pRight->nodeType == TSQL_NODE_VALUE);
|
||||||
|
|
||||||
param->setupInfoFn(pExpr, param->pExtInfo);
|
param->setupInfoFn(pExpr, param->pExtInfo);
|
||||||
if (pSkipList == NULL) {
|
if (pSkipList == NULL) {
|
||||||
tSQLListTraverseOnResult(pExpr, param->fp, result);
|
tSQLListTraverseOnResult(pExpr, param->fp, result);
|
||||||
} else {
|
return;
|
||||||
tQueryInfo *pQueryInfo = pExpr->_node.info;
|
|
||||||
|
|
||||||
if (pQueryInfo->colIndex == 0 && pQueryInfo->optr != TSDB_RELATION_LIKE) {
|
|
||||||
SQueryCond cond = {0};
|
|
||||||
/*int32_t ret = */ setQueryCond(pQueryInfo, &cond);
|
|
||||||
tQueryOnSkipList(pSkipList, &cond, pQueryInfo->q.nType, result);
|
|
||||||
} else {
|
|
||||||
/* Brutal force scan the whole skip list to find the appropriate result,
|
|
||||||
* since the filter is not applied to indexed column.
|
|
||||||
*/
|
|
||||||
assert(0);
|
|
||||||
// result->num = tSkipListIterateList(pSkipList, (tSkipListNode ***)&result->pRes, fp, queryColInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tQueryInfo *pQueryInfo = pExpr->_node.info;
|
||||||
|
if (pQueryInfo->colIndex == 0 && pQueryInfo->optr != TSDB_RELATION_LIKE) {
|
||||||
|
tQueryIndexColumn(pSkipList, pQueryInfo, result);
|
||||||
|
} else {
|
||||||
|
tQueryIndexlessColumn(pSkipList, pQueryInfo, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// recursive traverse left child branch
|
||||||
|
uint8_t weight = pLeft->_node.hasPK + pRight->_node.hasPK;
|
||||||
|
|
||||||
|
if (weight == 0 ) {
|
||||||
|
if (taosArrayGetSize(result) > 0 && pSkipList == NULL) {
|
||||||
|
/**
|
||||||
|
* Perform the filter operation based on the initial filter result, which is obtained from filtering from index.
|
||||||
|
* Since no index presented, the filter operation is done by scan all elements in the result set.
|
||||||
|
*
|
||||||
|
* if the query is a high selectivity filter, only small portion of meters are retrieved.
|
||||||
|
*/
|
||||||
|
exprTreeTraverseImpl(pExpr, result, param);
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* apply the hierarchical expression to every node in skiplist for find the qualified nodes
|
||||||
|
*/
|
||||||
|
assert(taosArrayGetSize(result) == 0);
|
||||||
|
tSQLBinaryTraverseOnSkipList(pExpr, result, pSkipList, param);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight == 2 || (weight == 1 && pExpr->_node.optr == TSDB_RELATION_OR)) {
|
||||||
|
SArray* rLeft = taosArrayInit(10, POINTER_BYTES);
|
||||||
|
SArray* rRight = taosArrayInit(10, POINTER_BYTES);
|
||||||
|
|
||||||
|
tExprTreeTraverse(pLeft, pSkipList, rLeft, param);
|
||||||
|
tExprTreeTraverse(pRight, pSkipList, rRight, param);
|
||||||
|
|
||||||
|
if (pExpr->_node.optr == TSDB_RELATION_AND) { // CROSS
|
||||||
|
intersect(rLeft, rRight, result);
|
||||||
|
} else if (pExpr->_node.optr == TSDB_RELATION_OR) { // or
|
||||||
|
merge(rLeft, rRight, result);
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayDestroy(rLeft);
|
||||||
|
taosArrayDestroy(rRight);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tSQLBinaryExprCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
void tSQLBinaryExprCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
||||||
char *(*getSourceDataBlock)(void *, char *, int32_t)) {
|
char *(*getSourceDataBlock)(void *, char *, int32_t)) {
|
||||||
if (pExprs == NULL) {
|
if (pExprs == NULL) {
|
||||||
|
@ -1032,49 +1085,143 @@ SBuffer exprTreeToBinary(tExprNode* pExprTree) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exprTreeFromBinaryImpl(tExprNode** pExprTree, SBuffer* pBuf) {
|
static tExprNode* exprTreeFromBinaryImpl(SBuffer* pBuf) {
|
||||||
tExprNode* pExpr = calloc(1, sizeof(tExprNode));
|
tExprNode* pExpr = calloc(1, sizeof(tExprNode));
|
||||||
tbufReadToBuffer(pBuf, &pExpr->nodeType, sizeof(pExpr->nodeType));
|
pExpr->nodeType = tbufReadUint8(pBuf);
|
||||||
|
|
||||||
if (pExpr->nodeType == TSQL_NODE_VALUE) {
|
if (pExpr->nodeType == TSQL_NODE_VALUE) {
|
||||||
tVariant* pVal = calloc(1, sizeof(tVariant));
|
tVariant* pVal = calloc(1, sizeof(tVariant));
|
||||||
|
if (pVal == NULL) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
pExpr->pVal = pVal;
|
||||||
|
|
||||||
tbufReadToBuffer(pBuf, &pVal->nType, sizeof(pVal->nType));
|
pVal->nType = tbufReadUint32(pBuf);
|
||||||
if (pVal->nType == TSDB_DATA_TYPE_BINARY) {
|
if (pVal->nType == TSDB_DATA_TYPE_BINARY) {
|
||||||
tbufReadToBuffer(pBuf, &pVal->nLen, sizeof(pVal->nLen));
|
tbufReadToBuffer(pBuf, &pVal->nLen, sizeof(pVal->nLen));
|
||||||
pVal->pz = calloc(1, pVal->nLen + 1);
|
pVal->pz = calloc(1, pVal->nLen + 1);
|
||||||
tbufReadToBuffer(pBuf, pVal->pz, pVal->nLen);
|
tbufReadToBuffer(pBuf, pVal->pz, pVal->nLen);
|
||||||
} else {
|
} else {
|
||||||
tbufReadToBuffer(pBuf, &pVal->pz, sizeof(pVal->i64Key));
|
pVal->i64Key = tbufReadInt64(pBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
pExpr->pVal = pVal;
|
|
||||||
} else if (pExpr->nodeType == TSQL_NODE_COL) {
|
} else if (pExpr->nodeType == TSQL_NODE_COL) {
|
||||||
SSchema* pSchema = calloc(1, sizeof(SSchema));
|
SSchema* pSchema = calloc(1, sizeof(SSchema));
|
||||||
tbufReadToBuffer(pBuf, &pSchema->colId, sizeof(pSchema->colId));
|
if (pSchema == NULL) {
|
||||||
tbufReadToBuffer(pBuf, &pSchema->bytes, sizeof(pSchema->bytes));
|
// TODO:
|
||||||
tbufReadToBuffer(pBuf, &pSchema->type, sizeof(pSchema->type));
|
}
|
||||||
|
pExpr->pSchema = pSchema;
|
||||||
|
|
||||||
|
pSchema->colId = tbufReadInt16(pBuf);
|
||||||
|
pSchema->bytes = tbufReadInt16(pBuf);
|
||||||
|
pSchema->type = tbufReadUint8(pBuf);
|
||||||
tbufReadToString(pBuf, pSchema->name, TSDB_COL_NAME_LEN);
|
tbufReadToString(pBuf, pSchema->name, TSDB_COL_NAME_LEN);
|
||||||
|
|
||||||
pExpr->pSchema = pSchema;
|
|
||||||
} else if (pExpr->nodeType == TSQL_NODE_EXPR) {
|
} else if (pExpr->nodeType == TSQL_NODE_EXPR) {
|
||||||
tbufReadToBuffer(pBuf, &pExpr->_node.optr, sizeof(pExpr->_node.optr));
|
pExpr->_node.optr = tbufReadUint8(pBuf);
|
||||||
tbufReadToBuffer(pBuf, &pExpr->_node.hasPK, sizeof(pExpr->_node.hasPK));
|
pExpr->_node.hasPK = tbufReadUint8(pBuf);
|
||||||
|
pExpr->_node.pLeft = exprTreeFromBinaryImpl(pBuf);
|
||||||
exprTreeFromBinaryImpl(&pExpr->_node.pLeft, pBuf);
|
pExpr->_node.pRight = exprTreeFromBinaryImpl(pBuf);
|
||||||
exprTreeFromBinaryImpl(&pExpr->_node.pRight, pBuf);
|
|
||||||
|
|
||||||
assert(pExpr->_node.pLeft != NULL && pExpr->_node.pRight != NULL);
|
assert(pExpr->_node.pLeft != NULL && pExpr->_node.pRight != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
*pExprTree = pExpr;
|
return pExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t exprTreeFromBinary(const void* pBuf, size_t size, tExprNode** pExprNode) {
|
tExprNode* exprTreeFromBinary(const void* pBuf, size_t size) {
|
||||||
|
if (size == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
SBuffer rbuf = {0};
|
SBuffer rbuf = {0};
|
||||||
/*int32_t code =*/ tbufBeginRead(&rbuf, pBuf, size);
|
tbufBeginRead(&rbuf, pBuf, size);
|
||||||
exprTreeFromBinaryImpl(pExprNode, &rbuf);
|
return exprTreeFromBinaryImpl(&rbuf);
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
||||||
|
if (!tbnameCond) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tExprNode* expr = calloc(1, sizeof(tExprNode));
|
||||||
|
if (expr == NULL) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
expr->nodeType = TSQL_NODE_EXPR;
|
||||||
|
|
||||||
|
tExprNode* left = calloc(1, sizeof(tExprNode));
|
||||||
|
if (left == NULL) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
expr->_node.pLeft = left;
|
||||||
|
|
||||||
|
left->nodeType = TSQL_NODE_COL;
|
||||||
|
SSchema* pSchema = calloc(1, sizeof(SSchema));
|
||||||
|
if (pSchema == NULL) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
left->pSchema = pSchema;
|
||||||
|
|
||||||
|
pSchema->type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
pSchema->bytes = TSDB_TABLE_NAME_LEN;
|
||||||
|
strcpy(pSchema->name, TSQL_TBNAME_L);
|
||||||
|
pSchema->colId = -1;
|
||||||
|
|
||||||
|
tExprNode* right = calloc(1, sizeof(tExprNode));
|
||||||
|
if (right == NULL) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
expr->_node.pRight = right;
|
||||||
|
|
||||||
|
if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN) == 0) {
|
||||||
|
right->nodeType = TSQL_NODE_VALUE;
|
||||||
|
expr->_node.optr = TSDB_RELATION_LIKE;
|
||||||
|
tVariant* pVal = calloc(1, sizeof(tVariant));
|
||||||
|
if (pVal == NULL) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
right->pVal = pVal;
|
||||||
|
pVal->nType = TSDB_DATA_TYPE_BINARY;
|
||||||
|
size_t len = strlen(tbnameCond + QUERY_COND_REL_PREFIX_LIKE_LEN) + 1;
|
||||||
|
pVal->pz = malloc(len);
|
||||||
|
if (pVal->pz == NULL) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
memcpy(pVal->pz, tbnameCond + QUERY_COND_REL_PREFIX_LIKE_LEN, len);
|
||||||
|
pVal->nLen = (int32_t)len;
|
||||||
|
|
||||||
|
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN) == 0) {
|
||||||
|
right->nodeType = TSQL_NODE_VALUE;
|
||||||
|
expr->_node.optr = TSDB_RELATION_IN;
|
||||||
|
tVariant* pVal = calloc(1, sizeof(tVariant));
|
||||||
|
if (pVal == NULL) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
right->pVal = pVal;
|
||||||
|
pVal->nType = TSDB_DATA_TYPE_ARRAY;
|
||||||
|
pVal->arr = taosArrayInit(2, sizeof(char*));
|
||||||
|
|
||||||
|
const char* cond = tbnameCond + QUERY_COND_REL_PREFIX_IN_LEN;
|
||||||
|
for (const char *e = cond; *e != 0; e++) {
|
||||||
|
if (*e == TS_PATH_DELIMITER[0]) {
|
||||||
|
cond = e + 1;
|
||||||
|
} else if (*e == ',') {
|
||||||
|
size_t len = e - cond + 1;
|
||||||
|
char* p = malloc( len );
|
||||||
|
memcpy(p, cond, len);
|
||||||
|
p[len - 1] = 0;
|
||||||
|
cond += len;
|
||||||
|
taosArrayPush(pVal->arr, &p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*cond != 0) {
|
||||||
|
char* p = strdup( cond );
|
||||||
|
taosArrayPush(pVal->arr, &p);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArraySortString(pVal->arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return expr;
|
||||||
|
}
|
|
@ -990,9 +990,7 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UNUSED_FUNC char *getGroupbyColumnData(SQuery *pQuery, SData **data, int16_t *type, int16_t *bytes) {
|
static char *getGroupbyColumnData(SQuery *pQuery, int16_t *type, int16_t *bytes, SArray* pDataBlock) {
|
||||||
char *groupbyColumnData = NULL;
|
|
||||||
|
|
||||||
SSqlGroupbyExpr *pGroupbyExpr = pQuery->pGroupbyExpr;
|
SSqlGroupbyExpr *pGroupbyExpr = pQuery->pGroupbyExpr;
|
||||||
|
|
||||||
for (int32_t k = 0; k < pGroupbyExpr->numOfGroupCols; ++k) {
|
for (int32_t k = 0; k < pGroupbyExpr->numOfGroupCols; ++k) {
|
||||||
|
@ -1015,12 +1013,22 @@ static UNUSED_FUNC char *getGroupbyColumnData(SQuery *pQuery, SData **data, int1
|
||||||
|
|
||||||
*type = pQuery->colList[colIndex].type;
|
*type = pQuery->colList[colIndex].type;
|
||||||
*bytes = pQuery->colList[colIndex].bytes;
|
*bytes = pQuery->colList[colIndex].bytes;
|
||||||
|
/*
|
||||||
// groupbyColumnData = doGetDataBlocks(pQuery, data, pQuery->colList[colIndex].inf);
|
* the colIndex is acquired from the first meter of all qualified meters in this vnode during query prepare
|
||||||
break;
|
* stage, the remain meter may not have the required column in cache actually. So, the validation of required
|
||||||
|
* column in cache with the corresponding meter schema is reinforced.
|
||||||
|
*/
|
||||||
|
int32_t numOfCols = taosArrayGetSize(pDataBlock);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
SColumnInfoData *p = taosArrayGet(pDataBlock, i);
|
||||||
|
if (pColIndex->colId == p->info.colId) {
|
||||||
|
return p->pData;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return groupbyColumnData;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, int32_t offset) {
|
static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, int32_t offset) {
|
||||||
|
@ -1091,8 +1099,7 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
|
||||||
|
|
||||||
char *groupbyColumnData = NULL;
|
char *groupbyColumnData = NULL;
|
||||||
if (groupbyStateValue) {
|
if (groupbyStateValue) {
|
||||||
assert(0);
|
groupbyColumnData = getGroupbyColumnData(pQuery, &type, &bytes, pDataBlock);
|
||||||
// groupbyColumnData = getGroupbyColumnData(pQuery, data, &type, &bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t k = 0; k < pQuery->numOfOutput; ++k) {
|
for (int32_t k = 0; k < pQuery->numOfOutput; ++k) {
|
||||||
|
@ -5273,7 +5280,7 @@ static char *createTableIdList(SQueryTableMsg *pQueryMsg, char *pMsg, SArray **p
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList, SSqlFuncMsg ***pExpr,
|
static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList, SSqlFuncMsg ***pExpr,
|
||||||
char **tagCond, SColIndex **groupbyCols, SColumnInfo** tagCols) {
|
char **tagCond, char** tbnameCond, SColIndex **groupbyCols, SColumnInfo** tagCols) {
|
||||||
pQueryMsg->numOfTables = htonl(pQueryMsg->numOfTables);
|
pQueryMsg->numOfTables = htonl(pQueryMsg->numOfTables);
|
||||||
|
|
||||||
pQueryMsg->window.skey = htobe64(pQueryMsg->window.skey);
|
pQueryMsg->window.skey = htobe64(pQueryMsg->window.skey);
|
||||||
|
@ -5286,6 +5293,7 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
||||||
pQueryMsg->order = htons(pQueryMsg->order);
|
pQueryMsg->order = htons(pQueryMsg->order);
|
||||||
pQueryMsg->orderColId = htons(pQueryMsg->orderColId);
|
pQueryMsg->orderColId = htons(pQueryMsg->orderColId);
|
||||||
pQueryMsg->queryType = htons(pQueryMsg->queryType);
|
pQueryMsg->queryType = htons(pQueryMsg->queryType);
|
||||||
|
pQueryMsg->tagNameRelType = htons(pQueryMsg->tagNameRelType);
|
||||||
|
|
||||||
pQueryMsg->numOfCols = htons(pQueryMsg->numOfCols);
|
pQueryMsg->numOfCols = htons(pQueryMsg->numOfCols);
|
||||||
pQueryMsg->numOfOutput = htons(pQueryMsg->numOfOutput);
|
pQueryMsg->numOfOutput = htons(pQueryMsg->numOfOutput);
|
||||||
|
@ -5429,13 +5437,6 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
||||||
pMsg += sizeof(int64_t) * pQueryMsg->numOfOutput;
|
pMsg += sizeof(int64_t) * pQueryMsg->numOfOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the tag query condition expression string is located at the end of query msg
|
|
||||||
if (pQueryMsg->tagCondLen > 0) {
|
|
||||||
*tagCond = calloc(1, pQueryMsg->tagCondLen);
|
|
||||||
memcpy(*tagCond, pMsg, pQueryMsg->tagCondLen);
|
|
||||||
pMsg += pQueryMsg->tagCondLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pQueryMsg->numOfTags > 0) {
|
if (pQueryMsg->numOfTags > 0) {
|
||||||
(*tagCols) = calloc(1, sizeof(SColumnInfo) * pQueryMsg->numOfTags);
|
(*tagCols) = calloc(1, sizeof(SColumnInfo) * pQueryMsg->numOfTags);
|
||||||
for (int32_t i = 0; i < pQueryMsg->numOfTags; ++i) {
|
for (int32_t i = 0; i < pQueryMsg->numOfTags; ++i) {
|
||||||
|
@ -5447,9 +5448,24 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
||||||
pTagCol->numOfFilters = 0;
|
pTagCol->numOfFilters = 0;
|
||||||
|
|
||||||
(*tagCols)[i] = *pTagCol;
|
(*tagCols)[i] = *pTagCol;
|
||||||
|
pMsg += sizeof(SColumnInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the tag query condition expression string is located at the end of query msg
|
||||||
|
if (pQueryMsg->tagCondLen > 0) {
|
||||||
|
*tagCond = calloc(1, pQueryMsg->tagCondLen);
|
||||||
|
memcpy(*tagCond, pMsg, pQueryMsg->tagCondLen);
|
||||||
|
pMsg += pQueryMsg->tagCondLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*pMsg != 0) {
|
||||||
|
size_t len = strlen(pMsg) + 1;
|
||||||
|
*tbnameCond = malloc(len);
|
||||||
|
strcpy(*tbnameCond, pMsg);
|
||||||
|
pMsg += len;
|
||||||
|
}
|
||||||
|
|
||||||
qTrace("qmsg:%p query on %d table(s), qrange:%" PRId64 "-%" PRId64
|
qTrace("qmsg:%p query on %d table(s), qrange:%" PRId64 "-%" PRId64
|
||||||
", numOfGroupbyTagCols:%d, ts order:%d, "
|
", numOfGroupbyTagCols:%d, ts order:%d, "
|
||||||
"outputCols:%d, numOfCols:%d, interval:%d" PRId64 ", fillType:%d, comptsLen:%d, limit:%" PRId64
|
"outputCols:%d, numOfCols:%d, interval:%d" PRId64 ", fillType:%d, comptsLen:%d, limit:%" PRId64
|
||||||
|
@ -6047,13 +6063,13 @@ int32_t qCreateQueryInfo(void *tsdb, SQueryTableMsg *pQueryMsg, qinfo_t *pQInfo)
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
char * tagCond = NULL;
|
char * tagCond = NULL, *tbnameCond = NULL;
|
||||||
SArray * pTableIdList = NULL;
|
SArray * pTableIdList = NULL;
|
||||||
SSqlFuncMsg **pExprMsg = NULL;
|
SSqlFuncMsg **pExprMsg = NULL;
|
||||||
SColIndex * pGroupColIndex = NULL;
|
SColIndex * pGroupColIndex = NULL;
|
||||||
SColumnInfo* pTagColumnInfo = NULL;
|
SColumnInfo* pTagColumnInfo = NULL;
|
||||||
|
|
||||||
if ((code = convertQueryMsg(pQueryMsg, &pTableIdList, &pExprMsg, &tagCond, &pGroupColIndex, &pTagColumnInfo)) !=
|
if ((code = convertQueryMsg(pQueryMsg, &pTableIdList, &pExprMsg, &tagCond, &tbnameCond, &pGroupColIndex, &pTagColumnInfo)) !=
|
||||||
TSDB_CODE_SUCCESS) {
|
TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -6088,9 +6104,16 @@ int32_t qCreateQueryInfo(void *tsdb, SQueryTableMsg *pQueryMsg, qinfo_t *pQInfo)
|
||||||
|
|
||||||
STableId *id = taosArrayGet(pTableIdList, 0);
|
STableId *id = taosArrayGet(pTableIdList, 0);
|
||||||
id->uid = -1; // todo fix me
|
id->uid = -1; // todo fix me
|
||||||
|
|
||||||
/*int32_t ret =*/tsdbQueryByTagsCond(tsdb, id->uid, tagCond, pQueryMsg->tagCondLen, &groupInfo, pGroupColIndex,
|
// group by normal column, do not pass the group by condition to tsdb to group table into different group
|
||||||
pQueryMsg->numOfGroupCols);
|
int32_t numOfGroupByCols = pQueryMsg->numOfGroupCols;
|
||||||
|
if (pQueryMsg->numOfGroupCols == 1 && !TSDB_COL_IS_TAG(pGroupColIndex->flag)) {
|
||||||
|
numOfGroupByCols = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo handle the error
|
||||||
|
/*int32_t ret =*/tsdbQueryByTagsCond(tsdb, id->uid, tagCond, pQueryMsg->tagCondLen, pQueryMsg->tagNameRelType, tbnameCond, &groupInfo, pGroupColIndex,
|
||||||
|
numOfGroupByCols);
|
||||||
if (groupInfo.numOfTables == 0) { // no qualified tables no need to do query
|
if (groupInfo.numOfTables == 0) { // no qualified tables no need to do query
|
||||||
code = TSDB_CODE_SUCCESS;
|
code = TSDB_CODE_SUCCESS;
|
||||||
goto _query_over;
|
goto _query_over;
|
||||||
|
@ -6112,6 +6135,8 @@ int32_t qCreateQueryInfo(void *tsdb, SQueryTableMsg *pQueryMsg, qinfo_t *pQInfo)
|
||||||
code = initQInfo(pQueryMsg, tsdb, *pQInfo, isSTableQuery);
|
code = initQInfo(pQueryMsg, tsdb, *pQInfo, isSTableQuery);
|
||||||
|
|
||||||
_query_over:
|
_query_over:
|
||||||
|
tfree(tagCond);
|
||||||
|
tfree(tbnameCond);
|
||||||
taosArrayDestroy(pTableIdList);
|
taosArrayDestroy(pTableIdList);
|
||||||
|
|
||||||
// if failed to add ref for all meters in this query, abort current query
|
// if failed to add ref for all meters in this query, abort current query
|
||||||
|
|
|
@ -130,6 +130,17 @@ void tVariantDestroy(tVariant *pVar) {
|
||||||
tfree(pVar->pz);
|
tfree(pVar->pz);
|
||||||
pVar->nLen = 0;
|
pVar->nLen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: this is only for string array
|
||||||
|
if (pVar->nType == TSDB_DATA_TYPE_ARRAY) {
|
||||||
|
size_t num = taosArrayGetSize(pVar->arr);
|
||||||
|
for(size_t i = 0; i < num; i++) {
|
||||||
|
void* p = taosArrayGetP(pVar->arr, i);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
taosArrayDestroy(pVar->arr);
|
||||||
|
pVar->arr = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tVariantAssign(tVariant *pDst, const tVariant *pSrc) {
|
void tVariantAssign(tVariant *pDst, const tVariant *pSrc) {
|
||||||
|
@ -145,6 +156,18 @@ void tVariantAssign(tVariant *pDst, const tVariant *pSrc) {
|
||||||
|
|
||||||
pDst->pz = calloc(1, len);
|
pDst->pz = calloc(1, len);
|
||||||
memcpy(pDst->pz, pSrc->pz, len);
|
memcpy(pDst->pz, pSrc->pz, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is only for string array
|
||||||
|
if (pSrc->nType == TSDB_DATA_TYPE_ARRAY) {
|
||||||
|
size_t num = taosArrayGetSize(pSrc->arr);
|
||||||
|
pDst->arr = taosArrayInit(num, sizeof(char*));
|
||||||
|
for(size_t i = 0; i < num; i++) {
|
||||||
|
char* p = (char*)taosArrayGetP(pSrc->arr, i);
|
||||||
|
char* n = strdup(p);
|
||||||
|
taosArrayPush(pDst->arr, &n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ TEST(testCase, patternMatchTest) {
|
||||||
EXPECT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
|
EXPECT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
|
||||||
|
|
||||||
str = "abcdefgabcdeju";
|
str = "abcdefgabcdeju";
|
||||||
ret = patternMatch("abc%f_", str, 1, &info);
|
ret = patternMatch("abc%f_", str, 1, &info); // pattern string is longe than the size
|
||||||
EXPECT_EQ(ret, TSDB_PATTERN_NOMATCH);
|
EXPECT_EQ(ret, TSDB_PATTERN_NOMATCH);
|
||||||
|
|
||||||
str = "abcdefgabcdeju";
|
str = "abcdefgabcdeju";
|
||||||
|
@ -72,4 +72,8 @@ TEST(testCase, patternMatchTest) {
|
||||||
str = "abcdefgabcdeju";
|
str = "abcdefgabcdeju";
|
||||||
ret = patternMatch("a__", str, 2, &info);
|
ret = patternMatch("a__", str, 2, &info);
|
||||||
EXPECT_EQ(ret, TSDB_PATTERN_NOMATCH);
|
EXPECT_EQ(ret, TSDB_PATTERN_NOMATCH);
|
||||||
|
|
||||||
|
str = "carzero";
|
||||||
|
ret = patternMatch("%o", str, strlen(str), &info);
|
||||||
|
EXPECT_EQ(ret, TSDB_PATTERN_MATCH);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1213,7 +1213,9 @@ void filterPrepare(void* expr, void* param) {
|
||||||
pInfo->compare = getComparFunc(pSchema->type, pCond->nType, pInfo->optr);
|
pInfo->compare = getComparFunc(pSchema->type, pCond->nType, pInfo->optr);
|
||||||
|
|
||||||
tVariantAssign(&pInfo->q, pCond);
|
tVariantAssign(&pInfo->q, pCond);
|
||||||
tVariantTypeSetType(&pInfo->q, pInfo->sch.type);
|
if (pInfo->optr != TSDB_RELATION_IN) {
|
||||||
|
tVariantTypeSetType(&pInfo->q, pInfo->sch.type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t doCompare(const char* f1, const char* f2, int32_t type, size_t size) {
|
int32_t doCompare(const char* f1, const char* f2, int32_t type, size_t size) {
|
||||||
|
@ -1327,12 +1329,9 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numOfOrderCols == 0 || size == 1) { // no group by tags clause or only one table
|
if (numOfOrderCols == 0 || size == 1) { // no group by tags clause or only one table
|
||||||
size_t num = taosArrayGetSize(pTableList);
|
SArray* sa = taosArrayInit(size, sizeof(SPair));
|
||||||
|
for(int32_t i = 0; i < size; ++i) {
|
||||||
SArray* sa = taosArrayInit(num, sizeof(SPair));
|
|
||||||
for(int32_t i = 0; i < num; ++i) {
|
|
||||||
STable* pTable = taosArrayGetP(pTableList, i);
|
STable* pTable = taosArrayGetP(pTableList, i);
|
||||||
|
|
||||||
SPair p = {.first = pTable};
|
SPair p = {.first = pTable};
|
||||||
taosArrayPush(sa, &p);
|
taosArrayPush(sa, &p);
|
||||||
}
|
}
|
||||||
|
@ -1358,16 +1357,26 @@ bool tSkipListNodeFilterCallback(const void* pNode, void* param) {
|
||||||
|
|
||||||
STable* pTable = *(STable**)(SL_GET_NODE_DATA((SSkipListNode*)pNode));
|
STable* pTable = *(STable**)(SL_GET_NODE_DATA((SSkipListNode*)pNode));
|
||||||
|
|
||||||
char* val = dataRowTuple(pTable->tagVal); // todo not only the first column
|
char* val = NULL;
|
||||||
int8_t type = pInfo->sch.type;
|
int8_t type = pInfo->sch.type;
|
||||||
|
|
||||||
|
if (pInfo->colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
|
val = pTable->name;
|
||||||
|
type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
} else {
|
||||||
|
val = dataRowTuple(pTable->tagVal); // todo not only the first column
|
||||||
|
}
|
||||||
|
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
if (pInfo->q.nType == TSDB_DATA_TYPE_BINARY || pInfo->q.nType == TSDB_DATA_TYPE_NCHAR) {
|
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
ret = pInfo->compare(val, pInfo->q.pz);
|
if (pInfo->optr == TSDB_RELATION_IN) {
|
||||||
|
ret = pInfo->compare(val, pInfo->q.arr);
|
||||||
|
} else {
|
||||||
|
ret = pInfo->compare(val, pInfo->q.pz);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tVariant t = {0};
|
tVariant t = {0};
|
||||||
tVariantCreateFromBinary(&t, val, (uint32_t)pInfo->sch.bytes, type);
|
tVariantCreateFromBinary(&t, val, (uint32_t)pInfo->sch.bytes, type);
|
||||||
|
|
||||||
ret = pInfo->compare(&t.i64Key, &pInfo->q.i64Key);
|
ret = pInfo->compare(&t.i64Key, &pInfo->q.i64Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1393,6 +1402,9 @@ bool tSkipListNodeFilterCallback(const void* pNode, void* param) {
|
||||||
case TSDB_RELATION_LIKE: {
|
case TSDB_RELATION_LIKE: {
|
||||||
return ret == 0;
|
return ret == 0;
|
||||||
}
|
}
|
||||||
|
case TSDB_RELATION_IN: {
|
||||||
|
return ret == 1;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -1400,6 +1412,7 @@ bool tSkipListNodeFilterCallback(const void* pNode, void* param) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr) {
|
static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr) {
|
||||||
// query according to the binary expression
|
// query according to the binary expression
|
||||||
STSchema* pSchema = pSTable->tagSchema;
|
STSchema* pSchema = pSTable->tagSchema;
|
||||||
|
@ -1422,12 +1435,23 @@ static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr)
|
||||||
tExprTreeDestroy(&pExpr, destroyHelper);
|
tExprTreeDestroy(&pExpr, destroyHelper);
|
||||||
|
|
||||||
convertQueryResult(pRes, pTableList);
|
convertQueryResult(pRes, pTableList);
|
||||||
|
taosArrayDestroy(pTableList);
|
||||||
|
free(schema);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tsdbQueryByTagsCond(TsdbRepoT* tsdb, int64_t uid, const char* pTagCond, size_t len, STableGroupInfo* pGroupInfo,
|
|
||||||
SColIndex* pColIndex, int32_t numOfCols) {
|
int32_t tsdbQueryByTagsCond(
|
||||||
|
TsdbRepoT *tsdb,
|
||||||
|
int64_t uid,
|
||||||
|
const char *pTagCond,
|
||||||
|
size_t len,
|
||||||
|
int16_t tagNameRelType,
|
||||||
|
const char* tbnameCond,
|
||||||
|
STableGroupInfo *pGroupInfo,
|
||||||
|
SColIndex *pColIndex,
|
||||||
|
int32_t numOfCols
|
||||||
|
) {
|
||||||
STable* pSTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), uid);
|
STable* pSTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), uid);
|
||||||
if (pSTable == NULL) {
|
if (pSTable == NULL) {
|
||||||
uError("failed to get stable, uid:%" PRIu64, uid);
|
uError("failed to get stable, uid:%" PRIu64, uid);
|
||||||
|
@ -1437,31 +1461,35 @@ int32_t tsdbQueryByTagsCond(TsdbRepoT* tsdb, int64_t uid, const char* pTagCond,
|
||||||
SArray* res = taosArrayInit(8, POINTER_BYTES);
|
SArray* res = taosArrayInit(8, POINTER_BYTES);
|
||||||
STSchema* pTagSchema = tsdbGetTableTagSchema(tsdbGetMeta(tsdb), pSTable);
|
STSchema* pTagSchema = tsdbGetTableTagSchema(tsdbGetMeta(tsdb), pSTable);
|
||||||
|
|
||||||
if (pTagCond == NULL || len == 0) { // no tags condition, all tables created according to this stable are involved
|
// no tags and tbname condition, all child tables of this stable are involved
|
||||||
|
if (tbnameCond == NULL && (pTagCond == NULL || len == 0)) {
|
||||||
int32_t ret = getAllTableIdList(tsdb, uid, res);
|
int32_t ret = getAllTableIdList(tsdb, uid, res);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret == TSDB_CODE_SUCCESS) {
|
||||||
taosArrayDestroy(res);
|
pGroupInfo->numOfTables = taosArrayGetSize(res);
|
||||||
return ret;
|
pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols);
|
||||||
}
|
}
|
||||||
|
|
||||||
pGroupInfo->numOfTables = taosArrayGetSize(res);
|
|
||||||
pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols);
|
|
||||||
taosArrayDestroy(res);
|
taosArrayDestroy(res);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
tExprNode* pExprNode = NULL;
|
|
||||||
int32_t ret = TSDB_CODE_SUCCESS;
|
int32_t ret = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
// failed to build expression, no result, return immediately
|
tExprNode* expr = exprTreeFromTableName(tbnameCond);
|
||||||
if ((ret = exprTreeFromBinary(pTagCond, len, &pExprNode) != TSDB_CODE_SUCCESS) || (pExprNode == NULL)) {
|
tExprNode* tagExpr = exprTreeFromBinary(pTagCond, len);
|
||||||
uError("stable:%" PRIu64 ", failed to deserialize expression tree, error exists", uid);
|
if (tagExpr != NULL) {
|
||||||
taosArrayDestroy(res);
|
if (expr == NULL) {
|
||||||
return ret;
|
expr = tagExpr;
|
||||||
|
} else {
|
||||||
|
tExprNode* tbnameExpr = expr;
|
||||||
|
expr = calloc(1, sizeof(tExprNode));
|
||||||
|
expr->nodeType = TSQL_NODE_EXPR;
|
||||||
|
expr->_node.optr = tagNameRelType;
|
||||||
|
expr->_node.pLeft = tagExpr;
|
||||||
|
expr->_node.pRight = tbnameExpr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doQueryTableList(pSTable, res, pExprNode);
|
doQueryTableList(pSTable, res, expr);
|
||||||
|
|
||||||
pGroupInfo->numOfTables = taosArrayGetSize(res);
|
pGroupInfo->numOfTables = taosArrayGetSize(res);
|
||||||
pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols);
|
pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols);
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ void* taosArrayPush(SArray* pArray, void* pData);
|
||||||
*
|
*
|
||||||
* @param pArray
|
* @param pArray
|
||||||
*/
|
*/
|
||||||
void taosArrayPop(SArray* pArray);
|
void* taosArrayPop(SArray* pArray);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the data from array
|
* get the data from array
|
||||||
|
@ -112,6 +112,34 @@ SArray* taosArrayClone(SArray* pSrc);
|
||||||
*/
|
*/
|
||||||
void taosArrayDestroy(SArray* pArray);
|
void taosArrayDestroy(SArray* pArray);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sort the array
|
||||||
|
* @param pArray
|
||||||
|
* @param compar
|
||||||
|
*/
|
||||||
|
void taosArraySort(SArray* pArray, int (*compar)(const void*, const void*));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sort string array
|
||||||
|
* @param pArray
|
||||||
|
*/
|
||||||
|
void taosArraySortString(SArray* pArray);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search the array
|
||||||
|
* @param pArray
|
||||||
|
* @param compar
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
void* taosArraySearch(const SArray* pArray, int (*compar)(const void*, const void*), const void* key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search the array
|
||||||
|
* @param pArray
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
char* taosArraySearchString(const SArray* pArray, const char* key);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -120,7 +120,7 @@ void tbufWriteString(SBuffer* buf, const char* str);
|
||||||
TBUFFER_DEFINE_FUNCTION(bool, Bool)
|
TBUFFER_DEFINE_FUNCTION(bool, Bool)
|
||||||
TBUFFER_DEFINE_FUNCTION(char, Char)
|
TBUFFER_DEFINE_FUNCTION(char, Char)
|
||||||
TBUFFER_DEFINE_FUNCTION(int8_t, Int8)
|
TBUFFER_DEFINE_FUNCTION(int8_t, Int8)
|
||||||
TBUFFER_DEFINE_FUNCTION(uint8_t, Unt8)
|
TBUFFER_DEFINE_FUNCTION(uint8_t, Uint8)
|
||||||
TBUFFER_DEFINE_FUNCTION(int16_t, Int16)
|
TBUFFER_DEFINE_FUNCTION(int16_t, Int16)
|
||||||
TBUFFER_DEFINE_FUNCTION(uint16_t, Uint16)
|
TBUFFER_DEFINE_FUNCTION(uint16_t, Uint16)
|
||||||
TBUFFER_DEFINE_FUNCTION(int32_t, Int32)
|
TBUFFER_DEFINE_FUNCTION(int32_t, Int32)
|
||||||
|
|
|
@ -27,7 +27,7 @@ void* taosArrayInit(size_t size, size_t elemSize) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pArray->pData = calloc(size, elemSize * size);
|
pArray->pData = calloc(size, elemSize);
|
||||||
if (pArray->pData == NULL) {
|
if (pArray->pData == NULL) {
|
||||||
free(pArray);
|
free(pArray);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -76,12 +76,14 @@ void* taosArrayPush(SArray* pArray, void* pData) {
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosArrayPop(SArray* pArray) {
|
void* taosArrayPop(SArray* pArray) {
|
||||||
if (pArray == NULL || pArray->size == 0) {
|
assert( pArray != NULL );
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (pArray->size == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
pArray->size -= 1;
|
pArray->size -= 1;
|
||||||
|
return TARRAY_GET_ELEM(pArray, pArray->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* taosArrayGet(const SArray* pArray, size_t index) {
|
void* taosArrayGet(const SArray* pArray, size_t index) {
|
||||||
|
@ -183,3 +185,40 @@ void taosArrayDestroy(SArray* pArray) {
|
||||||
free(pArray->pData);
|
free(pArray->pData);
|
||||||
free(pArray);
|
free(pArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void taosArraySort(SArray* pArray, int (*compar)(const void*, const void*)) {
|
||||||
|
assert(pArray != NULL);
|
||||||
|
assert(compar != NULL);
|
||||||
|
|
||||||
|
qsort(pArray->pData, pArray->size, pArray->elemSize, compar);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* taosArraySearch(const SArray* pArray, int (*compar)(const void*, const void*), const void* key) {
|
||||||
|
assert(pArray != NULL);
|
||||||
|
assert(compar != NULL);
|
||||||
|
assert(key != NULL);
|
||||||
|
|
||||||
|
return bsearch(key, pArray->pData, pArray->size, pArray->elemSize, compar);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int taosArrayCompareString(const void* a, const void* b) {
|
||||||
|
const char* x = *(const char**)a;
|
||||||
|
const char* y = *(const char**)b;
|
||||||
|
return strcmp(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void taosArraySortString(SArray* pArray) {
|
||||||
|
assert(pArray != NULL);
|
||||||
|
qsort(pArray->pData, pArray->size, pArray->elemSize, taosArrayCompareString);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* taosArraySearchString(const SArray* pArray, const char* key) {
|
||||||
|
assert(pArray != NULL);
|
||||||
|
assert(key != NULL);
|
||||||
|
|
||||||
|
void* p = bsearch(&key, pArray->pData, pArray->size, pArray->elemSize, taosArrayCompareString);
|
||||||
|
if (p == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return *(char**)p;
|
||||||
|
}
|
|
@ -1,42 +1,34 @@
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
|
#include <tarray.h>
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
int32_t compareInt32Val(const void *pLeft, const void *pRight) {
|
int32_t compareInt32Val(const void *pLeft, const void *pRight) {
|
||||||
int32_t ret = GET_INT32_VAL(pLeft) - GET_INT32_VAL(pRight);
|
int32_t left = GET_INT32_VAL(pLeft), right = GET_INT32_VAL(pRight);
|
||||||
if (ret == 0) {
|
if (left > right) return 1;
|
||||||
return 0;
|
if (left < right) return -1;
|
||||||
} else {
|
return 0;
|
||||||
return ret > 0 ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareInt64Val(const void *pLeft, const void *pRight) {
|
int32_t compareInt64Val(const void *pLeft, const void *pRight) {
|
||||||
int64_t ret = GET_INT64_VAL(pLeft) - GET_INT64_VAL(pRight);
|
int64_t left = GET_INT64_VAL(pLeft), right = GET_INT64_VAL(pRight);
|
||||||
if (ret == 0) {
|
if (left > right) return 1;
|
||||||
return 0;
|
if (left < right) return -1;
|
||||||
} else {
|
return 0;
|
||||||
return ret > 0 ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareInt16Val(const void *pLeft, const void *pRight) {
|
int32_t compareInt16Val(const void *pLeft, const void *pRight) {
|
||||||
int32_t ret = GET_INT16_VAL(pLeft) - GET_INT16_VAL(pRight);
|
int16_t left = GET_INT16_VAL(pLeft), right = GET_INT16_VAL(pRight);
|
||||||
if (ret == 0) {
|
if (left > right) return 1;
|
||||||
return 0;
|
if (left < right) return -1;
|
||||||
} else {
|
return 0;
|
||||||
return ret > 0 ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareInt8Val(const void *pLeft, const void *pRight) {
|
int32_t compareInt8Val(const void *pLeft, const void *pRight) {
|
||||||
int32_t ret = GET_INT8_VAL(pLeft) - GET_INT8_VAL(pRight);
|
int8_t left = GET_INT8_VAL(pLeft), right = GET_INT8_VAL(pRight);
|
||||||
if (ret == 0) {
|
if (left > right) return 1;
|
||||||
return 0;
|
if (left < right) return -1;
|
||||||
} else {
|
return 0;
|
||||||
return ret > 0 ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareIntDoubleVal(const void *pLeft, const void *pRight) {
|
int32_t compareIntDoubleVal(const void *pLeft, const void *pRight) {
|
||||||
|
@ -69,12 +61,7 @@ int32_t compareDoubleVal(const void *pLeft, const void *pRight) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareStrVal(const void *pLeft, const void *pRight) {
|
int32_t compareStrVal(const void *pLeft, const void *pRight) {
|
||||||
int32_t ret = strcmp(pLeft, pRight);
|
return (int32_t)strcmp(pLeft, pRight);
|
||||||
if (ret == 0) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return ret > 0 ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareWStrVal(const void *pLeft, const void *pRight) {
|
int32_t compareWStrVal(const void *pLeft, const void *pRight) {
|
||||||
|
@ -228,6 +215,11 @@ static UNUSED_FUNC int32_t compareStrPatternComp(const void* pLeft, const void*
|
||||||
return (ret == TSDB_PATTERN_MATCH) ? 0 : 1;
|
return (ret == TSDB_PATTERN_MATCH) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t compareFindStrInArray(const void* pLeft, const void* pRight) {
|
||||||
|
const SArray* arr = (const SArray*)pRight;
|
||||||
|
return taosArraySearchString(arr, pLeft) == NULL ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
static UNUSED_FUNC int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) {
|
static UNUSED_FUNC int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) {
|
||||||
SPatternCompareInfo pInfo = {'%', '_'};
|
SPatternCompareInfo pInfo = {'%', '_'};
|
||||||
|
|
||||||
|
@ -250,7 +242,6 @@ __compar_fn_t getComparFunc(int32_t type, int32_t filterDataType, int32_t optr)
|
||||||
case TSDB_DATA_TYPE_BIGINT:
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||||
// assert(type == filterDataType);
|
// assert(type == filterDataType);
|
||||||
|
|
||||||
if (filterDataType == TSDB_DATA_TYPE_BIGINT || filterDataType == TSDB_DATA_TYPE_TIMESTAMP) {
|
if (filterDataType == TSDB_DATA_TYPE_BIGINT || filterDataType == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||||
comparFn = compareInt64Val;
|
comparFn = compareInt64Val;
|
||||||
} else if (filterDataType >= TSDB_DATA_TYPE_FLOAT && filterDataType <= TSDB_DATA_TYPE_DOUBLE) {
|
} else if (filterDataType >= TSDB_DATA_TYPE_FLOAT && filterDataType <= TSDB_DATA_TYPE_DOUBLE) {
|
||||||
|
@ -259,6 +250,7 @@ __compar_fn_t getComparFunc(int32_t type, int32_t filterDataType, int32_t optr)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_BOOL: {
|
case TSDB_DATA_TYPE_BOOL: {
|
||||||
if (filterDataType >= TSDB_DATA_TYPE_BOOL && filterDataType <= TSDB_DATA_TYPE_BIGINT) {
|
if (filterDataType >= TSDB_DATA_TYPE_BOOL && filterDataType <= TSDB_DATA_TYPE_BIGINT) {
|
||||||
comparFn = compareInt32Val;
|
comparFn = compareInt32Val;
|
||||||
|
@ -267,6 +259,7 @@ __compar_fn_t getComparFunc(int32_t type, int32_t filterDataType, int32_t optr)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_FLOAT:
|
case TSDB_DATA_TYPE_FLOAT:
|
||||||
case TSDB_DATA_TYPE_DOUBLE: {
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
if (filterDataType >= TSDB_DATA_TYPE_BOOL && filterDataType <= TSDB_DATA_TYPE_BIGINT) {
|
if (filterDataType >= TSDB_DATA_TYPE_BOOL && filterDataType <= TSDB_DATA_TYPE_BIGINT) {
|
||||||
|
@ -276,12 +269,18 @@ __compar_fn_t getComparFunc(int32_t type, int32_t filterDataType, int32_t optr)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_BINARY: {
|
case TSDB_DATA_TYPE_BINARY: {
|
||||||
assert(filterDataType == TSDB_DATA_TYPE_BINARY);
|
|
||||||
|
|
||||||
if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */
|
if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */
|
||||||
|
assert(filterDataType == TSDB_DATA_TYPE_BINARY);
|
||||||
comparFn = compareStrPatternComp;
|
comparFn = compareStrPatternComp;
|
||||||
|
|
||||||
|
} else if (optr == TSDB_RELATION_IN) {
|
||||||
|
assert(filterDataType == TSDB_DATA_TYPE_ARRAY);
|
||||||
|
comparFn = compareFindStrInArray;
|
||||||
|
|
||||||
} else { /* normal relational comparFn */
|
} else { /* normal relational comparFn */
|
||||||
|
assert(filterDataType == TSDB_DATA_TYPE_BINARY);
|
||||||
comparFn = compareStrVal;
|
comparFn = compareStrVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
doQuery(taos, "create database if not exists test");
|
doQuery(taos, "create database if not exists test");
|
||||||
doQuery(taos, "use test");
|
doQuery(taos, "use test");
|
||||||
doQuery(taos, "insert into tm99 values('2020-01-01 1:1:1', 99);");
|
doQuery(taos, "select count(*),k,sum(k) from m1 group by k");
|
||||||
// doQuery(taos, "create table if not exists tm0 (ts timestamp, k int);");
|
// doQuery(taos, "create table if not exists tm0 (ts timestamp, k int);");
|
||||||
// doQuery(taos, "insert into tm0 values('2020-1-1 1:1:1', 1);");
|
// doQuery(taos, "insert into tm0 values('2020-1-1 1:1:1', 1);");
|
||||||
// doQuery(taos, "insert into tm0 values('2020-1-1 1:1:2', 2);");
|
// doQuery(taos, "insert into tm0 values('2020-1-1 1:1:2', 2);");
|
||||||
|
@ -86,7 +86,7 @@ int main(int argc, char *argv[]) {
|
||||||
// doQuery(taos, "insert into tm0 values('2020-1-1 1:1:7', 7);");
|
// doQuery(taos, "insert into tm0 values('2020-1-1 1:1:7', 7);");
|
||||||
// doQuery(taos, "insert into tm0 values('2020-1-1 1:1:8', 8);");
|
// doQuery(taos, "insert into tm0 values('2020-1-1 1:1:8', 8);");
|
||||||
// doQuery(taos, "insert into tm0 values('2020-1-1 1:1:9', 9);");
|
// doQuery(taos, "insert into tm0 values('2020-1-1 1:1:9', 9);");
|
||||||
doQuery(taos, "select sum(k),count(*) from m1 group by a");
|
// doQuery(taos, "select sum(k),count(*) from m1 group by a");
|
||||||
|
|
||||||
taos_close(taos);
|
taos_close(taos);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
import taos
|
||||||
|
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.prepare()
|
||||||
|
|
||||||
|
tdLog.info("=============== step1")
|
||||||
|
cmd = 'create table tb (ts timestamp, speed float)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
cmd = 'insert into tb values (now, -3.40E+38)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
|
||||||
|
tdLog.info("=============== step2")
|
||||||
|
cmd = 'insert into tb values (now+1a, 3.40E+308)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
try:
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdLog.exit(
|
||||||
|
"This test failed: insert wrong data error _not_ catched")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info(repr(e))
|
||||||
|
tdLog.notice("insert wrong data error catched")
|
||||||
|
|
||||||
|
cmd = 'select * from tb order by ts desc'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.query(cmd)
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
|
tdLog.info("=============== step3")
|
||||||
|
cmd = "insert into tb values (now+2a, 2.85)"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
cmd = "select * from tb order by ts desc"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
ret = tdSql.query(cmd)
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
|
||||||
|
if ((abs(tdSql.getData(0, 1) - 2.850000)) > 1.0e-7):
|
||||||
|
tdLog.exit("data is not 2.850000")
|
||||||
|
|
||||||
|
tdLog.info("=============== step4")
|
||||||
|
cmd = "insert into tb values (now+3a, 3.4)"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
cmd = "select * from tb order by ts desc"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.query(cmd)
|
||||||
|
tdSql.checkRows(3)
|
||||||
|
if (abs(tdSql.getData(0, 1) - 3.400000) > 1.0e-7):
|
||||||
|
tdLog.exit("data is not 3.400000")
|
||||||
|
|
||||||
|
tdLog.info("=============== step5")
|
||||||
|
cmd = "insert into tb values (now+4a, a2)"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
try:
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdLog.exit("This test failed: \
|
||||||
|
insert wrong data error _not_ catched")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info(repr(e))
|
||||||
|
tdLog.notice("insert wrong data error catched")
|
||||||
|
|
||||||
|
cmd = "insert into tb values (now+4a, 0)"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
cmd = "select * from tb order by ts desc"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.query(cmd)
|
||||||
|
tdSql.checkRows(4)
|
||||||
|
if (abs(tdSql.getData(0, 1) - 0.000000) != 0):
|
||||||
|
tdLog.exit("data is not 0.000000")
|
||||||
|
|
||||||
|
tdLog.info("=============== step6")
|
||||||
|
cmd = "insert into tb values (now+5a, 2a)"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
try:
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdLog.exit(
|
||||||
|
"This test failed: insert wrong data error _not_ catched")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info(repr(e))
|
||||||
|
tdLog.notice("insert wrong data error catched")
|
||||||
|
|
||||||
|
cmd = "insert into tb values (now+5a, 2)"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
cmd = "select * from tb order by ts desc"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
ret = tdSql.query(cmd)
|
||||||
|
tdSql.checkRows(5)
|
||||||
|
if (abs(tdSql.getData(0, 1) - 2.000000) > 1.0e-7):
|
||||||
|
tdLog.info("data is not 2.000000")
|
||||||
|
|
||||||
|
tdLog.info("=============== step7")
|
||||||
|
cmd = "insert into tb values (now+6a, 2a'1)"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
try:
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdLog.exit(
|
||||||
|
"This test failed: insert wrong data error _not_ catched")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info(repr(e))
|
||||||
|
tdLog.notice("insert wrong data error catched")
|
||||||
|
|
||||||
|
cmd = "insert into tb values (now+6a, 2)"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
cmd = "select * from tb order by ts desc"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.query(cmd)
|
||||||
|
if (abs(tdSql.getData(0, 1) - 2.000000) > 1.0e-7):
|
||||||
|
tdLog.exit("data is not 2.000000")
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -0,0 +1,184 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import taos
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.prepare()
|
||||||
|
|
||||||
|
tdLog.info("=============== step1")
|
||||||
|
tdSql.execute('create table tb (ts timestamp, speed int)')
|
||||||
|
|
||||||
|
cmd = 'insert into tb values (now, NULL)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdSql.query('select * from tb order by ts desc')
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
if(tdSql.getData(0, 1) is not None):
|
||||||
|
tdLog.exit("data is not NULL")
|
||||||
|
|
||||||
|
tdLog.info("=============== step2")
|
||||||
|
cmd = 'insert into tb values (now+1m, -2147483648)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
try:
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdLog.exit(
|
||||||
|
"This test failed: INT data overflow error _not_ catched")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info(repr(e))
|
||||||
|
tdLog.notice("INT data overflow error catched")
|
||||||
|
|
||||||
|
cmd = 'insert into tb values (now+1m, NULL)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdSql.query('select * from tb order by ts desc')
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
|
||||||
|
if(tdSql.getData(0, 1) is not None):
|
||||||
|
tdLog.exit("data is not NULL")
|
||||||
|
|
||||||
|
tdLog.info("=============== step3")
|
||||||
|
cmd = 'insert into tb values (now+2m, 2147483647)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdSql.query('select * from tb order by ts desc')
|
||||||
|
tdSql.checkRows(3)
|
||||||
|
if(tdSql.getData(0, 1) != 2147483647):
|
||||||
|
tdLog.exit("data is not 2147483647")
|
||||||
|
|
||||||
|
tdLog.info("=============== step4")
|
||||||
|
cmd = 'insert into tb values (now+3m, 2147483648)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
try:
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdLog.exit(
|
||||||
|
"This test failed: INT data overflow error _not_ catched")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info(repr(e))
|
||||||
|
tdLog.notice("INT data overflow error catched")
|
||||||
|
|
||||||
|
cmd = 'insert into tb values (now+3m, NULL)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdSql.query('select * from tb order by ts desc')
|
||||||
|
tdSql.checkRows(4)
|
||||||
|
|
||||||
|
if(tdSql.getData(0, 1) is not None):
|
||||||
|
tdLog.exit("data is not NULL")
|
||||||
|
|
||||||
|
tdLog.info("=============== step5")
|
||||||
|
cmd = 'insert into tb values (now+4m, a2)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
try:
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdLog.exit(
|
||||||
|
"This test failed: insert wrong data error _not_ catched")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info(repr(e))
|
||||||
|
tdLog.notice("insert wrong data error catched")
|
||||||
|
|
||||||
|
cmd = 'insert into tb values (now+4m, 0)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdSql.query('select * from tb order by ts desc')
|
||||||
|
tdSql.checkRows(5)
|
||||||
|
|
||||||
|
if(tdSql.getData(0, 1) != 0):
|
||||||
|
tdLog.exit("data is not 0")
|
||||||
|
|
||||||
|
tdLog.info("=============== step6")
|
||||||
|
cmd = 'insert into tb values (now+5m, 2a)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
try:
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdLog.exit(
|
||||||
|
"This test failed: insert wrong data error _not_ catched")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info(repr(e))
|
||||||
|
tdLog.notice("insert wrong data error catched")
|
||||||
|
|
||||||
|
cmd = 'insert into tb values (now+5m, 2)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdSql.query('select * from tb order by ts desc')
|
||||||
|
tdSql.checkRows(6)
|
||||||
|
if (tdSql.getData(0, 1) != 2):
|
||||||
|
tdLog.exit("data is not 2")
|
||||||
|
|
||||||
|
tdLog.info("=============== step7")
|
||||||
|
cmd = "insert into tb values (now+6m, 2a'1)"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
try:
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdLog.exit(
|
||||||
|
"This test failed: insert wrong data error _not_ catched")
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.info(repr(e))
|
||||||
|
tdLog.notice("insert wrong data error catched")
|
||||||
|
|
||||||
|
cmd = 'insert into tb values (now+6m, 2)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdSql.query('select * from tb order by ts desc')
|
||||||
|
tdSql.checkRows(7)
|
||||||
|
if (tdSql.getData(0, 1) != 2):
|
||||||
|
tdLog.exit("data is not 2")
|
||||||
|
|
||||||
|
tdLog.info("=============== step8")
|
||||||
|
cmd = 'insert into tb values (now+8m, "null")'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdSql.query('select * from tb order by ts desc')
|
||||||
|
tdSql.checkRows(8)
|
||||||
|
|
||||||
|
if (tdSql.getData(0, 1) is not None):
|
||||||
|
tdLog.exit("data is not null")
|
||||||
|
|
||||||
|
tdLog.info("=============== step9")
|
||||||
|
cmd = "insert into tb values (now+9m, 'null')"
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdSql.query('select * from tb order by ts desc')
|
||||||
|
tdSql.checkRows(9)
|
||||||
|
if (tdSql.getData(0, 1) is not None):
|
||||||
|
tdLog.exit("data is not null")
|
||||||
|
|
||||||
|
tdLog.info("=============== step10")
|
||||||
|
cmd = 'insert into tb values (now+10m, -123)'
|
||||||
|
tdLog.info(cmd)
|
||||||
|
tdSql.execute(cmd)
|
||||||
|
tdSql.query('select * from tb order by ts desc')
|
||||||
|
tdSql.checkRows(10)
|
||||||
|
|
||||||
|
if (tdSql.getData(0, 1) != -123):
|
||||||
|
tdLog.exit("data is not -123")
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -0,0 +1,75 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import taos
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.prepare()
|
||||||
|
|
||||||
|
tdSql.execute('create table cars (ts timestamp, speed int) tags(id int)')
|
||||||
|
tdSql.execute("create table carzero using cars tags(0)")
|
||||||
|
tdSql.execute("create table carone using cars tags(1)")
|
||||||
|
tdSql.execute("create table cartwo using cars tags(2)")
|
||||||
|
|
||||||
|
tdSql.execute("insert into carzero values(now, 100) carone values(now, 110)")
|
||||||
|
|
||||||
|
tdSql.query("select * from cars where tbname in ('carzero', 'carone')")
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
|
||||||
|
tdSql.query("select * from cars where tbname in ('carzero', 'cartwo')")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
|
tdSql.query("select * from cars where id=1 or tbname in ('carzero', 'cartwo')")
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
|
||||||
|
tdSql.query("select * from cars where id=1 and tbname in ('carzero', 'cartwo')")
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
|
||||||
|
tdSql.query("select * from cars where id=0 and tbname in ('carzero', 'cartwo')")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
|
"""
|
||||||
|
tdSql.query("select * from cars where tbname like 'car%'")
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
|
||||||
|
tdSql.cursor.execute("use db")
|
||||||
|
tdSql.query("select * from cars where tbname like '%o'")
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
|
tdSql.query("select * from cars where id=1 and tbname like 'car%')
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
|
tdSql.query("select * from cars where id = 1 and tbname like '%o')
|
||||||
|
tdSql.checkRows(0)
|
||||||
|
|
||||||
|
tdSql.query("select * from cars where id = 1 or tbname like '%o')
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -1,3 +1,9 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
python3 ./test.py -f insert/basic.py $1
|
python3 ./test.py -f insert/basic.py $1
|
||||||
python3 ./test.py -s $1
|
python3 ./test.py -s $1
|
||||||
|
sleep 1
|
||||||
|
python3 ./test.py -f insert/int.py $1
|
||||||
|
python3 ./test.py -s $1
|
||||||
|
sleep 1
|
||||||
|
python3 ./test.py -f insert/float.py $1
|
||||||
|
python3 ./test.py -s $1
|
||||||
|
|
|
@ -100,7 +100,7 @@ if __name__ == "__main__":
|
||||||
tdDnodes.deploy(1)
|
tdDnodes.deploy(1)
|
||||||
tdDnodes.start(1)
|
tdDnodes.start(1)
|
||||||
conn = taos.connect(
|
conn = taos.connect(
|
||||||
host='192.168.0.1',
|
host='127.0.0.1',
|
||||||
config=tdDnodes.getSimCfgPath())
|
config=tdDnodes.getSimCfgPath())
|
||||||
if fileName == "all":
|
if fileName == "all":
|
||||||
tdCases.runAllLinux(conn)
|
tdCases.runAllLinux(conn)
|
||||||
|
|
|
@ -67,12 +67,16 @@ class TDCases:
|
||||||
if tmp.name.find(fileName) != -1:
|
if tmp.name.find(fileName) != -1:
|
||||||
case = testModule.TDTestCase()
|
case = testModule.TDTestCase()
|
||||||
case.init(conn)
|
case.init(conn)
|
||||||
case.run()
|
try:
|
||||||
|
case.run()
|
||||||
|
except Exception as e:
|
||||||
|
tdLog.notice(repr(e))
|
||||||
|
tdLog.notice("%s failed: %s" % (__file__, fileName))
|
||||||
case.stop()
|
case.stop()
|
||||||
runNum += 1
|
runNum += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
tdLog.notice("total %d Linux test case(s) executed" % (runNum))
|
tdLog.success("total %d Linux test case(s) executed" % (runNum))
|
||||||
|
|
||||||
def runAllWindows(self, conn):
|
def runAllWindows(self, conn):
|
||||||
# TODO: load all Windows cases here
|
# TODO: load all Windows cases here
|
||||||
|
|
|
@ -19,12 +19,19 @@ from util.log import *
|
||||||
|
|
||||||
|
|
||||||
class TDSimClient:
|
class TDSimClient:
|
||||||
|
def __init__(self):
|
||||||
|
self.testCluster = False
|
||||||
|
|
||||||
def init(self, path):
|
def init(self, path):
|
||||||
|
self.__init__()
|
||||||
self.path = path
|
self.path = path
|
||||||
|
|
||||||
def getCfgDir(self):
|
def getCfgDir(self):
|
||||||
return self.cfgDir
|
return self.cfgDir
|
||||||
|
|
||||||
|
def setTestCluster(self, value):
|
||||||
|
self.testCluster = value
|
||||||
|
|
||||||
def cfg(self, option, value):
|
def cfg(self, option, value):
|
||||||
cmd = "echo '%s %s' >> %s" % (option, value, self.cfgPath)
|
cmd = "echo '%s %s' >> %s" % (option, value, self.cfgPath)
|
||||||
if os.system(cmd) != 0:
|
if os.system(cmd) != 0:
|
||||||
|
@ -55,8 +62,9 @@ class TDSimClient:
|
||||||
if os.system(cmd) != 0:
|
if os.system(cmd) != 0:
|
||||||
tdLog.exit(cmd)
|
tdLog.exit(cmd)
|
||||||
|
|
||||||
self.cfg("masterIp", "192.168.0.1")
|
if self.testCluster:
|
||||||
self.cfg("secondIp", "192.168.0.2")
|
self.cfg("masterIp", "192.168.0.1")
|
||||||
|
self.cfg("secondIp", "192.168.0.2")
|
||||||
self.cfg("logDir", self.logDir)
|
self.cfg("logDir", self.logDir)
|
||||||
self.cfg("numOfLogLines", "100000000")
|
self.cfg("numOfLogLines", "100000000")
|
||||||
self.cfg("numOfThreadsPerCore", "2.0")
|
self.cfg("numOfThreadsPerCore", "2.0")
|
||||||
|
@ -128,11 +136,12 @@ class TDDnode:
|
||||||
if self.testCluster:
|
if self.testCluster:
|
||||||
self.startIP()
|
self.startIP()
|
||||||
|
|
||||||
self.cfg("masterIp", "192.168.0.1")
|
if self.testCluster:
|
||||||
self.cfg("secondIp", "192.168.0.2")
|
self.cfg("masterIp", "192.168.0.1")
|
||||||
self.cfg("publicIp", "192.168.0.%d" % (self.index))
|
self.cfg("secondIp", "192.168.0.2")
|
||||||
self.cfg("internalIp", "192.168.0.%d" % (self.index))
|
self.cfg("publicIp", "192.168.0.%d" % (self.index))
|
||||||
self.cfg("privateIp", "192.168.0.%d" % (self.index))
|
self.cfg("internalIp", "192.168.0.%d" % (self.index))
|
||||||
|
self.cfg("privateIp", "192.168.0.%d" % (self.index))
|
||||||
self.cfg("dataDir", self.dataDir)
|
self.cfg("dataDir", self.dataDir)
|
||||||
self.cfg("logDir", self.logDir)
|
self.cfg("logDir", self.logDir)
|
||||||
self.cfg("numOfLogLines", "100000000")
|
self.cfg("numOfLogLines", "100000000")
|
||||||
|
@ -291,10 +300,6 @@ class TDDnodes:
|
||||||
for i in range(len(self.dnodes)):
|
for i in range(len(self.dnodes)):
|
||||||
self.dnodes[i].init(self.path)
|
self.dnodes[i].init(self.path)
|
||||||
|
|
||||||
self.sim = TDSimClient()
|
|
||||||
self.sim.init(self.path)
|
|
||||||
self.sim.deploy()
|
|
||||||
|
|
||||||
def setTestCluster(self, value):
|
def setTestCluster(self, value):
|
||||||
self.testCluster = value
|
self.testCluster = value
|
||||||
|
|
||||||
|
@ -302,6 +307,11 @@ class TDDnodes:
|
||||||
self.valgrind = value
|
self.valgrind = value
|
||||||
|
|
||||||
def deploy(self, index):
|
def deploy(self, index):
|
||||||
|
self.sim = TDSimClient()
|
||||||
|
self.sim.init(self.path)
|
||||||
|
self.sim.setTestCluster(self.testCluster)
|
||||||
|
self.sim.deploy()
|
||||||
|
|
||||||
self.check(index)
|
self.check(index)
|
||||||
self.dnodes[index - 1].setTestCluster(self.testCluster)
|
self.dnodes[index - 1].setTestCluster(self.testCluster)
|
||||||
self.dnodes[index - 1].setValgrind(self.valgrind)
|
self.dnodes[index - 1].setValgrind(self.valgrind)
|
||||||
|
|
|
@ -63,7 +63,7 @@ class TDSql:
|
||||||
def checkRows(self, expectRows):
|
def checkRows(self, expectRows):
|
||||||
if self.queryRows != expectRows:
|
if self.queryRows != expectRows:
|
||||||
tdLog.exit(
|
tdLog.exit(
|
||||||
"sql:%.40s, queryRows:%d != expect:%d" %
|
"failed: sql:%.40s, queryRows:%d != expect:%d" %
|
||||||
(self.sql, self.queryRows, expectRows))
|
(self.sql, self.queryRows, expectRows))
|
||||||
tdLog.info("sql:%.40s, queryRows:%d == expect:%d" %
|
tdLog.info("sql:%.40s, queryRows:%d == expect:%d" %
|
||||||
(self.sql, self.queryRows, expectRows))
|
(self.sql, self.queryRows, expectRows))
|
||||||
|
|
|
@ -25,15 +25,17 @@ if [ "$totalFailed" -ne "0" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd ../pytest
|
cd ../pytest
|
||||||
./simpletest.sh 2>&1 | grep 'successfully executed\|failed' | tee pytest-out.txt
|
./simpletest.sh 2>&1 | tee pytest-out.txt
|
||||||
totalPySuccess=`grep 'successfully executed' pytest-out.txt | wc -l`
|
totalPySuccess=`grep 'successfully executed' pytest-out.txt | wc -l`
|
||||||
|
|
||||||
if [ "$totalPySuccess" -gt "0" ]; then
|
if [ "$totalPySuccess" -gt "0" ]; then
|
||||||
|
grep 'successfully executed' pytest-out.txt
|
||||||
echo -e "${GREEN} ### Total $totalPySuccess python case(s) succeed! ### ${NC}"
|
echo -e "${GREEN} ### Total $totalPySuccess python case(s) succeed! ### ${NC}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
totalPyFailed=`grep 'failed' pytest-out.txt | wc -l`
|
totalPyFailed=`grep 'failed\|fault' pytest-out.txt | wc -l`
|
||||||
if [ "$totalPyFailed" -ne "0" ]; then
|
if [ "$totalPyFailed" -ne "0" ]; then
|
||||||
|
cat pytest-out.txt
|
||||||
echo -e "${RED} ### Total $totalPyFailed python case(s) failed! ### ${NC}"
|
echo -e "${RED} ### Total $totalPyFailed python case(s) failed! ### ${NC}"
|
||||||
exit $totalPyFailed
|
exit $totalPyFailed
|
||||||
fi
|
fi
|
||||||
|
|
Loading…
Reference in New Issue