Merge branch 'develop' into queryPercentile
This commit is contained in:
commit
a1b79d8115
|
@ -20,8 +20,8 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "qextbuffer.h"
|
#include "qExtbuffer.h"
|
||||||
#include "qfill.h"
|
#include "qFill.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tlosertree.h"
|
#include "tlosertree.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
|
|
|
@ -23,11 +23,11 @@ extern "C" {
|
||||||
/*
|
/*
|
||||||
* @date 2018/09/30
|
* @date 2018/09/30
|
||||||
*/
|
*/
|
||||||
#include "os.h"
|
|
||||||
#include "tbuffer.h"
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "qextbuffer.h"
|
#include "os.h"
|
||||||
|
#include "qExtbuffer.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
|
#include "tbuffer.h"
|
||||||
#include "tscLocalMerge.h"
|
#include "tscLocalMerge.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,8 @@ extern "C" {
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
#include "qExecutor.h"
|
#include "qExecutor.h"
|
||||||
|
#include "qTsbuf.h"
|
||||||
#include "qsqlparser.h"
|
#include "qsqlparser.h"
|
||||||
#include "qtsbuf.h"
|
|
||||||
#include "tcmdtype.h"
|
#include "tcmdtype.h"
|
||||||
|
|
||||||
// forward declaration
|
// forward declaration
|
||||||
|
@ -52,12 +52,20 @@ typedef struct STableComInfo {
|
||||||
int32_t rowSize;
|
int32_t rowSize;
|
||||||
} STableComInfo;
|
} STableComInfo;
|
||||||
|
|
||||||
|
typedef struct SCMCorVgroupInfo {
|
||||||
|
int32_t version;
|
||||||
|
int8_t inUse;
|
||||||
|
int8_t numOfEps;
|
||||||
|
SEpAddr epAddr[TSDB_MAX_REPLICA];
|
||||||
|
} SCMCorVgroupInfo;
|
||||||
|
|
||||||
typedef struct STableMeta {
|
typedef struct STableMeta {
|
||||||
STableComInfo tableInfo;
|
STableComInfo tableInfo;
|
||||||
uint8_t tableType;
|
uint8_t tableType;
|
||||||
int16_t sversion;
|
int16_t sversion;
|
||||||
int16_t tversion;
|
int16_t tversion;
|
||||||
SCMVgroupInfo vgroupInfo;
|
SCMVgroupInfo vgroupInfo;
|
||||||
|
SCMCorVgroupInfo corVgroupInfo;
|
||||||
int32_t sid; // the index of one table in a virtual node
|
int32_t sid; // the index of one table in a virtual node
|
||||||
uint64_t uid; // unique id of a table
|
uint64_t uid; // unique id of a table
|
||||||
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
|
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
|
||||||
|
@ -456,7 +464,8 @@ extern void * tscQhandle;
|
||||||
extern int tscKeepConn[];
|
extern int tscKeepConn[];
|
||||||
extern int tsInsertHeadSize;
|
extern int tsInsertHeadSize;
|
||||||
extern int tscNumOfThreads;
|
extern int tscNumOfThreads;
|
||||||
extern SRpcEpSet tscMgmtEpSet;
|
|
||||||
|
extern SRpcCorEpSet tscMgmtEpSet;
|
||||||
|
|
||||||
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "qextbuffer.h"
|
#include "qAst.h"
|
||||||
#include "qfill.h"
|
#include "qExtbuffer.h"
|
||||||
#include "qhistogram.h"
|
#include "qFill.h"
|
||||||
#include "qpercentile.h"
|
#include "qHistogram.h"
|
||||||
#include "qsyntaxtreefunction.h"
|
#include "qPercentile.h"
|
||||||
#include "qtsbuf.h"
|
#include "qSyntaxtreefunction.h"
|
||||||
|
#include "qTsbuf.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "qast.h"
|
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
#include "tscompression.h"
|
#include "tscompression.h"
|
||||||
|
@ -74,7 +74,7 @@ for (int32_t i = 0; i < (ctx)->tagInfo.numOfTagCols; ++i) { \
|
||||||
void noop1(SQLFunctionCtx *UNUSED_PARAM(pCtx)) {}
|
void noop1(SQLFunctionCtx *UNUSED_PARAM(pCtx)) {}
|
||||||
void noop2(SQLFunctionCtx *UNUSED_PARAM(pCtx), int32_t UNUSED_PARAM(index)) {}
|
void noop2(SQLFunctionCtx *UNUSED_PARAM(pCtx), int32_t UNUSED_PARAM(index)) {}
|
||||||
|
|
||||||
void doFinalizer(SQLFunctionCtx *pCtx) { resetResultInfo(GET_RES_INFO(pCtx)); }
|
void doFinalizer(SQLFunctionCtx *pCtx) { RESET_RESULT_INFO(GET_RES_INFO(pCtx)); }
|
||||||
|
|
||||||
typedef struct tValuePair {
|
typedef struct tValuePair {
|
||||||
tVariant v;
|
tVariant v;
|
||||||
|
@ -330,12 +330,6 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* the numOfRes should be kept, since it may be used later
|
|
||||||
* and allow the ResultInfo to be re initialized
|
|
||||||
*/
|
|
||||||
void resetResultInfo(SResultInfo *pResInfo) { pResInfo->initialized = false; }
|
|
||||||
|
|
||||||
void setResultInfoBuf(SResultInfo *pResInfo, int32_t size, bool superTable, char* buf) {
|
void setResultInfoBuf(SResultInfo *pResInfo, int32_t size, bool superTable, char* buf) {
|
||||||
assert(pResInfo->interResultBuf == NULL);
|
assert(pResInfo->interResultBuf == NULL);
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
|
|
||||||
#include "tcache.h"
|
#include "qExtbuffer.h"
|
||||||
#include "tscUtil.h"
|
|
||||||
#include "tsclient.h"
|
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tscLog.h"
|
#include "tcache.h"
|
||||||
#include "qextbuffer.h"
|
|
||||||
#include "tschemautil.h"
|
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
|
#include "tscLog.h"
|
||||||
|
#include "tscUtil.h"
|
||||||
|
#include "tschemautil.h"
|
||||||
|
#include "tsclient.h"
|
||||||
|
|
||||||
static void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, int16_t type, size_t valueLength);
|
static void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, int16_t type, size_t valueLength);
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
#include "qAst.h"
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "qast.h"
|
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
|
|
|
@ -140,7 +140,15 @@ struct SSchema tscGetTbnameColumnSchema() {
|
||||||
strcpy(s.name, TSQL_TBNAME_L);
|
strcpy(s.name, TSQL_TBNAME_L);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
static void tscInitCorVgroupInfo(SCMCorVgroupInfo *corVgroupInfo, SCMVgroupInfo *vgroupInfo) {
|
||||||
|
corVgroupInfo->version = 0;
|
||||||
|
corVgroupInfo->inUse = 0;
|
||||||
|
corVgroupInfo->numOfEps = vgroupInfo->numOfEps;
|
||||||
|
for (int32_t i = 0; i < corVgroupInfo->numOfEps; i++) {
|
||||||
|
strncpy(corVgroupInfo->epAddr[i].fqdn, vgroupInfo->epAddr[i].fqdn, TSDB_FQDN_LEN);
|
||||||
|
corVgroupInfo->epAddr[i].port = vgroupInfo->epAddr[i].port;
|
||||||
|
}
|
||||||
|
}
|
||||||
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size) {
|
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size) {
|
||||||
assert(pTableMetaMsg != NULL);
|
assert(pTableMetaMsg != NULL);
|
||||||
|
|
||||||
|
@ -157,6 +165,9 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size
|
||||||
pTableMeta->sid = pTableMetaMsg->sid;
|
pTableMeta->sid = pTableMetaMsg->sid;
|
||||||
pTableMeta->uid = pTableMetaMsg->uid;
|
pTableMeta->uid = pTableMetaMsg->uid;
|
||||||
pTableMeta->vgroupInfo = pTableMetaMsg->vgroup;
|
pTableMeta->vgroupInfo = pTableMetaMsg->vgroup;
|
||||||
|
|
||||||
|
tscInitCorVgroupInfo(&pTableMeta->corVgroupInfo, &pTableMeta->vgroupInfo);
|
||||||
|
|
||||||
pTableMeta->sversion = pTableMetaMsg->sversion;
|
pTableMeta->sversion = pTableMetaMsg->sversion;
|
||||||
pTableMeta->tversion = pTableMetaMsg->tversion;
|
pTableMeta->tversion = pTableMetaMsg->tversion;
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,11 @@
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
#include "ttimer.h"
|
#include "ttimer.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
#include "tlockfree.h"
|
||||||
|
|
||||||
#define TSC_MGMT_VNODE 999
|
#define TSC_MGMT_VNODE 999
|
||||||
|
|
||||||
SRpcEpSet tscMgmtEpSet;
|
SRpcCorEpSet tscMgmtEpSet;
|
||||||
SRpcEpSet tscDnodeEpSet;
|
SRpcEpSet tscDnodeEpSet;
|
||||||
|
|
||||||
int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo) = {0};
|
int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo) = {0};
|
||||||
|
@ -58,33 +59,74 @@ static void tscSetDnodeEpSet(SSqlObj* pSql, SCMVgroupInfo* pVgroupInfo) {
|
||||||
pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
|
pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static void tscDumpMgmtEpSet(SRpcEpSet *epSet) {
|
||||||
|
taosCorBeginRead(&tscMgmtEpSet.version);
|
||||||
|
*epSet = tscMgmtEpSet.epSet;
|
||||||
|
taosCorEndRead(&tscMgmtEpSet.version);
|
||||||
|
}
|
||||||
|
static void tscEpSetHtons(SRpcEpSet *s) {
|
||||||
|
for (int32_t i = 0; i < s->numOfEps; i++) {
|
||||||
|
s->port[i] = htons(s->port[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool tscEpSetIsEqual(SRpcEpSet *s1, SRpcEpSet *s2) {
|
||||||
|
if (s1->numOfEps != s2->numOfEps || s1->inUse != s2->inUse) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int32_t i = 0; i < s1->numOfEps; i++) {
|
||||||
|
if (s1->port[i] != s2->port[i]
|
||||||
|
|| strncmp(s1->fqdn[i], s2->fqdn[i], TSDB_FQDN_LEN) != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void tscUpdateMgmtEpSet(SRpcEpSet *pEpSet) {
|
||||||
|
// no need to update if equal
|
||||||
|
taosCorBeginWrite(&tscMgmtEpSet.version);
|
||||||
|
tscMgmtEpSet.epSet = *pEpSet;
|
||||||
|
taosCorEndWrite(&tscMgmtEpSet.version);
|
||||||
|
}
|
||||||
|
static void tscDumpEpSetFromVgroupInfo(SCMCorVgroupInfo *pVgroupInfo, SRpcEpSet *pEpSet) {
|
||||||
|
if (pVgroupInfo == NULL) { return;}
|
||||||
|
taosCorBeginRead(&pVgroupInfo->version);
|
||||||
|
int8_t inUse = pVgroupInfo->inUse;
|
||||||
|
pEpSet->inUse = (inUse >= 0 && inUse < TSDB_MAX_REPLICA) ? inUse: 0;
|
||||||
|
pEpSet->numOfEps = pVgroupInfo->numOfEps;
|
||||||
|
for (int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) {
|
||||||
|
strncpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn, TSDB_FQDN_LEN);
|
||||||
|
pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
|
||||||
|
}
|
||||||
|
taosCorEndRead(&pVgroupInfo->version);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tscUpdateVgroupInfo(SSqlObj *pObj, SRpcEpSet *pEpSet) {
|
||||||
|
SSqlCmd *pCmd = &pObj->cmd;
|
||||||
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||||
|
if (pTableMetaInfo == NULL || pTableMetaInfo->pTableMeta == NULL) { return;}
|
||||||
|
SCMCorVgroupInfo *pVgroupInfo = &pTableMetaInfo->pTableMeta->corVgroupInfo;
|
||||||
|
|
||||||
|
taosCorBeginWrite(&pVgroupInfo->version);
|
||||||
|
//TODO(dengyihao), dont care vgid
|
||||||
|
pVgroupInfo->inUse = pEpSet->inUse;
|
||||||
|
pVgroupInfo->numOfEps = pEpSet->numOfEps;
|
||||||
|
for (int32_t i = 0; pVgroupInfo->numOfEps; i++) {
|
||||||
|
strncpy(pVgroupInfo->epAddr[i].fqdn, pEpSet->fqdn[i], TSDB_FQDN_LEN);
|
||||||
|
pVgroupInfo->epAddr[i].port = pEpSet->port[i];
|
||||||
|
}
|
||||||
|
taosCorEndWrite(&pVgroupInfo->version);
|
||||||
|
}
|
||||||
void tscPrintMgmtEp() {
|
void tscPrintMgmtEp() {
|
||||||
if (tscMgmtEpSet.numOfEps <= 0) {
|
SRpcEpSet dump;
|
||||||
tscError("invalid mnode EP list:%d", tscMgmtEpSet.numOfEps);
|
tscDumpMgmtEpSet(&dump);
|
||||||
|
if (dump.numOfEps <= 0) {
|
||||||
|
tscError("invalid mnode EP list:%d", dump.numOfEps);
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < tscMgmtEpSet.numOfEps; ++i) {
|
for (int i = 0; i < dump.numOfEps; ++i) {
|
||||||
tscDebug("mnode index:%d %s:%d", i, tscMgmtEpSet.fqdn[i], tscMgmtEpSet.port[i]);
|
tscDebug("mnode index:%d %s:%d", i, dump.fqdn[i], dump.port[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscSetMgmtEpSet(SRpcEpSet *pEpSet) {
|
|
||||||
tscMgmtEpSet.numOfEps = pEpSet->numOfEps;
|
|
||||||
tscMgmtEpSet.inUse = pEpSet->inUse;
|
|
||||||
for (int32_t i = 0; i < tscMgmtEpSet.numOfEps; ++i) {
|
|
||||||
tscMgmtEpSet.port[i] = htons(pEpSet->port[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tscUpdateEpSet(void *ahandle, SRpcEpSet *pEpSet) {
|
|
||||||
tscMgmtEpSet = *pEpSet;
|
|
||||||
tscDebug("mnode EP list is changed for ufp is called, numOfEps:%d inUse:%d", tscMgmtEpSet.numOfEps, tscMgmtEpSet.inUse);
|
|
||||||
for (int32_t i = 0; i < tscMgmtEpSet.numOfEps; ++i) {
|
|
||||||
tscDebug("index:%d fqdn:%s port:%d", i, tscMgmtEpSet.fqdn[i], tscMgmtEpSet.port[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For each management node, try twice at least in case of poor network situation.
|
* For each management node, try twice at least in case of poor network situation.
|
||||||
* If the client start to connect to a non-management node from the client, and the first retry may fail due to
|
* If the client start to connect to a non-management node from the client, and the first retry may fail due to
|
||||||
|
@ -95,7 +137,9 @@ void tscUpdateEpSet(void *ahandle, SRpcEpSet *pEpSet) {
|
||||||
UNUSED_FUNC
|
UNUSED_FUNC
|
||||||
static int32_t tscGetMgmtConnMaxRetryTimes() {
|
static int32_t tscGetMgmtConnMaxRetryTimes() {
|
||||||
int32_t factor = 2;
|
int32_t factor = 2;
|
||||||
return tscMgmtEpSet.numOfEps * factor;
|
SRpcEpSet dump;
|
||||||
|
tscDumpMgmtEpSet(&dump);
|
||||||
|
return dump.numOfEps * factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
||||||
|
@ -111,9 +155,11 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
||||||
|
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
SCMHeartBeatRsp *pRsp = (SCMHeartBeatRsp *)pRes->pRsp;
|
SCMHeartBeatRsp *pRsp = (SCMHeartBeatRsp *)pRes->pRsp;
|
||||||
SRpcEpSet * pEpSet = &pRsp->epSet;
|
SRpcEpSet * epSet = &pRsp->epSet;
|
||||||
if (pEpSet->numOfEps > 0)
|
if (epSet->numOfEps > 0) {
|
||||||
tscSetMgmtEpSet(pEpSet);
|
tscEpSetHtons(epSet);
|
||||||
|
tscUpdateMgmtEpSet(epSet);
|
||||||
|
}
|
||||||
|
|
||||||
pSql->pTscObj->connId = htonl(pRsp->connId);
|
pSql->pTscObj->connId = htonl(pRsp->connId);
|
||||||
|
|
||||||
|
@ -185,7 +231,7 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
||||||
|
|
||||||
// set the mgmt ip list
|
// set the mgmt ip list
|
||||||
if (pSql->cmd.command >= TSDB_SQL_MGMT) {
|
if (pSql->cmd.command >= TSDB_SQL_MGMT) {
|
||||||
pSql->epSet = tscMgmtEpSet;
|
tscDumpMgmtEpSet(&pSql->epSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(pMsg, pSql->cmd.payload, pSql->cmd.payloadLen);
|
memcpy(pMsg, pSql->cmd.payload, pSql->cmd.payloadLen);
|
||||||
|
@ -236,41 +282,28 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pEpSet) {
|
||||||
|
//SRpcEpSet dump;
|
||||||
|
tscEpSetHtons(pEpSet);
|
||||||
|
if (tscEpSetIsEqual(&pSql->epSet, pEpSet)) {
|
||||||
if(pCmd->command < TSDB_SQL_MGMT) {
|
if(pCmd->command < TSDB_SQL_MGMT) {
|
||||||
if (pEpSet) pSql->epSet = *pEpSet;
|
tscUpdateVgroupInfo(pSql, pEpSet);
|
||||||
} else {
|
} else {
|
||||||
if (pEpSet) tscMgmtEpSet = *pEpSet;
|
tscUpdateMgmtEpSet(pEpSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rpcMsg->pCont == NULL) {
|
|
||||||
rpcMsg->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
|
||||||
} else {
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||||
// if (rpcMsg->code != TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
|
||||||
// if (pCmd->command == TSDB_SQL_CONNECT) {
|
|
||||||
// rpcMsg->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
|
||||||
// rpcFreeCont(rpcMsg->pCont);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (pCmd->command == TSDB_SQL_HB) {
|
int32_t cmd = pCmd->command;
|
||||||
// rpcMsg->code = TSDB_CODE_RPC_NOT_READY;
|
if ((cmd == TSDB_SQL_SELECT || cmd == TSDB_SQL_FETCH || cmd == TSDB_SQL_INSERT || cmd == TSDB_SQL_UPDATE_TAGS_VAL) &&
|
||||||
// rpcFreeCont(rpcMsg->pCont);
|
(rpcMsg->code == TSDB_CODE_TDB_INVALID_TABLE_ID ||
|
||||||
// return;
|
rpcMsg->code == TSDB_CODE_VND_INVALID_VGROUP_ID ||
|
||||||
// }
|
rpcMsg->code == TSDB_CODE_RPC_NETWORK_UNAVAIL ||
|
||||||
|
rpcMsg->code == TSDB_CODE_TDB_TABLE_RECONFIGURE)) {
|
||||||
// if (pCmd->command == TSDB_SQL_META || pCmd->command == TSDB_SQL_DESCRIBE_TABLE ||
|
|
||||||
// pCmd->command == TSDB_SQL_STABLEVGROUP || pCmd->command == TSDB_SQL_SHOW ||
|
|
||||||
// pCmd->command == TSDB_SQL_RETRIEVE) {
|
|
||||||
// // get table meta/vgroup query will not retry, do nothing
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if ((pCmd->command == TSDB_SQL_SELECT || pCmd->command == TSDB_SQL_FETCH || pCmd->command == TSDB_SQL_INSERT ||
|
|
||||||
pCmd->command == TSDB_SQL_UPDATE_TAGS_VAL) &&
|
|
||||||
(rpcMsg->code == TSDB_CODE_TDB_INVALID_TABLE_ID || rpcMsg->code == TSDB_CODE_VND_INVALID_VGROUP_ID ||
|
|
||||||
rpcMsg->code == TSDB_CODE_RPC_NETWORK_UNAVAIL || rpcMsg->code == TSDB_CODE_TDB_TABLE_RECONFIGURE)) {
|
|
||||||
tscWarn("%p it shall renew table meta, code:%s, retry:%d", pSql, tstrerror(rpcMsg->code), ++pSql->retry);
|
tscWarn("%p it shall renew table meta, code:%s, retry:%d", pSql, tstrerror(rpcMsg->code), ++pSql->retry);
|
||||||
|
|
||||||
// set the flag to denote that sql string needs to be re-parsed and build submit block with table schema
|
// set the flag to denote that sql string needs to be re-parsed and build submit block with table schema
|
||||||
if (rpcMsg->code == TSDB_CODE_TDB_TABLE_RECONFIGURE) {
|
if (rpcMsg->code == TSDB_CODE_TDB_TABLE_RECONFIGURE) {
|
||||||
pSql->cmd.submitSchema = 1;
|
pSql->cmd.submitSchema = 1;
|
||||||
|
@ -283,14 +316,12 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
||||||
rpcMsg->code = tscRenewTableMeta(pSql, pTableMetaInfo->name);
|
rpcMsg->code = tscRenewTableMeta(pSql, pTableMetaInfo->name);
|
||||||
|
|
||||||
// if there is an error occurring, proceed to the following error handling procedure.
|
// if there is an error occurring, proceed to the following error handling procedure.
|
||||||
// todo add test cases
|
|
||||||
if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
rpcFreeCont(rpcMsg->pCont);
|
rpcFreeCont(rpcMsg->pCont);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pRes->rspLen = 0;
|
pRes->rspLen = 0;
|
||||||
|
|
||||||
|
@ -421,7 +452,8 @@ int tscProcessSql(SSqlObj *pSql) {
|
||||||
return pSql->res.code;
|
return pSql->res.code;
|
||||||
}
|
}
|
||||||
} else if (pCmd->command < TSDB_SQL_LOCAL) {
|
} else if (pCmd->command < TSDB_SQL_LOCAL) {
|
||||||
pSql->epSet = tscMgmtEpSet;
|
|
||||||
|
//pSql->epSet = tscMgmtEpSet;
|
||||||
} else { // local handler
|
} else { // local handler
|
||||||
return (*tscProcessMsgRsp[pCmd->command])(pSql);
|
return (*tscProcessMsgRsp[pCmd->command])(pSql);
|
||||||
}
|
}
|
||||||
|
@ -525,7 +557,7 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
|
|
||||||
// pSql->cmd.payloadLen is set during copying data into payload
|
// pSql->cmd.payloadLen is set during copying data into payload
|
||||||
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
||||||
tscSetDnodeEpSet(pSql, &pTableMeta->vgroupInfo);
|
tscDumpEpSetFromVgroupInfo(&pTableMeta->corVgroupInfo, &pSql->epSet);
|
||||||
|
|
||||||
tscDebug("%p build submit msg, vgId:%d numOfTables:%d numberOfEP:%d", pSql, vgId, pSql->cmd.numOfTablesInSubmit,
|
tscDebug("%p build submit msg, vgId:%d numOfTables:%d numberOfEP:%d", pSql, vgId, pSql->cmd.numOfTablesInSubmit,
|
||||||
pSql->epSet.numOfEps);
|
pSql->epSet.numOfEps);
|
||||||
|
@ -567,8 +599,8 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
||||||
} else {
|
} else {
|
||||||
pVgroupInfo = &pTableMeta->vgroupInfo;
|
pVgroupInfo = &pTableMeta->vgroupInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
tscSetDnodeEpSet(pSql, pVgroupInfo);
|
tscSetDnodeEpSet(pSql, pVgroupInfo);
|
||||||
|
|
||||||
if (pVgroupInfo != NULL) {
|
if (pVgroupInfo != NULL) {
|
||||||
pQueryMsg->head.vgId = htonl(pVgroupInfo->vgId);
|
pQueryMsg->head.vgId = htonl(pVgroupInfo->vgId);
|
||||||
}
|
}
|
||||||
|
@ -1136,11 +1168,11 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pShowMsg->payloadLen = htons(pPattern->n);
|
pShowMsg->payloadLen = htons(pPattern->n);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SSQLToken *pIpAddr = &pShowInfo->prefix;
|
SSQLToken *pEpAddr = &pShowInfo->prefix;
|
||||||
assert(pIpAddr->n > 0 && pIpAddr->type > 0);
|
assert(pEpAddr->n > 0 && pEpAddr->type > 0);
|
||||||
|
|
||||||
strncpy(pShowMsg->payload, pIpAddr->z, pIpAddr->n);
|
strncpy(pShowMsg->payload, pEpAddr->z, pEpAddr->n);
|
||||||
pShowMsg->payloadLen = htons(pIpAddr->n);
|
pShowMsg->payloadLen = htons(pEpAddr->n);
|
||||||
}
|
}
|
||||||
|
|
||||||
pCmd->payloadLen = sizeof(SCMShowMsg) + pShowMsg->payloadLen;
|
pCmd->payloadLen = sizeof(SCMShowMsg) + pShowMsg->payloadLen;
|
||||||
|
@ -1323,7 +1355,7 @@ int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) {
|
||||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
tscSetDnodeEpSet(pSql, &pTableMetaInfo->pTableMeta->vgroupInfo);
|
tscDumpEpSetFromVgroupInfo(&pTableMetaInfo->pTableMeta->corVgroupInfo, &pSql->epSet);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1847,13 +1879,14 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
memcpy(pInfo->vgroupList, pVgroupInfo, size);
|
memcpy(pInfo->vgroupList, pVgroupInfo, size);
|
||||||
for (int32_t j = 0; j < pInfo->vgroupList->numOfVgroups; ++j) {
|
for (int32_t j = 0; j < pInfo->vgroupList->numOfVgroups; ++j) {
|
||||||
|
//just init, no need to lock
|
||||||
SCMVgroupInfo *pVgroups = &pInfo->vgroupList->vgroups[j];
|
SCMVgroupInfo *pVgroups = &pInfo->vgroupList->vgroups[j];
|
||||||
|
|
||||||
pVgroups->vgId = htonl(pVgroups->vgId);
|
pVgroups->vgId = htonl(pVgroups->vgId);
|
||||||
assert(pVgroups->numOfEps >= 1);
|
assert(pVgroups->numOfEps >= 1);
|
||||||
|
|
||||||
for (int32_t k = 0; k < pVgroups->numOfEps; ++k) {
|
for (int32_t k = 0; k < pVgroups->numOfEps; ++k) {
|
||||||
pVgroups->epAddr[k].port = htons(pVgroups->epAddr[k].port);
|
pVgroups->epAddr[k].port = htons(pVgroups->epAddr[k].port);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pMsg += size;
|
pMsg += size;
|
||||||
|
@ -1946,8 +1979,10 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
|
||||||
assert(len <= sizeof(pObj->db));
|
assert(len <= sizeof(pObj->db));
|
||||||
tstrncpy(pObj->db, temp, sizeof(pObj->db));
|
tstrncpy(pObj->db, temp, sizeof(pObj->db));
|
||||||
|
|
||||||
if (pConnect->epSet.numOfEps > 0)
|
if (pConnect->epSet.numOfEps > 0) {
|
||||||
tscSetMgmtEpSet(&pConnect->epSet);
|
tscEpSetHtons(&pConnect->epSet);
|
||||||
|
tscUpdateMgmtEpSet(&pConnect->epSet);
|
||||||
|
}
|
||||||
|
|
||||||
strcpy(pObj->sversion, pConnect->serverVersion);
|
strcpy(pObj->sversion, pConnect->serverVersion);
|
||||||
pObj->writeAuth = pConnect->writeAuth;
|
pObj->writeAuth = pConnect->writeAuth;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "qast.h"
|
#include "qAst.h"
|
||||||
#include "tcache.h"
|
#include "tcache.h"
|
||||||
#include "tnote.h"
|
#include "tnote.h"
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
|
@ -63,7 +63,7 @@ SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pass, con
|
||||||
|
|
||||||
if (ip) {
|
if (ip) {
|
||||||
if (tscSetMgmtEpSetFromCfg(ip, NULL) < 0) return NULL;
|
if (tscSetMgmtEpSetFromCfg(ip, NULL) < 0) return NULL;
|
||||||
if (port) tscMgmtEpSet.port[0] = port;
|
if (port) tscMgmtEpSet.epSet.port[0] = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *pDnodeConn = NULL;
|
void *pDnodeConn = NULL;
|
||||||
|
@ -724,6 +724,13 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void asyncCallback(void *param, TAOS_RES *tres, int code) {
|
||||||
|
assert(param != NULL);
|
||||||
|
SSqlObj *pSql = ((SSqlObj *)param);
|
||||||
|
pSql->res.code = code;
|
||||||
|
sem_post(&pSql->rspSem);
|
||||||
|
}
|
||||||
|
|
||||||
int taos_validate_sql(TAOS *taos, const char *sql) {
|
int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
STscObj *pObj = (STscObj *)taos;
|
STscObj *pObj = (STscObj *)taos;
|
||||||
if (pObj == NULL || pObj->signature != pObj) {
|
if (pObj == NULL || pObj->signature != pObj) {
|
||||||
|
@ -732,7 +739,8 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||||
|
pSql->pTscObj = taos;
|
||||||
|
pSql->signature = pSql;
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
||||||
|
@ -766,10 +774,17 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
pCmd->pTableList = NULL;
|
pCmd->pTableList = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pRes->code = (uint8_t)tsParseSql(pSql, false);
|
pSql->fp = asyncCallback;
|
||||||
int code = pRes->code;
|
pSql->fetchFp = asyncCallback;
|
||||||
|
pSql->param = pSql;
|
||||||
tscDebug("%p Valid SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(taos), pObj);
|
int code = tsParseSql(pSql, true);
|
||||||
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
|
sem_wait(&pSql->rspSem);
|
||||||
|
code = pSql->res.code;
|
||||||
|
}
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tscDebug("%p Valid SQL result:%d, %s pObj:%p", pSql, code, taos_errstr(taos), pObj);
|
||||||
|
}
|
||||||
taos_free_result(pSql);
|
taos_free_result(pSql);
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -865,6 +880,8 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||||
|
pSql->pTscObj = taos;
|
||||||
|
pSql->signature = pSql;
|
||||||
SSqlRes *pRes = &pSql->res;
|
SSqlRes *pRes = &pSql->res;
|
||||||
|
|
||||||
pRes->numOfTotal = 0; // the number of getting table meta from server
|
pRes->numOfTotal = 0; // the number of getting table meta from server
|
||||||
|
|
|
@ -122,7 +122,7 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) {
|
||||||
pQueryInfo->window.ekey = pStream->etime;
|
pQueryInfo->window.ekey = pStream->etime;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pQueryInfo->window.skey = pStream->stime - pStream->interval;
|
pQueryInfo->window.skey = pStream->stime;
|
||||||
int64_t etime = taosGetTimestamp(pStream->precision);
|
int64_t etime = taosGetTimestamp(pStream->precision);
|
||||||
// delay to wait all data in last time window
|
// delay to wait all data in last time window
|
||||||
if (pStream->precision == TSDB_TIME_PRECISION_MICRO) {
|
if (pStream->precision == TSDB_TIME_PRECISION_MICRO) {
|
||||||
|
@ -232,6 +232,9 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
||||||
(*pStream->fp)(pStream->param, res, row);
|
(*pStream->fp)(pStream->param, res, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pStream->isProject) {
|
||||||
|
pStream->stime += pStream->slidingTime;
|
||||||
|
}
|
||||||
// actually only one row is returned. this following is not necessary
|
// actually only one row is returned. this following is not necessary
|
||||||
taos_fetch_rows_a(res, tscProcessStreamRetrieveResult, pStream);
|
taos_fetch_rows_a(res, tscProcessStreamRetrieveResult, pStream);
|
||||||
} else { // numOfRows == 0, all data has been retrieved
|
} else { // numOfRows == 0, all data has been retrieved
|
||||||
|
@ -432,6 +435,7 @@ static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, in
|
||||||
} else { // timewindow based aggregation stream
|
} else { // timewindow based aggregation stream
|
||||||
if (stime == 0) { // no data in meter till now
|
if (stime == 0) { // no data in meter till now
|
||||||
stime = ((int64_t)taosGetTimestamp(pStream->precision) / pStream->interval) * pStream->interval;
|
stime = ((int64_t)taosGetTimestamp(pStream->precision) / pStream->interval) * pStream->interval;
|
||||||
|
stime -= pStream->interval;
|
||||||
tscWarn("%p stream:%p, last timestamp:0, reset to:%" PRId64, pSql, pStream, stime);
|
tscWarn("%p stream:%p, last timestamp:0, reset to:%" PRId64, pSql, pStream, stime);
|
||||||
} else {
|
} else {
|
||||||
int64_t newStime = (stime / pStream->interval) * pStream->interval;
|
int64_t newStime = (stime / pStream->interval) * pStream->interval;
|
||||||
|
|
|
@ -34,6 +34,7 @@ typedef struct SSubscriptionProgress {
|
||||||
typedef struct SSub {
|
typedef struct SSub {
|
||||||
void * signature;
|
void * signature;
|
||||||
char topic[32];
|
char topic[32];
|
||||||
|
sem_t sem;
|
||||||
int64_t lastSyncTime;
|
int64_t lastSyncTime;
|
||||||
int64_t lastConsumeTime;
|
int64_t lastConsumeTime;
|
||||||
TAOS * taos;
|
TAOS * taos;
|
||||||
|
@ -83,84 +84,108 @@ void tscUpdateSubscriptionProgress(void* sub, int64_t uid, TSKEY ts) {
|
||||||
|
|
||||||
static void asyncCallback(void *param, TAOS_RES *tres, int code) {
|
static void asyncCallback(void *param, TAOS_RES *tres, int code) {
|
||||||
assert(param != NULL);
|
assert(param != NULL);
|
||||||
SSqlObj *pSql = ((SSqlObj *)param);
|
SSub *pSub = ((SSub *)param);
|
||||||
|
pSub->pSql->res.code = code;
|
||||||
pSql->res.code = code;
|
sem_post(&pSub->sem);
|
||||||
sem_post(&pSql->rspSem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char* sql) {
|
static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char* sql) {
|
||||||
SSub* pSub = NULL;
|
int code = TSDB_CODE_SUCCESS, line = __LINE__;
|
||||||
|
SSqlObj* pSql = NULL;
|
||||||
|
|
||||||
|
SSub* pSub = calloc(1, sizeof(SSub));
|
||||||
|
if (pSub == NULL) {
|
||||||
|
line = __LINE__;
|
||||||
|
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
pSub->signature = pSub;
|
||||||
|
if (tsem_init(&pSub->sem, 0, 0) == -1) {
|
||||||
|
line = __LINE__;
|
||||||
|
code = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
tstrncpy(pSub->topic, topic, sizeof(pSub->topic));
|
||||||
|
pSub->progress = taosArrayInit(32, sizeof(SSubscriptionProgress));
|
||||||
|
if (pSub->progress == NULL) {
|
||||||
|
line = __LINE__;
|
||||||
|
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSql = calloc(1, sizeof(SSqlObj));
|
||||||
|
if (pSql == NULL) {
|
||||||
|
line = __LINE__;
|
||||||
|
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
pSql->signature = pSql;
|
||||||
|
pSql->pTscObj = pObj;
|
||||||
|
pSql->pSubscription = pSub;
|
||||||
|
pSub->pSql = pSql;
|
||||||
|
|
||||||
TRY( 8 ) {
|
|
||||||
SSqlObj* pSql = calloc_throw(1, sizeof(SSqlObj));
|
|
||||||
CLEANUP_PUSH_FREE(true, pSql);
|
|
||||||
SSqlCmd* pCmd = &pSql->cmd;
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
SSqlRes* pRes = &pSql->res;
|
SSqlRes* pRes = &pSql->res;
|
||||||
|
|
||||||
if (tsem_init(&pSql->rspSem, 0, 0) == -1) {
|
if (tsem_init(&pSql->rspSem, 0, 0) == -1) {
|
||||||
THROW(TAOS_SYSTEM_ERROR(errno));
|
line = __LINE__;
|
||||||
|
code = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
CLEANUP_PUSH_INT_PTR(true, tsem_destroy, &pSql->rspSem);
|
|
||||||
|
|
||||||
pSql->signature = pSql;
|
pSql->param = pSub;
|
||||||
pSql->param = pSql;
|
|
||||||
pSql->pTscObj = pObj;
|
|
||||||
pSql->maxRetry = TSDB_MAX_REPLICA;
|
pSql->maxRetry = TSDB_MAX_REPLICA;
|
||||||
pSql->fp = asyncCallback;
|
pSql->fp = asyncCallback;
|
||||||
|
pSql->fetchFp = asyncCallback;
|
||||||
int code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
pSql->sqlstr = strdup(sql);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (pSql->sqlstr == NULL) {
|
||||||
THROW(code);
|
line = __LINE__;
|
||||||
|
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
CLEANUP_PUSH_FREE(true, pCmd->payload);
|
strtolower(pSql->sqlstr, pSql->sqlstr);
|
||||||
|
|
||||||
pRes->qhandle = 0;
|
pRes->qhandle = 0;
|
||||||
pRes->numOfRows = 1;
|
pRes->numOfRows = 1;
|
||||||
|
|
||||||
pSql->sqlstr = strdup_throw(sql);
|
code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||||
CLEANUP_PUSH_FREE(true, pSql->sqlstr);
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
strtolower(pSql->sqlstr, pSql->sqlstr);
|
line = __LINE__;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
code = tsParseSql(pSql, false);
|
code = tsParseSql(pSql, false);
|
||||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
// wait for the callback function to post the semaphore
|
sem_wait(&pSub->sem);
|
||||||
sem_wait(&pSql->rspSem);
|
|
||||||
code = pSql->res.code;
|
code = pSql->res.code;
|
||||||
}
|
}
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
tscError("failed to parse sql statement: %s, error: %s", pSub->topic, tstrerror(code));
|
line = __LINE__;
|
||||||
THROW( code );
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSql->cmd.command != TSDB_SQL_SELECT) {
|
if (pSql->cmd.command != TSDB_SQL_SELECT) {
|
||||||
tscError("only 'select' statement is allowed in subscription: %s", pSub->topic);
|
line = __LINE__;
|
||||||
THROW( -1 ); // TODO
|
code = TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSub = calloc_throw(1, sizeof(SSub));
|
|
||||||
CLEANUP_PUSH_FREE(true, pSub);
|
|
||||||
pSql->pSubscription = pSub;
|
|
||||||
pSub->pSql = pSql;
|
|
||||||
pSub->signature = pSub;
|
|
||||||
strncpy(pSub->topic, topic, sizeof(pSub->topic));
|
|
||||||
pSub->topic[sizeof(pSub->topic) - 1] = 0;
|
|
||||||
pSub->progress = taosArrayInit(32, sizeof(SSubscriptionProgress));
|
|
||||||
if (pSub->progress == NULL) {
|
|
||||||
THROW(TSDB_CODE_TSC_OUT_OF_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
CLEANUP_EXECUTE();
|
|
||||||
|
|
||||||
} CATCH( code ) {
|
|
||||||
tscError("failed to create subscription object: %s", tstrerror(code));
|
|
||||||
CLEANUP_EXECUTE();
|
|
||||||
pSub = NULL;
|
|
||||||
|
|
||||||
} END_TRY
|
|
||||||
|
|
||||||
return pSub;
|
return pSub;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
tscError("tscCreateSubscription failed at line %d, reason: %s", line, tstrerror(code));
|
||||||
|
if (pSql != NULL) {
|
||||||
|
tscFreeSqlObj(pSql);
|
||||||
|
pSql = NULL;
|
||||||
|
}
|
||||||
|
if (pSub != NULL) {
|
||||||
|
taosArrayDestroy(pSub->progress);
|
||||||
|
tsem_destroy(&pSub->sem);
|
||||||
|
free(pSub);
|
||||||
|
pSub = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
terrno = code;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -405,9 +430,10 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
||||||
tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->vgroupIndex = 0;
|
tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->vgroupIndex = 0;
|
||||||
|
|
||||||
pSql->fp = asyncCallback;
|
pSql->fp = asyncCallback;
|
||||||
pSql->param = pSql;
|
pSql->fetchFp = asyncCallback;
|
||||||
|
pSql->param = pSub;
|
||||||
tscDoQuery(pSql);
|
tscDoQuery(pSql);
|
||||||
sem_wait(&pSql->rspSem);
|
sem_wait(&pSub->sem);
|
||||||
|
|
||||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -437,7 +463,9 @@ void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keepProgress) {
|
if (keepProgress) {
|
||||||
|
if (pSub->progress != NULL) {
|
||||||
tscSaveSubscriptionProgress(pSub);
|
tscSaveSubscriptionProgress(pSub);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
char path[256];
|
char path[256];
|
||||||
sprintf(path, "%s/subscribe/%s", tsDataDir, pSub->topic);
|
sprintf(path, "%s/subscribe/%s", tsDataDir, pSub->topic);
|
||||||
|
@ -448,6 +476,7 @@ void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress) {
|
||||||
|
|
||||||
tscFreeSqlObj(pSub->pSql);
|
tscFreeSqlObj(pSub->pSql);
|
||||||
taosArrayDestroy(pSub->progress);
|
taosArrayDestroy(pSub->progress);
|
||||||
|
tsem_destroy(&pSub->sem);
|
||||||
memset(pSub, 0, sizeof(*pSub));
|
memset(pSub, 0, sizeof(*pSub));
|
||||||
free(pSub);
|
free(pSub);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
*/
|
*/
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "qtsbuf.h"
|
#include "qAst.h"
|
||||||
#include "qast.h"
|
#include "qTsbuf.h"
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
|
|
|
@ -41,7 +41,7 @@ int tscNumOfThreads;
|
||||||
|
|
||||||
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
||||||
void taosInitNote(int numOfNoteLines, int maxNotes, char* lable);
|
void taosInitNote(int numOfNoteLines, int maxNotes, char* lable);
|
||||||
void tscUpdateEpSet(void *ahandle, SRpcEpSet *pEpSet);
|
//void tscUpdateEpSet(void *ahandle, SRpcEpSet *pEpSet);
|
||||||
|
|
||||||
void tscCheckDiskUsage(void *UNUSED_PARAM(para), void* UNUSED_PARAM(param)) {
|
void tscCheckDiskUsage(void *UNUSED_PARAM(para), void* UNUSED_PARAM(param)) {
|
||||||
taosGetDisk();
|
taosGetDisk();
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "os.h"
|
|
||||||
#include "hash.h"
|
|
||||||
#include "tscUtil.h"
|
#include "tscUtil.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "os.h"
|
||||||
|
#include "qAst.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "qast.h"
|
|
||||||
#include "tcache.h"
|
#include "tcache.h"
|
||||||
#include "tkey.h"
|
#include "tkey.h"
|
||||||
#include "tmd5.h"
|
#include "tmd5.h"
|
||||||
|
@ -2146,16 +2146,19 @@ char* strdup_throw(const char* str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscSetMgmtEpSetFromCfg(const char *first, const char *second) {
|
int tscSetMgmtEpSetFromCfg(const char *first, const char *second) {
|
||||||
tscMgmtEpSet.numOfEps = 0;
|
// init mgmt ip set
|
||||||
tscMgmtEpSet.inUse = 0;
|
tscMgmtEpSet.version = 0;
|
||||||
|
SRpcEpSet *mgmtEpSet = &(tscMgmtEpSet.epSet);
|
||||||
|
mgmtEpSet->numOfEps = 0;
|
||||||
|
mgmtEpSet->inUse = 0;
|
||||||
|
|
||||||
if (first && first[0] != 0) {
|
if (first && first[0] != 0) {
|
||||||
if (strlen(first) >= TSDB_EP_LEN) {
|
if (strlen(first) >= TSDB_EP_LEN) {
|
||||||
terrno = TSDB_CODE_TSC_INVALID_FQDN;
|
terrno = TSDB_CODE_TSC_INVALID_FQDN;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
taosGetFqdnPortFromEp(first, tscMgmtEpSet.fqdn[tscMgmtEpSet.numOfEps], &tscMgmtEpSet.port[tscMgmtEpSet.numOfEps]);
|
taosGetFqdnPortFromEp(first, mgmtEpSet->fqdn[mgmtEpSet->numOfEps], &(mgmtEpSet->port[mgmtEpSet->numOfEps]));
|
||||||
tscMgmtEpSet.numOfEps++;
|
mgmtEpSet->numOfEps++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (second && second[0] != 0) {
|
if (second && second[0] != 0) {
|
||||||
|
@ -2163,11 +2166,11 @@ int tscSetMgmtEpSetFromCfg(const char *first, const char *second) {
|
||||||
terrno = TSDB_CODE_TSC_INVALID_FQDN;
|
terrno = TSDB_CODE_TSC_INVALID_FQDN;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
taosGetFqdnPortFromEp(second, tscMgmtEpSet.fqdn[tscMgmtEpSet.numOfEps], &tscMgmtEpSet.port[tscMgmtEpSet.numOfEps]);
|
taosGetFqdnPortFromEp(second, mgmtEpSet->fqdn[mgmtEpSet->numOfEps], &(mgmtEpSet->port[mgmtEpSet->numOfEps]));
|
||||||
tscMgmtEpSet.numOfEps++;
|
mgmtEpSet->numOfEps++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( tscMgmtEpSet.numOfEps == 0) {
|
if (mgmtEpSet->numOfEps == 0) {
|
||||||
terrno = TSDB_CODE_TSC_INVALID_FQDN;
|
terrno = TSDB_CODE_TSC_INVALID_FQDN;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,8 +67,6 @@ DLL_EXPORT void taos_init();
|
||||||
DLL_EXPORT void taos_cleanup();
|
DLL_EXPORT void taos_cleanup();
|
||||||
DLL_EXPORT int taos_options(TSDB_OPTION option, const void *arg, ...);
|
DLL_EXPORT int taos_options(TSDB_OPTION option, const void *arg, ...);
|
||||||
DLL_EXPORT TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
|
DLL_EXPORT TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
|
||||||
DLL_EXPORT TAOS *taos_connect_c(const char *ip, uint8_t ipLen, const char *user, uint8_t userLen,
|
|
||||||
const char *pass, uint8_t passLen, const char *db, uint8_t dbLen, uint16_t port);
|
|
||||||
DLL_EXPORT void taos_close(TAOS *taos);
|
DLL_EXPORT void taos_close(TAOS *taos);
|
||||||
|
|
||||||
typedef struct TAOS_BIND {
|
typedef struct TAOS_BIND {
|
||||||
|
@ -90,7 +88,6 @@ TAOS_RES * taos_stmt_use_result(TAOS_STMT *stmt);
|
||||||
int taos_stmt_close(TAOS_STMT *stmt);
|
int taos_stmt_close(TAOS_STMT *stmt);
|
||||||
|
|
||||||
DLL_EXPORT TAOS_RES *taos_query(TAOS *taos, const char *sql);
|
DLL_EXPORT TAOS_RES *taos_query(TAOS *taos, const char *sql);
|
||||||
DLL_EXPORT TAOS_RES *taos_query_c(TAOS *taos, const char *sql, uint32_t sqlLen);
|
|
||||||
DLL_EXPORT TAOS_ROW taos_fetch_row(TAOS_RES *res);
|
DLL_EXPORT TAOS_ROW taos_fetch_row(TAOS_RES *res);
|
||||||
DLL_EXPORT int taos_result_precision(TAOS_RES *res); // get the time precision of result
|
DLL_EXPORT int taos_result_precision(TAOS_RES *res); // get the time precision of result
|
||||||
DLL_EXPORT void taos_free_result(TAOS_RES *res);
|
DLL_EXPORT void taos_free_result(TAOS_RES *res);
|
||||||
|
|
|
@ -35,6 +35,11 @@ typedef struct SRpcEpSet {
|
||||||
char fqdn[TSDB_MAX_REPLICA][TSDB_FQDN_LEN];
|
char fqdn[TSDB_MAX_REPLICA][TSDB_FQDN_LEN];
|
||||||
} SRpcEpSet;
|
} SRpcEpSet;
|
||||||
|
|
||||||
|
typedef struct SRpcCorEpSet {
|
||||||
|
int32_t version;
|
||||||
|
SRpcEpSet epSet;
|
||||||
|
} SRpcCorEpSet;
|
||||||
|
|
||||||
typedef struct SRpcConnInfo {
|
typedef struct SRpcConnInfo {
|
||||||
uint32_t clientIp;
|
uint32_t clientIp;
|
||||||
uint16_t clientPort;
|
uint16_t clientPort;
|
||||||
|
|
|
@ -361,7 +361,7 @@ int main(int argc, char *argv[]) {
|
||||||
arguments.num_of_DPT = 100000;
|
arguments.num_of_DPT = 100000;
|
||||||
arguments.num_of_RPR = 1000;
|
arguments.num_of_RPR = 1000;
|
||||||
arguments.use_metric = true;
|
arguments.use_metric = true;
|
||||||
arguments.insert_only = true;
|
arguments.insert_only = false;
|
||||||
// end change
|
// end change
|
||||||
|
|
||||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||||
|
@ -954,13 +954,13 @@ void *readMetric(void *sarg) {
|
||||||
|
|
||||||
for (int i = 1; i <= m; i++) {
|
for (int i = 1; i <= m; i++) {
|
||||||
if (i == 1) {
|
if (i == 1) {
|
||||||
sprintf(tempS, "index = %d", i);
|
sprintf(tempS, "areaid = %d", i);
|
||||||
} else {
|
} else {
|
||||||
sprintf(tempS, " or index = %d ", i);
|
sprintf(tempS, " or areaid = %d ", i);
|
||||||
}
|
}
|
||||||
strcat(condition, tempS);
|
strcat(condition, tempS);
|
||||||
|
|
||||||
sprintf(command, "select %s from m1 where %s", aggreFunc[j], condition);
|
sprintf(command, "select %s from meters where %s", aggreFunc[j], condition);
|
||||||
|
|
||||||
printf("Where condition: %s\n", condition);
|
printf("Where condition: %s\n", condition);
|
||||||
fprintf(fp, "%s\n", command);
|
fprintf(fp, "%s\n", command);
|
||||||
|
|
|
@ -45,7 +45,6 @@ typedef void (*__do_filter_suppl_fn_t)(void *, void *);
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef struct tQueryInfo {
|
typedef struct tQueryInfo {
|
||||||
int32_t colIndex; // index of column in schema
|
|
||||||
uint8_t optr; // expression operator
|
uint8_t optr; // expression operator
|
||||||
SSchema sch; // schema of tags
|
SSchema sch; // schema of tags
|
||||||
char* q;
|
char* q;
|
|
@ -18,16 +18,16 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "qfill.h"
|
#include "qFill.h"
|
||||||
#include "qresultBuf.h"
|
#include "qResultbuf.h"
|
||||||
|
#include "qTsbuf.h"
|
||||||
#include "qsqlparser.h"
|
#include "qsqlparser.h"
|
||||||
#include "qtsbuf.h"
|
#include "query.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "tlockfree.h"
|
#include "tlockfree.h"
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
#include "tsqlfunction.h"
|
#include "tsqlfunction.h"
|
||||||
#include "query.h"
|
|
||||||
|
|
||||||
struct SColumnFilterElem;
|
struct SColumnFilterElem;
|
||||||
typedef bool (*__filter_func_t)(struct SColumnFilterElem* pFilter, char* val1, char* val2);
|
typedef bool (*__filter_func_t)(struct SColumnFilterElem* pFilter, char* val1, char* val2);
|
||||||
|
@ -158,7 +158,7 @@ typedef struct SQueryRuntimeEnv {
|
||||||
SResultInfo* resultInfo; // todo refactor to merge with SWindowResInfo
|
SResultInfo* resultInfo; // todo refactor to merge with SWindowResInfo
|
||||||
SQuery* pQuery;
|
SQuery* pQuery;
|
||||||
SQLFunctionCtx* pCtx;
|
SQLFunctionCtx* pCtx;
|
||||||
int16_t numOfRowsPerPage;
|
int32_t numOfRowsPerPage;
|
||||||
int16_t offset[TSDB_MAX_COLUMNS];
|
int16_t offset[TSDB_MAX_COLUMNS];
|
||||||
uint16_t scanFlag; // denotes reversed scan of data or not
|
uint16_t scanFlag; // denotes reversed scan of data or not
|
||||||
SFillInfo* pFillInfo;
|
SFillInfo* pFillInfo;
|
||||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
||||||
#include "tdataformat.h"
|
#include "tdataformat.h"
|
||||||
#include "talgo.h"
|
#include "talgo.h"
|
||||||
|
|
||||||
#define DEFAULT_PAGE_SIZE (1024L*64) // 16k larger than the SHistoInfo
|
#define DEFAULT_PAGE_SIZE (1024L*4) // 16k larger than the SHistoInfo
|
||||||
#define MAX_TMPFILE_PATH_LENGTH PATH_MAX
|
#define MAX_TMPFILE_PATH_LENGTH PATH_MAX
|
||||||
#define INITIAL_ALLOCATION_BUFFER_SIZE 64
|
#define INITIAL_ALLOCATION_BUFFER_SIZE 64
|
||||||
|
|
|
@ -21,8 +21,8 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
#include "qExtbuffer.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "qextbuffer.h"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
STColumn col; // column info
|
STColumn col; // column info
|
|
@ -16,7 +16,7 @@
|
||||||
#ifndef TDENGINE_QPERCENTILE_H
|
#ifndef TDENGINE_QPERCENTILE_H
|
||||||
#define TDENGINE_QPERCENTILE_H
|
#define TDENGINE_QPERCENTILE_H
|
||||||
|
|
||||||
#include "qextbuffer.h"
|
#include "qExtbuffer.h"
|
||||||
|
|
||||||
typedef struct MinMaxEntry {
|
typedef struct MinMaxEntry {
|
||||||
union {
|
union {
|
|
@ -20,9 +20,9 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "os.h"
|
|
||||||
#include "qextbuffer.h"
|
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "os.h"
|
||||||
|
#include "qExtbuffer.h"
|
||||||
|
|
||||||
typedef struct SArray* SIDList;
|
typedef struct SArray* SIDList;
|
||||||
|
|
||||||
|
@ -33,14 +33,20 @@ typedef struct SDiskbasedResultBuf {
|
||||||
int32_t fd; // data file fd
|
int32_t fd; // data file fd
|
||||||
int32_t allocateId; // allocated page id
|
int32_t allocateId; // allocated page id
|
||||||
int32_t incStep; // minimum allocated pages
|
int32_t incStep; // minimum allocated pages
|
||||||
char* pBuf; // mmap buffer pointer
|
void* pBuf; // mmap buffer pointer
|
||||||
char* path; // file path
|
char* path; // file path
|
||||||
|
int32_t pageSize; // current used page size
|
||||||
|
int32_t inMemPages; // numOfPages that are allocated in memory
|
||||||
SHashObj* idsTable; // id hash table
|
SHashObj* idsTable; // id hash table
|
||||||
SIDList list; // for each id, there is a page id list
|
SIDList list; // for each id, there is a page id list
|
||||||
|
|
||||||
|
void* iBuf; // inmemory buf
|
||||||
|
void* handle; // for debug purpose
|
||||||
|
void* emptyDummyIdList; // dummy id list
|
||||||
} SDiskbasedResultBuf;
|
} SDiskbasedResultBuf;
|
||||||
|
|
||||||
#define DEFAULT_INTERN_BUF_PAGE_SIZE (8192L*5)
|
#define DEFAULT_INTERN_BUF_PAGE_SIZE (1024L)
|
||||||
|
#define DEFAULT_INMEM_BUF_PAGES 10
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create disk-based result buffer
|
* create disk-based result buffer
|
||||||
|
@ -49,7 +55,8 @@ typedef struct SDiskbasedResultBuf {
|
||||||
* @param rowSize
|
* @param rowSize
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t size, int32_t rowSize, void* handle);
|
int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t numOfPages, int32_t rowSize, int32_t pagesize,
|
||||||
|
int32_t inMemPages, void* handle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -81,8 +88,13 @@ SIDList getDataBufPagesIdList(SDiskbasedResultBuf* pResultBuf, int32_t groupId);
|
||||||
* @param id
|
* @param id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
#define GET_RES_BUF_PAGE_BY_ID(buf, id) ((tFilePage*)((buf)->pBuf + DEFAULT_INTERN_BUF_PAGE_SIZE*(id)))
|
static FORCE_INLINE tFilePage* getResBufPage(SDiskbasedResultBuf* pResultBuf, int32_t id) {
|
||||||
|
if (id < pResultBuf->inMemPages) {
|
||||||
|
return (tFilePage*) ((char*) pResultBuf->iBuf + id * pResultBuf->pageSize);
|
||||||
|
} else {
|
||||||
|
return (tFilePage*) ((char*) pResultBuf->pBuf + (id - pResultBuf->inMemPages) * pResultBuf->pageSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* get the total buffer size in the format of disk file
|
* get the total buffer size in the format of disk file
|
||||||
* @param pResultBuf
|
* @param pResultBuf
|
|
@ -49,7 +49,7 @@ static FORCE_INLINE char *getPosInResultPage(SQueryRuntimeEnv *pRuntimeEnv, int3
|
||||||
assert(pResult != NULL && pRuntimeEnv != NULL);
|
assert(pResult != NULL && pRuntimeEnv != NULL);
|
||||||
|
|
||||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||||
tFilePage *page = GET_RES_BUF_PAGE_BY_ID(pRuntimeEnv->pResultBuf, pResult->pos.pageId);
|
tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResult->pos.pageId);
|
||||||
int32_t realRowId = pResult->pos.rowId * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pRuntimeEnv->topBotQuery, pRuntimeEnv->stableQuery);
|
int32_t realRowId = pResult->pos.rowId * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pRuntimeEnv->topBotQuery, pRuntimeEnv->stableQuery);
|
||||||
|
|
||||||
return ((char *)page->data) + pRuntimeEnv->offset[columnIndex] * pRuntimeEnv->numOfRowsPerPage +
|
return ((char *)page->data) + pRuntimeEnv->offset[columnIndex] * pRuntimeEnv->numOfRowsPerPage +
|
||||||
|
@ -59,6 +59,4 @@ static FORCE_INLINE char *getPosInResultPage(SQueryRuntimeEnv *pRuntimeEnv, int3
|
||||||
__filter_func_t *getRangeFilterFuncArray(int32_t type);
|
__filter_func_t *getRangeFilterFuncArray(int32_t type);
|
||||||
__filter_func_t *getValueFilterFuncArray(int32_t type);
|
__filter_func_t *getValueFilterFuncArray(int32_t type);
|
||||||
|
|
||||||
bool supportPrefilter(int32_t type);
|
|
||||||
|
|
||||||
#endif // TDENGINE_QUERYUTIL_H
|
#endif // TDENGINE_QUERYUTIL_H
|
||||||
|
|
|
@ -255,7 +255,15 @@ extern int32_t functionCompatList[]; // compatible check array list
|
||||||
|
|
||||||
bool topbot_datablock_filter(SQLFunctionCtx *pCtx, int32_t functionId, const char *minval, const char *maxval);
|
bool topbot_datablock_filter(SQLFunctionCtx *pCtx, int32_t functionId, const char *minval, const char *maxval);
|
||||||
|
|
||||||
void resetResultInfo(SResultInfo *pResInfo);
|
/**
|
||||||
|
* the numOfRes should be kept, since it may be used later
|
||||||
|
* and allow the ResultInfo to be re initialized
|
||||||
|
*/
|
||||||
|
#define RESET_RESULT_INFO(_r) \
|
||||||
|
do { \
|
||||||
|
(_r)->initialized = false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
void setResultInfoBuf(SResultInfo *pResInfo, int32_t size, bool superTable, char* buf);
|
void setResultInfoBuf(SResultInfo *pResInfo, int32_t size, bool superTable, char* buf);
|
||||||
|
|
||||||
static FORCE_INLINE void initResultInfo(SResultInfo *pResInfo) {
|
static FORCE_INLINE void initResultInfo(SResultInfo *pResInfo) {
|
||||||
|
|
|
@ -16,17 +16,17 @@
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "tname.h"
|
|
||||||
#include "qast.h"
|
|
||||||
#include "tsdb.h"
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
#include "qAst.h"
|
||||||
|
#include "qSyntaxtreefunction.h"
|
||||||
#include "qsqlparser.h"
|
#include "qsqlparser.h"
|
||||||
#include "qsyntaxtreefunction.h"
|
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "tbuffer.h"
|
#include "tbuffer.h"
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
|
#include "tname.h"
|
||||||
|
#include "tsdb.h"
|
||||||
#include "tskiplist.h"
|
#include "tskiplist.h"
|
||||||
#include "tsqlfunction.h"
|
#include "tsqlfunction.h"
|
||||||
#include "tstoken.h"
|
#include "tstoken.h"
|
||||||
|
@ -678,7 +678,7 @@ static void tQueryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo,
|
||||||
|
|
||||||
tstr *name = (tstr*) tsdbGetTableName(*(void**) pData);
|
tstr *name = (tstr*) tsdbGetTableName(*(void**) pData);
|
||||||
// todo speed up by using hash
|
// todo speed up by using hash
|
||||||
if (pQueryInfo->colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
if (pQueryInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
if (pQueryInfo->optr == TSDB_RELATION_IN) {
|
if (pQueryInfo->optr == TSDB_RELATION_IN) {
|
||||||
addToResult = pQueryInfo->compare(name, pQueryInfo->q);
|
addToResult = pQueryInfo->compare(name, pQueryInfo->q);
|
||||||
} else if (pQueryInfo->optr == TSDB_RELATION_LIKE) {
|
} else if (pQueryInfo->optr == TSDB_RELATION_LIKE) {
|
||||||
|
@ -716,7 +716,7 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S
|
||||||
}
|
}
|
||||||
|
|
||||||
tQueryInfo *pQueryInfo = pExpr->_node.info;
|
tQueryInfo *pQueryInfo = pExpr->_node.info;
|
||||||
if (pQueryInfo->colIndex == 0 && pQueryInfo->optr != TSDB_RELATION_LIKE) {
|
if (pQueryInfo->sch.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX && pQueryInfo->optr != TSDB_RELATION_LIKE) {
|
||||||
tQueryIndexColumn(pSkipList, pQueryInfo, result);
|
tQueryIndexColumn(pSkipList, pQueryInfo, result);
|
||||||
} else {
|
} else {
|
||||||
tQueryIndexlessColumn(pSkipList, pQueryInfo, result, param->nodeFilterFn);
|
tQueryIndexlessColumn(pSkipList, pQueryInfo, result, param->nodeFilterFn);
|
|
@ -13,19 +13,19 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
#include "qFill.h"
|
||||||
|
#include "taosmsg.h"
|
||||||
#include "tcache.h"
|
#include "tcache.h"
|
||||||
#include "tglobal.h"
|
#include "tglobal.h"
|
||||||
#include "qfill.h"
|
|
||||||
#include "taosmsg.h"
|
|
||||||
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "qAst.h"
|
||||||
#include "qExecutor.h"
|
#include "qExecutor.h"
|
||||||
|
#include "qResultbuf.h"
|
||||||
#include "qUtil.h"
|
#include "qUtil.h"
|
||||||
#include "qresultBuf.h"
|
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
#include "queryLog.h"
|
#include "queryLog.h"
|
||||||
#include "qast.h"
|
|
||||||
#include "tlosertree.h"
|
#include "tlosertree.h"
|
||||||
#include "tscompression.h"
|
#include "tscompression.h"
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
|
@ -50,11 +50,6 @@
|
||||||
|
|
||||||
#define SDATA_BLOCK_INITIALIZER (SDataBlockInfo) {{0}, 0}
|
#define SDATA_BLOCK_INITIALIZER (SDataBlockInfo) {{0}, 0}
|
||||||
|
|
||||||
/* get the qinfo struct address from the query struct address */
|
|
||||||
#define GET_COLUMN_BYTES(query, colidx) \
|
|
||||||
((query)->colList[(query)->pSelectExpr[colidx].base.colInfo.colIndex].bytes)
|
|
||||||
#define GET_COLUMN_TYPE(query, colidx) ((query)->colList[(query)->pSelectExpr[colidx].base.colInfo.colIndex].type)
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
// when query starts to execute, this status will set
|
// when query starts to execute, this status will set
|
||||||
QUERY_NOT_COMPLETED = 0x1u,
|
QUERY_NOT_COMPLETED = 0x1u,
|
||||||
|
@ -238,9 +233,7 @@ bool isGroupbyNormalCol(SSqlGroupbyExpr *pGroupbyExpr) {
|
||||||
for (int32_t i = 0; i < pGroupbyExpr->numOfGroupCols; ++i) {
|
for (int32_t i = 0; i < pGroupbyExpr->numOfGroupCols; ++i) {
|
||||||
SColIndex *pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, i);
|
SColIndex *pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, i);
|
||||||
if (pColIndex->flag == TSDB_COL_NORMAL) {
|
if (pColIndex->flag == TSDB_COL_NORMAL) {
|
||||||
/*
|
//make sure the normal column locates at the second position if tbname exists in group by clause
|
||||||
* make sure the normal column locates at the second position if tbname exists in group by clause
|
|
||||||
*/
|
|
||||||
if (pGroupbyExpr->numOfGroupCols > 1) {
|
if (pGroupbyExpr->numOfGroupCols > 1) {
|
||||||
assert(pColIndex->colIndex > 0);
|
assert(pColIndex->colIndex > 0);
|
||||||
}
|
}
|
||||||
|
@ -299,6 +292,17 @@ bool isSelectivityWithTagsQuery(SQuery *pQuery) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isProjQuery(SQuery *pQuery) {
|
||||||
|
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||||
|
int32_t functId = pQuery->pSelectExpr[i].base.functionId;
|
||||||
|
if (functId != TSDB_FUNC_PRJ && functId != TSDB_FUNC_TAGPRJ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool isTSCompQuery(SQuery *pQuery) { return pQuery->pSelectExpr[0].base.functionId == TSDB_FUNC_TS_COMP; }
|
bool isTSCompQuery(SQuery *pQuery) { return pQuery->pSelectExpr[0].base.functionId == TSDB_FUNC_TS_COMP; }
|
||||||
|
|
||||||
static bool limitResults(SQueryRuntimeEnv* pRuntimeEnv) {
|
static bool limitResults(SQueryRuntimeEnv* pRuntimeEnv) {
|
||||||
|
@ -394,14 +398,14 @@ static SWindowResult *doSetTimeWindowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWin
|
||||||
if (pWindowResInfo->size >= pWindowResInfo->capacity) {
|
if (pWindowResInfo->size >= pWindowResInfo->capacity) {
|
||||||
int64_t newCap = pWindowResInfo->capacity * 1.5;
|
int64_t newCap = pWindowResInfo->capacity * 1.5;
|
||||||
char *t = realloc(pWindowResInfo->pResult, newCap * sizeof(SWindowResult));
|
char *t = realloc(pWindowResInfo->pResult, newCap * sizeof(SWindowResult));
|
||||||
if (t != NULL) {
|
if (t == NULL) {
|
||||||
|
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
pWindowResInfo->pResult = (SWindowResult *)t;
|
pWindowResInfo->pResult = (SWindowResult *)t;
|
||||||
|
|
||||||
int32_t inc = newCap - pWindowResInfo->capacity;
|
int32_t inc = newCap - pWindowResInfo->capacity;
|
||||||
memset(&pWindowResInfo->pResult[pWindowResInfo->capacity], 0, sizeof(SWindowResult) * inc);
|
memset(&pWindowResInfo->pResult[pWindowResInfo->capacity], 0, sizeof(SWindowResult) * inc);
|
||||||
} else {
|
|
||||||
// todo
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t i = pWindowResInfo->capacity; i < newCap; ++i) {
|
for (int32_t i = pWindowResInfo->capacity; i < newCap; ++i) {
|
||||||
createQueryResultInfo(pQuery, &pWindowResInfo->pResult[i], pRuntimeEnv->stableQuery, pRuntimeEnv->interBufSize);
|
createQueryResultInfo(pQuery, &pWindowResInfo->pResult[i], pRuntimeEnv->stableQuery, pRuntimeEnv->interBufSize);
|
||||||
|
@ -475,7 +479,7 @@ static int32_t addNewWindowResultBuf(SWindowResult *pWindowRes, SDiskbasedResult
|
||||||
pData = getNewDataBuf(pResultBuf, sid, &pageId);
|
pData = getNewDataBuf(pResultBuf, sid, &pageId);
|
||||||
} else {
|
} else {
|
||||||
pageId = getLastPageId(list);
|
pageId = getLastPageId(list);
|
||||||
pData = GET_RES_BUF_PAGE_BY_ID(pResultBuf, pageId);
|
pData = getResBufPage(pResultBuf, pageId);
|
||||||
|
|
||||||
if (pData->num >= numOfRowsPerPage) {
|
if (pData->num >= numOfRowsPerPage) {
|
||||||
pData = getNewDataBuf(pResultBuf, sid, &pageId);
|
pData = getNewDataBuf(pResultBuf, sid, &pageId);
|
||||||
|
@ -1008,7 +1012,6 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat
|
||||||
case TSDB_DATA_TYPE_BIGINT: v = GET_INT64_VAL(pData); break;
|
case TSDB_DATA_TYPE_BIGINT: v = GET_INT64_VAL(pData); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert(pRuntimeEnv->windowResInfo.hashList->size <= 2);
|
|
||||||
SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, &pRuntimeEnv->windowResInfo, pData, bytes, true);
|
SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, &pRuntimeEnv->windowResInfo, pData, bytes, true);
|
||||||
if (pWindowRes == NULL) {
|
if (pWindowRes == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1053,9 +1056,9 @@ static char *getGroupbyColumnData(SQuery *pQuery, int16_t *type, int16_t *bytes,
|
||||||
*type = pQuery->colList[colIndex].type;
|
*type = pQuery->colList[colIndex].type;
|
||||||
*bytes = pQuery->colList[colIndex].bytes;
|
*bytes = pQuery->colList[colIndex].bytes;
|
||||||
/*
|
/*
|
||||||
* the colIndex is acquired from the first meter of all qualified meters in this vnode during query prepare
|
* the colIndex is acquired from the first tables of all qualified tables in this vnode during query prepare
|
||||||
* stage, the remain meter may not have the required column in cache actually. So, the validation of required
|
* stage, the remain tables may not have the required column in cache actually. So, the validation of required
|
||||||
* column in cache with the corresponding meter schema is reinforced.
|
* column in cache with the corresponding schema is reinforced.
|
||||||
*/
|
*/
|
||||||
int32_t numOfCols = taosArrayGetSize(pDataBlock);
|
int32_t numOfCols = taosArrayGetSize(pDataBlock);
|
||||||
|
|
||||||
|
@ -1206,9 +1209,8 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// interval window query
|
// interval window query, decide the time window according to the primary timestamp
|
||||||
if (QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
if (QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
||||||
// decide the time window according to the primary timestamp
|
|
||||||
int64_t ts = tsCols[offset];
|
int64_t ts = tsCols[offset];
|
||||||
STimeWindow win = getActiveTimeWindow(pWindowResInfo, ts, pQuery);
|
STimeWindow win = getActiveTimeWindow(pWindowResInfo, ts, pQuery);
|
||||||
|
|
||||||
|
@ -1230,8 +1232,7 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
GET_NEXT_TIMEWINDOW(pQuery, &nextWin);
|
GET_NEXT_TIMEWINDOW(pQuery, &nextWin);
|
||||||
if (/*pWindowResInfo->startTime > nextWin.skey ||*/
|
if ((nextWin.skey > pQuery->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||||
(nextWin.skey > pQuery->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
|
||||||
(nextWin.skey < pQuery->window.ekey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
(nextWin.skey < pQuery->window.ekey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1489,6 +1490,8 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
|
||||||
goto _clean;
|
goto _clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug("QInfo:%p setup runtime env1", GET_QINFO_ADDR(pRuntimeEnv));
|
||||||
|
|
||||||
pRuntimeEnv->offset[0] = 0;
|
pRuntimeEnv->offset[0] = 0;
|
||||||
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||||
SSqlFuncMsg *pSqlFuncMsg = &pQuery->pSelectExpr[i].base;
|
SSqlFuncMsg *pSqlFuncMsg = &pQuery->pSelectExpr[i].base;
|
||||||
|
@ -1533,6 +1536,8 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug("QInfo:%p setup runtime env2", GET_QINFO_ADDR(pRuntimeEnv));
|
||||||
|
|
||||||
// set the order information for top/bottom query
|
// set the order information for top/bottom query
|
||||||
int32_t functionId = pCtx->functionId;
|
int32_t functionId = pCtx->functionId;
|
||||||
|
|
||||||
|
@ -1553,17 +1558,25 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug("QInfo:%p setup runtime env3", GET_QINFO_ADDR(pRuntimeEnv));
|
||||||
|
|
||||||
char* buf = (char*) pRuntimeEnv->resultInfo + sizeof(SResultInfo) * pQuery->numOfOutput;
|
char* buf = (char*) pRuntimeEnv->resultInfo + sizeof(SResultInfo) * pQuery->numOfOutput;
|
||||||
|
|
||||||
// set the intermediate result output buffer
|
// set the intermediate result output buffer
|
||||||
setWindowResultInfo(pRuntimeEnv->resultInfo, pQuery, pRuntimeEnv->stableQuery, buf);
|
setWindowResultInfo(pRuntimeEnv->resultInfo, pQuery, pRuntimeEnv->stableQuery, buf);
|
||||||
|
|
||||||
|
qDebug("QInfo:%p setup runtime env4", GET_QINFO_ADDR(pRuntimeEnv));
|
||||||
|
|
||||||
// if it is group by normal column, do not set output buffer, the output buffer is pResult
|
// if it is group by normal column, do not set output buffer, the output buffer is pResult
|
||||||
if (!isGroupbyNormalCol(pQuery->pGroupbyExpr) && !pRuntimeEnv->stableQuery) {
|
if (!pRuntimeEnv->groupbyNormalCol && !pRuntimeEnv->stableQuery) {
|
||||||
resetCtxOutputBuf(pRuntimeEnv);
|
resetCtxOutputBuf(pRuntimeEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug("QInfo:%p setup runtime env5", GET_QINFO_ADDR(pRuntimeEnv));
|
||||||
|
|
||||||
setCtxTagColumnInfo(pRuntimeEnv, pRuntimeEnv->pCtx);
|
setCtxTagColumnInfo(pRuntimeEnv, pRuntimeEnv->pCtx);
|
||||||
|
|
||||||
|
qDebug("QInfo:%p init completed", GET_QINFO_ADDR(pRuntimeEnv));
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
_clean:
|
_clean:
|
||||||
|
@ -1915,9 +1928,20 @@ static int32_t getInitialPageNum(SQInfo *pQInfo) {
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE int32_t getNumOfRowsInResultPage(SQuery *pQuery, bool topBotQuery, bool isSTableQuery) {
|
static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) {
|
||||||
int32_t rowSize = pQuery->rowSize * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, topBotQuery, isSTableQuery);
|
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||||
return (DEFAULT_INTERN_BUF_PAGE_SIZE - sizeof(tFilePage)) / rowSize;
|
|
||||||
|
*rowsize = pQuery->rowSize * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pRuntimeEnv->topBotQuery, pRuntimeEnv->stableQuery);
|
||||||
|
int32_t overhead = sizeof(tFilePage);
|
||||||
|
|
||||||
|
// one page contains at least two rows
|
||||||
|
*ps = DEFAULT_INTERN_BUF_PAGE_SIZE;
|
||||||
|
while(((*rowsize) * 2) > (*ps) - overhead) {
|
||||||
|
*ps = (*ps << 1u);
|
||||||
|
}
|
||||||
|
|
||||||
|
pRuntimeEnv->numOfRowsPerPage = ((*ps) - sizeof(tFilePage)) / (*rowsize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IS_PREFILTER_TYPE(_t) ((_t) != TSDB_DATA_TYPE_BINARY && (_t) != TSDB_DATA_TYPE_NCHAR)
|
#define IS_PREFILTER_TYPE(_t) ((_t) != TSDB_DATA_TYPE_BINARY && (_t) != TSDB_DATA_TYPE_NCHAR)
|
||||||
|
@ -2043,8 +2067,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv *pRuntimeEnv, void* pQueryHandle,
|
||||||
} else { // check if this data block is required to load
|
} else { // check if this data block is required to load
|
||||||
|
|
||||||
// Calculate all time windows that are overlapping or contain current data block.
|
// Calculate all time windows that are overlapping or contain current data block.
|
||||||
// If current data block is contained by all possible time window, loading current
|
// If current data block is contained by all possible time window, do not load current data block.
|
||||||
// data block is not needed.
|
|
||||||
if (QUERY_IS_INTERVAL_QUERY(pQuery) && overlapWithTimeWindow(pQuery, pBlockInfo)) {
|
if (QUERY_IS_INTERVAL_QUERY(pQuery) && overlapWithTimeWindow(pQuery, pBlockInfo)) {
|
||||||
status = BLK_DATA_ALL_NEEDED;
|
status = BLK_DATA_ALL_NEEDED;
|
||||||
}
|
}
|
||||||
|
@ -2364,6 +2387,18 @@ static void doSetTagValueInParam(void *tsdb, void* pTable, int32_t tagColId, tVa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SColumnInfo* doGetTagColumnInfoById(SColumnInfo* pTagColList, int32_t numOfTags, int16_t colId) {
|
||||||
|
assert(pTagColList != NULL && numOfTags > 0);
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < numOfTags; ++i) {
|
||||||
|
if (pTagColList[i].colId == colId) {
|
||||||
|
return &pTagColList[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
|
void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
|
||||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||||
SQInfo* pQInfo = GET_QINFO_ADDR(pRuntimeEnv);
|
SQInfo* pQInfo = GET_QINFO_ADDR(pRuntimeEnv);
|
||||||
|
@ -2372,16 +2407,10 @@ void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
|
||||||
if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP) {
|
if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP) {
|
||||||
assert(pExprInfo->base.numOfParams == 1);
|
assert(pExprInfo->base.numOfParams == 1);
|
||||||
|
|
||||||
// todo refactor extract function.
|
int16_t tagColId = pExprInfo->base.arg->argValue.i64;
|
||||||
int16_t type = -1, bytes = -1;
|
SColumnInfo* pColInfo = doGetTagColumnInfoById(pQuery->tagColList, pQuery->numOfTags, tagColId);
|
||||||
for(int32_t i = 0; i < pQuery->numOfTags; ++i) {
|
|
||||||
if (pQuery->tagColList[i].colId == pExprInfo->base.arg->argValue.i64) {
|
|
||||||
type = pQuery->tagColList[i].type;
|
|
||||||
bytes = pQuery->tagColList[i].bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
doSetTagValueInParam(tsdb, pTable, pExprInfo->base.arg->argValue.i64, &pRuntimeEnv->pCtx[0].tag, type, bytes);
|
doSetTagValueInParam(tsdb, pTable, tagColId, &pRuntimeEnv->pCtx[0].tag, pColInfo->type, pColInfo->bytes);
|
||||||
} else {
|
} else {
|
||||||
// set tag value, by which the results are aggregated.
|
// set tag value, by which the results are aggregated.
|
||||||
for (int32_t idx = 0; idx < pQuery->numOfOutput; ++idx) {
|
for (int32_t idx = 0; idx < pQuery->numOfOutput; ++idx) {
|
||||||
|
@ -2399,20 +2428,14 @@ void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
|
||||||
|
|
||||||
// set the join tag for first column
|
// set the join tag for first column
|
||||||
SSqlFuncMsg *pFuncMsg = &pExprInfo->base;
|
SSqlFuncMsg *pFuncMsg = &pExprInfo->base;
|
||||||
if ((pFuncMsg->functionId == TSDB_FUNC_TS || pFuncMsg->functionId == TSDB_FUNC_PRJ) && pFuncMsg->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX &&
|
if ((pFuncMsg->functionId == TSDB_FUNC_TS || pFuncMsg->functionId == TSDB_FUNC_PRJ) && pRuntimeEnv->pTSBuf != NULL &&
|
||||||
pRuntimeEnv->pTSBuf != NULL) {
|
pFuncMsg->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||||
assert(pFuncMsg->numOfParams == 1);
|
assert(pFuncMsg->numOfParams == 1);
|
||||||
|
|
||||||
// todo refactor
|
int16_t tagColId = pExprInfo->base.arg->argValue.i64;
|
||||||
int16_t type = -1, bytes = -1;
|
SColumnInfo* pColInfo = doGetTagColumnInfoById(pQuery->tagColList, pQuery->numOfTags, tagColId);
|
||||||
for(int32_t i = 0; i < pQuery->numOfTags; ++i) {
|
|
||||||
if (pQuery->tagColList[i].colId == pExprInfo->base.arg->argValue.i64) {
|
|
||||||
type = pQuery->tagColList[i].type;
|
|
||||||
bytes = pQuery->tagColList[i].bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
doSetTagValueInParam(tsdb, pTable, pExprInfo->base.arg->argValue.i64, &pRuntimeEnv->pCtx[0].tag, type, bytes);
|
doSetTagValueInParam(tsdb, pTable, tagColId, &pRuntimeEnv->pCtx[0].tag, pColInfo->type, pColInfo->bytes);
|
||||||
qDebug("QInfo:%p set tag value for join comparison, colId:%" PRId64 ", val:%"PRId64, pQInfo, pExprInfo->base.arg->argValue.i64,
|
qDebug("QInfo:%p set tag value for join comparison, colId:%" PRId64 ", val:%"PRId64, pQInfo, pExprInfo->base.arg->argValue.i64,
|
||||||
pRuntimeEnv->pCtx[0].tag.i64Key)
|
pRuntimeEnv->pCtx[0].tag.i64Key)
|
||||||
}
|
}
|
||||||
|
@ -2429,7 +2452,7 @@ static void doMerge(SQueryRuntimeEnv *pRuntimeEnv, int64_t timestamp, SWindowRes
|
||||||
pCtx[i].aOutputBuf = pCtx[i].aOutputBuf + pCtx[i].outputBytes;
|
pCtx[i].aOutputBuf = pCtx[i].aOutputBuf + pCtx[i].outputBytes;
|
||||||
pCtx[i].currentStage = FIRST_STAGE_MERGE;
|
pCtx[i].currentStage = FIRST_STAGE_MERGE;
|
||||||
|
|
||||||
resetResultInfo(pCtx[i].resultInfo);
|
RESET_RESULT_INFO(pCtx[i].resultInfo);
|
||||||
aAggs[functionId].init(&pCtx[i]);
|
aAggs[functionId].init(&pCtx[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2666,7 +2689,7 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
|
||||||
int32_t size = taosArrayGetSize(list);
|
int32_t size = taosArrayGetSize(list);
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
int32_t* pgId = taosArrayGet(list, i);
|
int32_t* pgId = taosArrayGet(list, i);
|
||||||
tFilePage *pData = GET_RES_BUF_PAGE_BY_ID(pResultBuf, *pgId);
|
tFilePage *pData = getResBufPage(pResultBuf, *pgId);
|
||||||
total += pData->num;
|
total += pData->num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2675,7 +2698,7 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
|
||||||
int32_t offset = 0;
|
int32_t offset = 0;
|
||||||
for (int32_t j = 0; j < size; ++j) {
|
for (int32_t j = 0; j < size; ++j) {
|
||||||
int32_t* pgId = taosArrayGet(list, j);
|
int32_t* pgId = taosArrayGet(list, j);
|
||||||
tFilePage *pData = GET_RES_BUF_PAGE_BY_ID(pResultBuf, *pgId);
|
tFilePage *pData = getResBufPage(pResultBuf, *pgId);
|
||||||
|
|
||||||
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||||
int32_t bytes = pRuntimeEnv->pCtx[i].outputBytes;
|
int32_t bytes = pRuntimeEnv->pCtx[i].outputBytes;
|
||||||
|
@ -2865,10 +2888,10 @@ int32_t flushFromResultBuf(SQInfo *pQInfo) {
|
||||||
SQuery * pQuery = pRuntimeEnv->pQuery;
|
SQuery * pQuery = pRuntimeEnv->pQuery;
|
||||||
|
|
||||||
SDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf;
|
SDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf;
|
||||||
int32_t capacity = (DEFAULT_INTERN_BUF_PAGE_SIZE - sizeof(tFilePage)) / pQuery->rowSize;
|
|
||||||
|
|
||||||
// the base value for group result, since the maximum number of table for each vnode will not exceed 100,000.
|
// the base value for group result, since the maximum number of table for each vnode will not exceed 100,000.
|
||||||
int32_t pageId = -1;
|
int32_t pageId = -1;
|
||||||
|
int32_t capacity = pResultBuf->numOfRowsPerPage;
|
||||||
|
|
||||||
int32_t remain = pQuery->sdata[0]->num;
|
int32_t remain = pQuery->sdata[0]->num;
|
||||||
int32_t offset = 0;
|
int32_t offset = 0;
|
||||||
|
@ -3038,7 +3061,7 @@ void resetCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||||
* set the output buffer information and intermediate buffer
|
* set the output buffer information and intermediate buffer
|
||||||
* not all queries require the interResultBuf, such as COUNT/TAGPRJ/PRJ/TAG etc.
|
* not all queries require the interResultBuf, such as COUNT/TAGPRJ/PRJ/TAG etc.
|
||||||
*/
|
*/
|
||||||
resetResultInfo(&pRuntimeEnv->resultInfo[i]);
|
RESET_RESULT_INFO(&pRuntimeEnv->resultInfo[i]);
|
||||||
pCtx->resultInfo = &pRuntimeEnv->resultInfo[i];
|
pCtx->resultInfo = &pRuntimeEnv->resultInfo[i];
|
||||||
|
|
||||||
// set the timestamp output buffer for top/bottom/diff query
|
// set the timestamp output buffer for top/bottom/diff query
|
||||||
|
@ -3077,7 +3100,7 @@ void forwardCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, int64_t output) {
|
||||||
pRuntimeEnv->pCtx[j].ptsOutputBuf += TSDB_KEYSIZE * output;
|
pRuntimeEnv->pCtx[j].ptsOutputBuf += TSDB_KEYSIZE * output;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetResultInfo(pRuntimeEnv->pCtx[j].resultInfo);
|
RESET_RESULT_INFO(pRuntimeEnv->pCtx[j].resultInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3331,8 +3354,8 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
|
||||||
if (pRuntimeEnv->pSecQueryHandle == NULL) {
|
if (pRuntimeEnv->pSecQueryHandle == NULL) {
|
||||||
longjmp(pRuntimeEnv->env, terrno);
|
longjmp(pRuntimeEnv->env, terrno);
|
||||||
}
|
}
|
||||||
pRuntimeEnv->windowResInfo.curIndex = qstatus.windowIndex;
|
|
||||||
|
|
||||||
|
pRuntimeEnv->windowResInfo.curIndex = qstatus.windowIndex;
|
||||||
setQueryStatus(pQuery, QUERY_NOT_COMPLETED);
|
setQueryStatus(pQuery, QUERY_NOT_COMPLETED);
|
||||||
pRuntimeEnv->scanFlag = REPEAT_SCAN;
|
pRuntimeEnv->scanFlag = REPEAT_SCAN;
|
||||||
|
|
||||||
|
@ -3467,7 +3490,6 @@ void setExecutionContext(SQInfo *pQInfo, int32_t groupIndex, TSKEY nextKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t GROUPRESULTID = 1;
|
|
||||||
SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&groupIndex,
|
SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&groupIndex,
|
||||||
sizeof(groupIndex), true);
|
sizeof(groupIndex), true);
|
||||||
if (pWindowRes == NULL) {
|
if (pWindowRes == NULL) {
|
||||||
|
@ -3479,7 +3501,7 @@ void setExecutionContext(SQInfo *pQInfo, int32_t groupIndex, TSKEY nextKey) {
|
||||||
* all group belong to one result set, and each group result has different group id so set the id to be one
|
* all group belong to one result set, and each group result has different group id so set the id to be one
|
||||||
*/
|
*/
|
||||||
if (pWindowRes->pos.pageId == -1) {
|
if (pWindowRes->pos.pageId == -1) {
|
||||||
if (addNewWindowResultBuf(pWindowRes, pRuntimeEnv->pResultBuf, GROUPRESULTID, pRuntimeEnv->numOfRowsPerPage) !=
|
if (addNewWindowResultBuf(pWindowRes, pRuntimeEnv->pResultBuf, groupIndex, pRuntimeEnv->numOfRowsPerPage) !=
|
||||||
TSDB_CODE_SUCCESS) {
|
TSDB_CODE_SUCCESS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4149,6 +4171,7 @@ static int32_t setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery)
|
||||||
} else {
|
} else {
|
||||||
pRuntimeEnv->pQueryHandle = tsdbQueryTables(tsdb, &cond, &pQInfo->tableGroupInfo, pQInfo);
|
pRuntimeEnv->pQueryHandle = tsdbQueryTables(tsdb, &cond, &pQInfo->tableGroupInfo, pQInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4174,10 +4197,9 @@ static SFillColInfo* taosCreateFillColInfo(SQuery* pQuery) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bool isSTableQuery) {
|
int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bool isSTableQuery) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
|
||||||
|
|
||||||
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
|
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
|
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
|
||||||
|
|
||||||
pQuery->precision = tsdbGetCfg(tsdb)->precision;
|
pQuery->precision = tsdbGetCfg(tsdb)->precision;
|
||||||
|
@ -4186,6 +4208,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
|
||||||
|
|
||||||
setScanLimitationByResultBuffer(pQuery);
|
setScanLimitationByResultBuffer(pQuery);
|
||||||
changeExecuteScanOrder(pQInfo, false);
|
changeExecuteScanOrder(pQInfo, false);
|
||||||
|
|
||||||
code = setupQueryHandle(tsdb, pQInfo, isSTableQuery);
|
code = setupQueryHandle(tsdb, pQInfo, isSTableQuery);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
|
@ -4212,33 +4235,42 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
pRuntimeEnv->numOfRowsPerPage = getNumOfRowsInResultPage(pQuery, pRuntimeEnv->topBotQuery, isSTableQuery);
|
int32_t ps = DEFAULT_PAGE_SIZE;
|
||||||
|
int32_t rowsize = 0;
|
||||||
|
getIntermediateBufInfo(pRuntimeEnv, &ps, &rowsize);
|
||||||
|
|
||||||
if (isSTableQuery && !onlyQueryTags(pRuntimeEnv->pQuery)) {
|
if (isSTableQuery && !onlyQueryTags(pRuntimeEnv->pQuery)) {
|
||||||
int32_t rows = getInitialPageNum(pQInfo);
|
int32_t numOfPages = getInitialPageNum(pQInfo);
|
||||||
code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, rows, pQuery->rowSize, pQInfo);
|
code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, numOfPages, rowsize, ps, numOfPages, pQInfo);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
if (!QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
||||||
int16_t type = TSDB_DATA_TYPE_NULL;
|
int16_t type = TSDB_DATA_TYPE_NULL;
|
||||||
|
int32_t threshold = 0;
|
||||||
|
|
||||||
if (pRuntimeEnv->groupbyNormalCol) { // group by columns not tags;
|
if (pRuntimeEnv->groupbyNormalCol) { // group by columns not tags;
|
||||||
type = getGroupbyColumnType(pQuery, pQuery->pGroupbyExpr);
|
type = getGroupbyColumnType(pQuery, pQuery->pGroupbyExpr);
|
||||||
|
threshold = 4000;
|
||||||
} else {
|
} else {
|
||||||
type = TSDB_DATA_TYPE_INT; // group id
|
type = TSDB_DATA_TYPE_INT; // group id
|
||||||
|
threshold = GET_NUM_OF_TABLEGROUP(pQInfo);
|
||||||
|
if (threshold < 8) {
|
||||||
|
threshold = 8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code = initWindowResInfo(&pRuntimeEnv->windowResInfo, pRuntimeEnv, 32, 4096, type);
|
code = initWindowResInfo(&pRuntimeEnv->windowResInfo, pRuntimeEnv, 8, threshold, type);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (pRuntimeEnv->groupbyNormalCol || QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
} else if (pRuntimeEnv->groupbyNormalCol || QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
||||||
int32_t rows = getInitialPageNum(pQInfo);
|
int32_t numOfResultRows = getInitialPageNum(pQInfo);
|
||||||
code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, rows, pQuery->rowSize, pQInfo);
|
getIntermediateBufInfo(pRuntimeEnv, &ps, &rowsize);
|
||||||
|
|
||||||
|
code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, numOfResultRows, rowsize, ps, numOfResultRows, pQInfo);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -4250,7 +4282,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
|
||||||
type = TSDB_DATA_TYPE_TIMESTAMP;
|
type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = initWindowResInfo(&pRuntimeEnv->windowResInfo, pRuntimeEnv, rows, 4096, type);
|
code = initWindowResInfo(&pRuntimeEnv->windowResInfo, pRuntimeEnv, numOfResultRows, 4096, type);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -4932,7 +4964,7 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
|
||||||
pQuery->current->lastKey, pQuery->window.ekey);
|
pQuery->current->lastKey, pQuery->window.ekey);
|
||||||
} else if (Q_STATUS_EQUAL(pQuery->status, QUERY_COMPLETED)) {
|
} else if (Q_STATUS_EQUAL(pQuery->status, QUERY_COMPLETED)) {
|
||||||
STableIdInfo tidInfo;
|
STableIdInfo tidInfo;
|
||||||
STableId* id = TSDB_TABLEID(pQuery->current);
|
STableId* id = TSDB_TABLEID(pQuery->current->pTable);
|
||||||
|
|
||||||
tidInfo.uid = id->uid;
|
tidInfo.uid = id->uid;
|
||||||
tidInfo.tid = id->tid;
|
tidInfo.tid = id->tid;
|
||||||
|
@ -5693,7 +5725,6 @@ static void doUpdateExprColumnIndex(SQuery *pQuery) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int compareTableIdInfo(const void* a, const void* b) {
|
static int compareTableIdInfo(const void* a, const void* b) {
|
||||||
const STableIdInfo* x = (const STableIdInfo*)a;
|
const STableIdInfo* x = (const STableIdInfo*)a;
|
||||||
const STableIdInfo* y = (const STableIdInfo*)b;
|
const STableIdInfo* y = (const STableIdInfo*)b;
|
||||||
|
@ -5709,6 +5740,7 @@ static void calResultBufSize(SQuery* pQuery) {
|
||||||
const int32_t RESULT_MSG_MIN_ROWS = 8192;
|
const int32_t RESULT_MSG_MIN_ROWS = 8192;
|
||||||
const float RESULT_THRESHOLD_RATIO = 0.85;
|
const float RESULT_THRESHOLD_RATIO = 0.85;
|
||||||
|
|
||||||
|
if (isProjQuery(pQuery)) {
|
||||||
int32_t numOfRes = RESULT_MSG_MIN_SIZE / pQuery->rowSize;
|
int32_t numOfRes = RESULT_MSG_MIN_SIZE / pQuery->rowSize;
|
||||||
if (numOfRes < RESULT_MSG_MIN_ROWS) {
|
if (numOfRes < RESULT_MSG_MIN_ROWS) {
|
||||||
numOfRes = RESULT_MSG_MIN_ROWS;
|
numOfRes = RESULT_MSG_MIN_ROWS;
|
||||||
|
@ -5716,6 +5748,10 @@ static void calResultBufSize(SQuery* pQuery) {
|
||||||
|
|
||||||
pQuery->rec.capacity = numOfRes;
|
pQuery->rec.capacity = numOfRes;
|
||||||
pQuery->rec.threshold = numOfRes * RESULT_THRESHOLD_RATIO;
|
pQuery->rec.threshold = numOfRes * RESULT_THRESHOLD_RATIO;
|
||||||
|
} else { // in case of non-prj query, a smaller output buffer will be used.
|
||||||
|
pQuery->rec.capacity = 4096;
|
||||||
|
pQuery->rec.threshold = pQuery->rec.capacity * RESULT_THRESHOLD_RATIO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList, SSqlGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList, SSqlGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
||||||
|
@ -5727,6 +5763,7 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
|
||||||
if (pQInfo == NULL) {
|
if (pQInfo == NULL) {
|
||||||
goto _cleanup_qinfo;
|
goto _cleanup_qinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// to make sure third party won't overwrite this structure
|
// to make sure third party won't overwrite this structure
|
||||||
pQInfo->signature = pQInfo;
|
pQInfo->signature = pQInfo;
|
||||||
pQInfo->tableGroupInfo = *pTableGroupInfo;
|
pQInfo->tableGroupInfo = *pTableGroupInfo;
|
||||||
|
@ -5926,6 +5963,7 @@ static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQ
|
||||||
pQuery->window.ekey, pQuery->order.order);
|
pQuery->window.ekey, pQuery->order.order);
|
||||||
setQueryStatus(pQuery, QUERY_COMPLETED);
|
setQueryStatus(pQuery, QUERY_COMPLETED);
|
||||||
pQInfo->tableqinfoGroupInfo.numOfTables = 0;
|
pQInfo->tableqinfoGroupInfo.numOfTables = 0;
|
||||||
|
|
||||||
sem_post(&pQInfo->dataReady);
|
sem_post(&pQInfo->dataReady);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -6044,11 +6082,10 @@ static void freeQInfo(SQInfo *pQInfo) {
|
||||||
|
|
||||||
tfree(pQuery->sdata);
|
tfree(pQuery->sdata);
|
||||||
tfree(pQuery);
|
tfree(pQuery);
|
||||||
|
pQInfo->signature = 0;
|
||||||
|
|
||||||
qDebug("QInfo:%p QInfo is freed", pQInfo);
|
qDebug("QInfo:%p QInfo is freed", pQInfo);
|
||||||
|
|
||||||
// destroy signature, in order to avoid the query process pass the object safety check
|
|
||||||
memset(pQInfo, 0, sizeof(SQInfo));
|
|
||||||
tfree(pQInfo);
|
tfree(pQInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6136,16 +6173,17 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, vo
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
char * tagCond = NULL, *tbnameCond = NULL;
|
char *tagCond = NULL;
|
||||||
|
char *tbnameCond = NULL;
|
||||||
SArray *pTableIdList = NULL;
|
SArray *pTableIdList = NULL;
|
||||||
SSqlFuncMsg **pExprMsg = NULL;
|
SSqlFuncMsg **pExprMsg = NULL;
|
||||||
|
SExprInfo *pExprs = NULL;
|
||||||
SColIndex *pGroupColIndex = NULL;
|
SColIndex *pGroupColIndex = NULL;
|
||||||
SColumnInfo *pTagColumnInfo = NULL;
|
SColumnInfo *pTagColumnInfo = NULL;
|
||||||
SExprInfo *pExprs = NULL;
|
|
||||||
SSqlGroupbyExpr *pGroupbyExpr = NULL;
|
SSqlGroupbyExpr *pGroupbyExpr = NULL;
|
||||||
|
|
||||||
if ((code = convertQueryMsg(pQueryMsg, &pTableIdList, &pExprMsg, &tagCond, &tbnameCond, &pGroupColIndex, &pTagColumnInfo)) !=
|
code = convertQueryMsg(pQueryMsg, &pTableIdList, &pExprMsg, &tagCond, &tbnameCond, &pGroupColIndex, &pTagColumnInfo);
|
||||||
TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
goto _over;
|
goto _over;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6172,6 +6210,7 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, vo
|
||||||
|
|
||||||
bool isSTableQuery = false;
|
bool isSTableQuery = false;
|
||||||
STableGroupInfo tableGroupInfo = {0};
|
STableGroupInfo tableGroupInfo = {0};
|
||||||
|
int64_t st = taosGetTimestampUs();
|
||||||
|
|
||||||
if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_TABLE_QUERY)) {
|
if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_TABLE_QUERY)) {
|
||||||
STableIdInfo *id = taosArrayGet(pTableIdList, 0);
|
STableIdInfo *id = taosArrayGet(pTableIdList, 0);
|
||||||
|
@ -6182,7 +6221,6 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, vo
|
||||||
}
|
}
|
||||||
} else if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY|TSDB_QUERY_TYPE_STABLE_QUERY)) {
|
} else if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY|TSDB_QUERY_TYPE_STABLE_QUERY)) {
|
||||||
isSTableQuery = true;
|
isSTableQuery = true;
|
||||||
// TODO: need a macro from TSDB to check if table is super table
|
|
||||||
|
|
||||||
// also note there's possibility that only one table in the super table
|
// also note there's possibility that only one table in the super table
|
||||||
if (!TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY)) {
|
if (!TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY)) {
|
||||||
|
@ -6194,10 +6232,11 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, vo
|
||||||
numOfGroupByCols = 0;
|
numOfGroupByCols = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug("qmsg:%p query stable, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid);
|
||||||
code = tsdbQuerySTableByTagCond(tsdb, id->uid, tagCond, pQueryMsg->tagCondLen, pQueryMsg->tagNameRelType, tbnameCond, &tableGroupInfo, pGroupColIndex,
|
code = tsdbQuerySTableByTagCond(tsdb, id->uid, tagCond, pQueryMsg->tagCondLen, pQueryMsg->tagNameRelType, tbnameCond, &tableGroupInfo, pGroupColIndex,
|
||||||
numOfGroupByCols);
|
numOfGroupByCols);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
qError("qmsg:%p failed to QueryStable, reason: %s", pQueryMsg, tstrerror(code));
|
qError("qmsg:%p failed to query stable, reason: %s", pQueryMsg, tstrerror(code));
|
||||||
goto _over;
|
goto _over;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -6208,6 +6247,9 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, vo
|
||||||
|
|
||||||
qDebug("qmsg:%p query on %zu tables in one group from client", pQueryMsg, tableGroupInfo.numOfTables);
|
qDebug("qmsg:%p query on %zu tables in one group from client", pQueryMsg, tableGroupInfo.numOfTables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t el = taosGetTimestampUs() - st;
|
||||||
|
qDebug("qmsg:%p tag filter completed, numOfTables:%zu, elapsed time:%"PRId64"us", pQueryMsg, tableGroupInfo.numOfTables, el);
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
@ -6247,7 +6289,7 @@ _over:
|
||||||
*pQInfo = NULL;
|
*pQInfo = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if failed to add ref for all meters in this query, abort current query
|
// if failed to add ref for all tables in this query, abort current query
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,16 +12,15 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include "qExtbuffer.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tulog.h"
|
#include "queryLog.h"
|
||||||
#include "qextbuffer.h"
|
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tsqlfunction.h"
|
#include "tsqlfunction.h"
|
||||||
#include "ttime.h"
|
#include "tulog.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
#include "queryLog.h"
|
|
||||||
|
|
||||||
#define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \
|
#define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \
|
||||||
(data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes)
|
(data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes)
|
|
@ -13,9 +13,9 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "qFill.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "qfill.h"
|
#include "qExtbuffer.h"
|
||||||
#include "qextbuffer.h"
|
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tsqlfunction.h"
|
#include "tsqlfunction.h"
|
|
@ -554,5 +554,3 @@ __filter_func_t* getValueFilterFuncArray(int32_t type) {
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportPrefilter(int32_t type) { return type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR; }
|
|
|
@ -14,7 +14,7 @@
|
||||||
*/
|
*/
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "qhistogram.h"
|
#include "qHistogram.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tlosertree.h"
|
#include "tlosertree.h"
|
|
@ -13,12 +13,12 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "qPercentile.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tulog.h"
|
#include "queryLog.h"
|
||||||
#include "qpercentile.h"
|
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "queryLog.h"
|
#include "tulog.h"
|
||||||
|
|
||||||
tExtMemBuffer *releaseBucketsExceptFor(tMemBucket *pMemBucket, int16_t segIdx, int16_t slotIdx) {
|
tExtMemBuffer *releaseBucketsExceptFor(tMemBucket *pMemBucket, int16_t segIdx, int16_t slotIdx) {
|
||||||
tExtMemBuffer *pBuffer = NULL;
|
tExtMemBuffer *pBuffer = NULL;
|
|
@ -0,0 +1,221 @@
|
||||||
|
#include "qResultbuf.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "qExtbuffer.h"
|
||||||
|
#include "queryLog.h"
|
||||||
|
#include "taoserror.h"
|
||||||
|
|
||||||
|
int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t numOfPages, int32_t rowSize,
|
||||||
|
int32_t pagesize, int32_t inMemPages, void* handle) {
|
||||||
|
|
||||||
|
*pResultBuf = calloc(1, sizeof(SDiskbasedResultBuf));
|
||||||
|
SDiskbasedResultBuf* pResBuf = *pResultBuf;
|
||||||
|
if (pResBuf == NULL) {
|
||||||
|
return TSDB_CODE_COM_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
pResBuf->pageSize = pagesize;
|
||||||
|
pResBuf->numOfPages = inMemPages; // all pages are in buffer in the first place
|
||||||
|
pResBuf->inMemPages = inMemPages;
|
||||||
|
assert(inMemPages <= numOfPages);
|
||||||
|
|
||||||
|
pResBuf->numOfRowsPerPage = (pagesize - sizeof(tFilePage)) / rowSize;
|
||||||
|
|
||||||
|
pResBuf->totalBufSize = pResBuf->numOfPages * pagesize;
|
||||||
|
pResBuf->incStep = 4;
|
||||||
|
pResBuf->allocateId = -1;
|
||||||
|
|
||||||
|
pResBuf->iBuf = calloc(pResBuf->inMemPages, pResBuf->pageSize);
|
||||||
|
|
||||||
|
// init id hash table
|
||||||
|
pResBuf->idsTable = taosHashInit(numOfPages, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false);
|
||||||
|
pResBuf->list = taosArrayInit(numOfPages, POINTER_BYTES);
|
||||||
|
|
||||||
|
char path[PATH_MAX] = {0};
|
||||||
|
getTmpfilePath("tsdb_qbuf", path);
|
||||||
|
pResBuf->path = strdup(path);
|
||||||
|
|
||||||
|
pResBuf->fd = FD_INITIALIZER;
|
||||||
|
pResBuf->pBuf = NULL;
|
||||||
|
pResBuf->emptyDummyIdList = taosArrayInit(1, sizeof(int32_t));
|
||||||
|
|
||||||
|
qDebug("QInfo:%p create resBuf for output, page size:%d, initial pages:%d, %" PRId64 "bytes", handle,
|
||||||
|
pResBuf->pageSize, pResBuf->numOfPages, pResBuf->totalBufSize);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getNumOfResultBufGroupId(SDiskbasedResultBuf* pResultBuf) { return taosHashGetSize(pResultBuf->idsTable); }
|
||||||
|
|
||||||
|
int32_t getResBufSize(SDiskbasedResultBuf* pResultBuf) { return pResultBuf->totalBufSize; }
|
||||||
|
|
||||||
|
#define NUM_OF_PAGES_ON_DISK(_r) ((_r)->numOfPages - (_r)->inMemPages)
|
||||||
|
#define FILE_SIZE_ON_DISK(_r) (NUM_OF_PAGES_ON_DISK(_r) * (_r)->pageSize)
|
||||||
|
|
||||||
|
static int32_t createDiskResidesBuf(SDiskbasedResultBuf* pResultBuf) {
|
||||||
|
pResultBuf->fd = open(pResultBuf->path, O_CREAT | O_RDWR, 0666);
|
||||||
|
if (!FD_VALID(pResultBuf->fd)) {
|
||||||
|
qError("failed to create tmp file: %s on disk. %s", pResultBuf->path, strerror(errno));
|
||||||
|
return TAOS_SYSTEM_ERROR(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(pResultBuf->numOfPages == pResultBuf->inMemPages);
|
||||||
|
pResultBuf->numOfPages += pResultBuf->incStep;
|
||||||
|
|
||||||
|
int32_t ret = ftruncate(pResultBuf->fd, NUM_OF_PAGES_ON_DISK(pResultBuf) * pResultBuf->pageSize);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
qError("failed to create tmp file: %s on disk. %s", pResultBuf->path, strerror(errno));
|
||||||
|
return TAOS_SYSTEM_ERROR(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
pResultBuf->pBuf = mmap(NULL, FILE_SIZE_ON_DISK(pResultBuf), PROT_READ | PROT_WRITE, MAP_SHARED, pResultBuf->fd, 0);
|
||||||
|
if (pResultBuf->pBuf == MAP_FAILED) {
|
||||||
|
qError("QInfo:%p failed to map temp file: %s. %s", pResultBuf->handle, pResultBuf->path, strerror(errno));
|
||||||
|
return TAOS_SYSTEM_ERROR(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
pResultBuf->totalBufSize = pResultBuf->numOfPages * pResultBuf->pageSize;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t extendDiskFileSize(SDiskbasedResultBuf* pResultBuf, int32_t incNumOfPages) {
|
||||||
|
assert(pResultBuf->numOfPages * pResultBuf->pageSize == pResultBuf->totalBufSize);
|
||||||
|
int32_t ret = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
if (pResultBuf->pBuf == NULL) {
|
||||||
|
assert(pResultBuf->fd == FD_INITIALIZER);
|
||||||
|
|
||||||
|
if ((ret = createDiskResidesBuf(pResultBuf)) != TSDB_CODE_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = munmap(pResultBuf->pBuf, FILE_SIZE_ON_DISK(pResultBuf));
|
||||||
|
pResultBuf->numOfPages += incNumOfPages;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* disk-based output buffer is exhausted, try to extend the disk-based buffer, the available disk space may
|
||||||
|
* be insufficient
|
||||||
|
*/
|
||||||
|
ret = ftruncate(pResultBuf->fd, NUM_OF_PAGES_ON_DISK(pResultBuf) * pResultBuf->pageSize);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
// dError("QInfo:%p failed to create intermediate result output file:%s. %s", pQInfo, pSupporter->extBufFile,
|
||||||
|
// strerror(errno));
|
||||||
|
return TSDB_CODE_QRY_NO_DISKSPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pResultBuf->totalBufSize = pResultBuf->numOfPages * pResultBuf->pageSize;
|
||||||
|
pResultBuf->pBuf = mmap(NULL, FILE_SIZE_ON_DISK(pResultBuf), PROT_READ | PROT_WRITE, MAP_SHARED, pResultBuf->fd, 0);
|
||||||
|
|
||||||
|
if (pResultBuf->pBuf == MAP_FAILED) {
|
||||||
|
// dError("QInfo:%p failed to map temp file: %s. %s", pQInfo, pSupporter->extBufFile, strerror(errno));
|
||||||
|
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NO_AVAILABLE_PAGES(_b) ((_b)->allocateId == (_b)->numOfPages - 1)
|
||||||
|
|
||||||
|
static FORCE_INLINE int32_t getGroupIndex(SDiskbasedResultBuf* pResultBuf, int32_t groupId) {
|
||||||
|
assert(pResultBuf != NULL);
|
||||||
|
|
||||||
|
char* p = taosHashGet(pResultBuf->idsTable, (const char*)&groupId, sizeof(int32_t));
|
||||||
|
if (p == NULL) { // it is a new group id
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t slot = GET_INT32_VAL(p);
|
||||||
|
assert(slot >= 0 && slot < taosHashGetSize(pResultBuf->idsTable));
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t addNewGroupId(SDiskbasedResultBuf* pResultBuf, int32_t groupId) {
|
||||||
|
int32_t num = getNumOfResultBufGroupId(pResultBuf); // the num is the newest allocated group id slot
|
||||||
|
taosHashPut(pResultBuf->idsTable, (const char*)&groupId, sizeof(int32_t), &num, sizeof(int32_t));
|
||||||
|
|
||||||
|
SArray* pa = taosArrayInit(1, sizeof(int32_t));
|
||||||
|
taosArrayPush(pResultBuf->list, &pa);
|
||||||
|
|
||||||
|
assert(taosArrayGetSize(pResultBuf->list) == taosHashGetSize(pResultBuf->idsTable));
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void registerPageId(SDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t pageId) {
|
||||||
|
int32_t slot = getGroupIndex(pResultBuf, groupId);
|
||||||
|
if (slot < 0) {
|
||||||
|
slot = addNewGroupId(pResultBuf, groupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
SIDList pList = taosArrayGetP(pResultBuf->list, slot);
|
||||||
|
taosArrayPush(pList, &pageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
tFilePage* getNewDataBuf(SDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t* pageId) {
|
||||||
|
if (NO_AVAILABLE_PAGES(pResultBuf)) {
|
||||||
|
if (extendDiskFileSize(pResultBuf, pResultBuf->incStep) != TSDB_CODE_SUCCESS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// register new id in this group
|
||||||
|
*pageId = (++pResultBuf->allocateId);
|
||||||
|
registerPageId(pResultBuf, groupId, *pageId);
|
||||||
|
|
||||||
|
// clear memory for the new page
|
||||||
|
tFilePage* page = getResBufPage(pResultBuf, *pageId);
|
||||||
|
memset(page, 0, pResultBuf->pageSize);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getNumOfRowsPerPage(SDiskbasedResultBuf* pResultBuf) { return pResultBuf->numOfRowsPerPage; }
|
||||||
|
|
||||||
|
SIDList getDataBufPagesIdList(SDiskbasedResultBuf* pResultBuf, int32_t groupId) {
|
||||||
|
int32_t slot = getGroupIndex(pResultBuf, groupId);
|
||||||
|
if (slot < 0) {
|
||||||
|
return pResultBuf->emptyDummyIdList;
|
||||||
|
} else {
|
||||||
|
return taosArrayGetP(pResultBuf->list, slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyResultBuf(SDiskbasedResultBuf* pResultBuf, void* handle) {
|
||||||
|
if (pResultBuf == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FD_VALID(pResultBuf->fd)) {
|
||||||
|
qDebug("QInfo:%p disk-based output buffer closed, total:%" PRId64 " bytes, file created:%s, file size:%d", handle,
|
||||||
|
pResultBuf->totalBufSize, pResultBuf->path, FILE_SIZE_ON_DISK(pResultBuf));
|
||||||
|
|
||||||
|
close(pResultBuf->fd);
|
||||||
|
munmap(pResultBuf->pBuf, FILE_SIZE_ON_DISK(pResultBuf));
|
||||||
|
pResultBuf->pBuf = NULL;
|
||||||
|
} else {
|
||||||
|
qDebug("QInfo:%p disk-based output buffer closed, total:%" PRId64 " bytes, no file created", handle,
|
||||||
|
pResultBuf->totalBufSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink(pResultBuf->path);
|
||||||
|
tfree(pResultBuf->path);
|
||||||
|
|
||||||
|
size_t size = taosArrayGetSize(pResultBuf->list);
|
||||||
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
|
SArray* pa = taosArrayGetP(pResultBuf->list, i);
|
||||||
|
taosArrayDestroy(pa);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayDestroy(pResultBuf->list);
|
||||||
|
taosArrayDestroy(pResultBuf->emptyDummyIdList);
|
||||||
|
taosHashCleanup(pResultBuf->idsTable);
|
||||||
|
|
||||||
|
tfree(pResultBuf->iBuf);
|
||||||
|
tfree(pResultBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getLastPageId(SIDList pList) {
|
||||||
|
size_t size = taosArrayGetSize(pList);
|
||||||
|
return *(int32_t*) taosArrayGet(pList, size - 1);
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "qsyntaxtreefunction.h"
|
#include "qSyntaxtreefunction.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "qtsbuf.h"
|
#include "qTsbuf.h"
|
||||||
|
#include "taoserror.h"
|
||||||
#include "tscompression.h"
|
#include "tscompression.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
#include "taoserror.h"
|
|
||||||
|
|
||||||
static int32_t getDataStartOffset();
|
static int32_t getDataStartOffset();
|
||||||
static void TSBufUpdateVnodeInfo(STSBuf* pTSBuf, int32_t index, STSVnodeBlockInfo* pBlockInfo);
|
static void TSBufUpdateVnodeInfo(STSBuf* pTSBuf, int32_t index, STSVnodeBlockInfo* pBlockInfo);
|
|
@ -26,12 +26,10 @@ int32_t getOutputInterResultBufSize(SQuery* pQuery) {
|
||||||
int32_t size = 0;
|
int32_t size = 0;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||||
assert(pQuery->pSelectExpr[i].interBytes <= DEFAULT_INTERN_BUF_PAGE_SIZE);
|
|
||||||
size += pQuery->pSelectExpr[i].interBytes;
|
size += pQuery->pSelectExpr[i].interBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +241,7 @@ void clearTimeWindowResBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pWindow
|
||||||
size_t size = pRuntimeEnv->pQuery->pSelectExpr[i].bytes;
|
size_t size = pRuntimeEnv->pQuery->pSelectExpr[i].bytes;
|
||||||
memset(s, 0, size);
|
memset(s, 0, size);
|
||||||
|
|
||||||
resetResultInfo(pResultInfo);
|
RESET_RESULT_INFO(pResultInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
pWindowRes->numOfRows = 0;
|
pWindowRes->numOfRows = 0;
|
||||||
|
|
|
@ -1,184 +0,0 @@
|
||||||
#include "qresultBuf.h"
|
|
||||||
#include "hash.h"
|
|
||||||
#include "qextbuffer.h"
|
|
||||||
#include "taoserror.h"
|
|
||||||
#include "queryLog.h"
|
|
||||||
|
|
||||||
int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t size, int32_t rowSize, void* handle) {
|
|
||||||
*pResultBuf = calloc(1, sizeof(SDiskbasedResultBuf));
|
|
||||||
SDiskbasedResultBuf* pResBuf = *pResultBuf;
|
|
||||||
if (pResBuf == NULL) {
|
|
||||||
return TSDB_CODE_COM_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
pResBuf->numOfRowsPerPage = (DEFAULT_INTERN_BUF_PAGE_SIZE - sizeof(tFilePage)) / rowSize;
|
|
||||||
pResBuf->numOfPages = size;
|
|
||||||
|
|
||||||
pResBuf->totalBufSize = pResBuf->numOfPages * DEFAULT_INTERN_BUF_PAGE_SIZE;
|
|
||||||
pResBuf->incStep = 4;
|
|
||||||
|
|
||||||
// init id hash table
|
|
||||||
pResBuf->idsTable = taosHashInit(size, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false);
|
|
||||||
pResBuf->list = taosArrayInit(size, POINTER_BYTES);
|
|
||||||
|
|
||||||
char path[4096] = {0};
|
|
||||||
getTmpfilePath("tsdb_qbuf", path);
|
|
||||||
pResBuf->path = strdup(path);
|
|
||||||
|
|
||||||
pResBuf->fd = open(pResBuf->path, O_CREAT | O_RDWR, 0666);
|
|
||||||
if (!FD_VALID(pResBuf->fd)) {
|
|
||||||
qError("failed to create tmp file: %s on disk. %s", pResBuf->path, strerror(errno));
|
|
||||||
return TAOS_SYSTEM_ERROR(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t ret = ftruncate(pResBuf->fd, pResBuf->numOfPages * DEFAULT_INTERN_BUF_PAGE_SIZE);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
qError("failed to create tmp file: %s on disk. %s", pResBuf->path, strerror(errno));
|
|
||||||
return TAOS_SYSTEM_ERROR(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
pResBuf->pBuf = mmap(NULL, pResBuf->totalBufSize, PROT_READ | PROT_WRITE, MAP_SHARED, pResBuf->fd, 0);
|
|
||||||
if (pResBuf->pBuf == MAP_FAILED) {
|
|
||||||
qError("QInfo:%p failed to map temp file: %s. %s", handle, pResBuf->path, strerror(errno));
|
|
||||||
return TAOS_SYSTEM_ERROR(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug("QInfo:%p create tmp file for output result:%s, %" PRId64 "bytes", handle, pResBuf->path,
|
|
||||||
pResBuf->totalBufSize);
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t getNumOfResultBufGroupId(SDiskbasedResultBuf* pResultBuf) { return taosHashGetSize(pResultBuf->idsTable); }
|
|
||||||
|
|
||||||
int32_t getResBufSize(SDiskbasedResultBuf* pResultBuf) { return pResultBuf->totalBufSize; }
|
|
||||||
|
|
||||||
static int32_t extendDiskFileSize(SDiskbasedResultBuf* pResultBuf, int32_t numOfPages) {
|
|
||||||
assert(pResultBuf->numOfPages * DEFAULT_INTERN_BUF_PAGE_SIZE == pResultBuf->totalBufSize);
|
|
||||||
|
|
||||||
int32_t ret = munmap(pResultBuf->pBuf, pResultBuf->totalBufSize);
|
|
||||||
pResultBuf->numOfPages += numOfPages;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* disk-based output buffer is exhausted, try to extend the disk-based buffer, the available disk space may
|
|
||||||
* be insufficient
|
|
||||||
*/
|
|
||||||
ret = ftruncate(pResultBuf->fd, pResultBuf->numOfPages * DEFAULT_INTERN_BUF_PAGE_SIZE);
|
|
||||||
if (ret != 0) {
|
|
||||||
// dError("QInfo:%p failed to create intermediate result output file:%s. %s", pQInfo, pSupporter->extBufFile,
|
|
||||||
// strerror(errno));
|
|
||||||
return TSDB_CODE_QRY_NO_DISKSPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pResultBuf->totalBufSize = pResultBuf->numOfPages * DEFAULT_INTERN_BUF_PAGE_SIZE;
|
|
||||||
pResultBuf->pBuf = mmap(NULL, pResultBuf->totalBufSize, PROT_READ | PROT_WRITE, MAP_SHARED, pResultBuf->fd, 0);
|
|
||||||
|
|
||||||
if (pResultBuf->pBuf == MAP_FAILED) {
|
|
||||||
// dError("QInfo:%p failed to map temp file: %s. %s", pQInfo, pSupporter->extBufFile, strerror(errno));
|
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FORCE_INLINE bool noMoreAvailablePages(SDiskbasedResultBuf* pResultBuf) {
|
|
||||||
return (pResultBuf->allocateId == pResultBuf->numOfPages - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static FORCE_INLINE int32_t getGroupIndex(SDiskbasedResultBuf* pResultBuf, int32_t groupId) {
|
|
||||||
assert(pResultBuf != NULL);
|
|
||||||
|
|
||||||
char* p = taosHashGet(pResultBuf->idsTable, (const char*)&groupId, sizeof(int32_t));
|
|
||||||
if (p == NULL) { // it is a new group id
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t slot = GET_INT32_VAL(p);
|
|
||||||
assert(slot >= 0 && slot < taosHashGetSize(pResultBuf->idsTable));
|
|
||||||
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t addNewGroupId(SDiskbasedResultBuf* pResultBuf, int32_t groupId) {
|
|
||||||
int32_t num = getNumOfResultBufGroupId(pResultBuf); // the num is the newest allocated group id slot
|
|
||||||
taosHashPut(pResultBuf->idsTable, (const char*)&groupId, sizeof(int32_t), &num, sizeof(int32_t));
|
|
||||||
|
|
||||||
SArray* pa = taosArrayInit(1, sizeof(int32_t));
|
|
||||||
taosArrayPush(pResultBuf->list, &pa);
|
|
||||||
|
|
||||||
assert(taosArrayGetSize(pResultBuf->list) == taosHashGetSize(pResultBuf->idsTable));
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void registerPageId(SDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t pageId) {
|
|
||||||
int32_t slot = getGroupIndex(pResultBuf, groupId);
|
|
||||||
if (slot < 0) {
|
|
||||||
slot = addNewGroupId(pResultBuf, groupId);
|
|
||||||
}
|
|
||||||
|
|
||||||
SIDList pList = taosArrayGetP(pResultBuf->list, slot);
|
|
||||||
taosArrayPush(pList, &pageId);
|
|
||||||
}
|
|
||||||
|
|
||||||
tFilePage* getNewDataBuf(SDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t* pageId) {
|
|
||||||
if (noMoreAvailablePages(pResultBuf)) {
|
|
||||||
if (extendDiskFileSize(pResultBuf, pResultBuf->incStep) != TSDB_CODE_SUCCESS) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// register new id in this group
|
|
||||||
*pageId = (pResultBuf->allocateId++);
|
|
||||||
registerPageId(pResultBuf, groupId, *pageId);
|
|
||||||
|
|
||||||
tFilePage* page = GET_RES_BUF_PAGE_BY_ID(pResultBuf, *pageId);
|
|
||||||
|
|
||||||
// clear memory for the new page
|
|
||||||
memset(page, 0, DEFAULT_INTERN_BUF_PAGE_SIZE);
|
|
||||||
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t getNumOfRowsPerPage(SDiskbasedResultBuf* pResultBuf) { return pResultBuf->numOfRowsPerPage; }
|
|
||||||
|
|
||||||
SIDList getDataBufPagesIdList(SDiskbasedResultBuf* pResultBuf, int32_t groupId) {
|
|
||||||
int32_t slot = getGroupIndex(pResultBuf, groupId);
|
|
||||||
if (slot < 0) {
|
|
||||||
return taosArrayInit(1, sizeof(int32_t));
|
|
||||||
} else {
|
|
||||||
return taosArrayGetP(pResultBuf->list, slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroyResultBuf(SDiskbasedResultBuf* pResultBuf, void* handle) {
|
|
||||||
if (pResultBuf == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FD_VALID(pResultBuf->fd)) {
|
|
||||||
close(pResultBuf->fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug("QInfo:%p disk-based output buffer closed, %" PRId64 " bytes, file:%s", handle, pResultBuf->totalBufSize, pResultBuf->path);
|
|
||||||
munmap(pResultBuf->pBuf, pResultBuf->totalBufSize);
|
|
||||||
unlink(pResultBuf->path);
|
|
||||||
|
|
||||||
tfree(pResultBuf->path);
|
|
||||||
|
|
||||||
size_t size = taosArrayGetSize(pResultBuf->list);
|
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
|
||||||
SArray* pa = taosArrayGetP(pResultBuf->list, i);
|
|
||||||
taosArrayDestroy(pa);
|
|
||||||
}
|
|
||||||
|
|
||||||
taosArrayDestroy(pResultBuf->list);
|
|
||||||
taosHashCleanup(pResultBuf->idsTable);
|
|
||||||
|
|
||||||
tfree(pResultBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t getLastPageId(SIDList pList) {
|
|
||||||
size_t size = taosArrayGetSize(pList);
|
|
||||||
return *(int32_t*) taosArrayGet(pList, size - 1);
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,5 +11,5 @@ IF (HEADER_GTEST_INCLUDE_DIR AND LIB_GTEST_STATIC_DIR)
|
||||||
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
||||||
|
|
||||||
ADD_EXECUTABLE(queryTest ${SOURCE_LIST})
|
ADD_EXECUTABLE(queryTest ${SOURCE_LIST})
|
||||||
TARGET_LINK_LIBRARIES(queryTest taos query gtest pthread)
|
TARGET_LINK_LIBRARIES(queryTest taos query gtest pthread gcov)
|
||||||
ENDIF()
|
ENDIF()
|
|
@ -3,8 +3,8 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "qAst.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "qast.h"
|
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
#include "tskiplist.h"
|
#include "tskiplist.h"
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "tstoken.h"
|
#include "tstoken.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
#include "qhistogram.h"
|
#include "qHistogram.h"
|
||||||
|
|
||||||
/* test validate the names for table/database */
|
/* test validate the names for table/database */
|
||||||
TEST(testCase, histogram_binary_search) {
|
TEST(testCase, histogram_binary_search) {
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "qResultbuf.h"
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "qresultBuf.h"
|
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// simple test
|
// simple test
|
||||||
void simpleTest() {
|
void simpleTest() {
|
||||||
SDiskbasedResultBuf* pResultBuf = NULL;
|
SDiskbasedResultBuf* pResultBuf = NULL;
|
||||||
int32_t ret = createDiskbasedResultBuffer(&pResultBuf, 1000, 64, NULL);
|
int32_t ret = createDiskbasedResultBuffer(&pResultBuf, 1000, 64, 1024, 4, NULL);
|
||||||
|
|
||||||
int32_t pageId = 0;
|
int32_t pageId = 0;
|
||||||
int32_t groupId = 0;
|
int32_t groupId = 0;
|
||||||
|
@ -22,8 +22,7 @@ void simpleTest() {
|
||||||
ASSERT_EQ(getResBufSize(pResultBuf), 1000*16384L);
|
ASSERT_EQ(getResBufSize(pResultBuf), 1000*16384L);
|
||||||
|
|
||||||
SIDList list = getDataBufPagesIdList(pResultBuf, groupId);
|
SIDList list = getDataBufPagesIdList(pResultBuf, groupId);
|
||||||
ASSERT_EQ(list.size, 1);
|
ASSERT_EQ(taosArrayGetSize(list), 1);
|
||||||
|
|
||||||
ASSERT_EQ(getNumOfResultBufGroupId(pResultBuf), 1);
|
ASSERT_EQ(getNumOfResultBufGroupId(pResultBuf), 1);
|
||||||
|
|
||||||
destroyResultBuf(pResultBuf, NULL);
|
destroyResultBuf(pResultBuf, NULL);
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
|
|
||||||
|
#include "qTsbuf.h"
|
||||||
#include "tstoken.h"
|
#include "tstoken.h"
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
#include "qtsbuf.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -446,6 +446,9 @@ void rpcSendResponse(const SRpcMsg *pRsp) {
|
||||||
// set the idle timer to monitor the activity
|
// set the idle timer to monitor the activity
|
||||||
taosTmrReset(rpcProcessIdleTimer, pRpc->idleTime, pConn, pRpc->tmrCtrl, &pConn->pIdleTimer);
|
taosTmrReset(rpcProcessIdleTimer, pRpc->idleTime, pConn, pRpc->tmrCtrl, &pConn->pIdleTimer);
|
||||||
rpcSendMsgToPeer(pConn, msg, msgLen);
|
rpcSendMsgToPeer(pConn, msg, msgLen);
|
||||||
|
|
||||||
|
// if not set to secured, set it expcet NOT_READY case, since client wont treat it as secured
|
||||||
|
if (pConn->secured == 0 && pMsg->code != TSDB_CODE_RPC_NOT_READY)
|
||||||
pConn->secured = 1; // connection shall be secured
|
pConn->secured = 1; // connection shall be secured
|
||||||
|
|
||||||
if (pConn->pReqMsg) rpcFreeCont(pConn->pReqMsg);
|
if (pConn->pReqMsg) rpcFreeCont(pConn->pReqMsg);
|
||||||
|
|
|
@ -426,6 +426,7 @@ int tsdbUpdateFileHeader(SFile* pFile, uint32_t version);
|
||||||
int tsdbEncodeSFileInfo(void** buf, const STsdbFileInfo* pInfo);
|
int tsdbEncodeSFileInfo(void** buf, const STsdbFileInfo* pInfo);
|
||||||
void* tsdbDecodeSFileInfo(void* buf, STsdbFileInfo* pInfo);
|
void* tsdbDecodeSFileInfo(void* buf, STsdbFileInfo* pInfo);
|
||||||
void tsdbRemoveFileGroup(STsdbRepo* pRepo, SFileGroup* pFGroup);
|
void tsdbRemoveFileGroup(STsdbRepo* pRepo, SFileGroup* pFGroup);
|
||||||
|
void tsdbGetFidKeyRange(int daysPerFile, int8_t precision, int fileId, TSKEY *minKey, TSKEY *maxKey);
|
||||||
|
|
||||||
// ------------------ tsdbRWHelper.c
|
// ------------------ tsdbRWHelper.c
|
||||||
#define TSDB_HELPER_CLEAR_STATE 0x0 // Clear state
|
#define TSDB_HELPER_CLEAR_STATE 0x0 // Clear state
|
||||||
|
|
|
@ -31,7 +31,6 @@ static int tsdbCommitMeta(STsdbRepo *pRepo);
|
||||||
static void tsdbEndCommit(STsdbRepo *pRepo);
|
static void tsdbEndCommit(STsdbRepo *pRepo);
|
||||||
static int tsdbHasDataToCommit(SCommitIter *iters, int nIters, TSKEY minKey, TSKEY maxKey);
|
static int tsdbHasDataToCommit(SCommitIter *iters, int nIters, TSKEY minKey, TSKEY maxKey);
|
||||||
static int tsdbCommitToFile(STsdbRepo *pRepo, int fid, SCommitIter *iters, SRWHelper *pHelper, SDataCols *pDataCols);
|
static int tsdbCommitToFile(STsdbRepo *pRepo, int fid, SCommitIter *iters, SRWHelper *pHelper, SDataCols *pDataCols);
|
||||||
static void tsdbGetFidKeyRange(int daysPerFile, int8_t precision, int fileId, TSKEY *minKey, TSKEY *maxKey);
|
|
||||||
static SCommitIter *tsdbCreateCommitIters(STsdbRepo *pRepo);
|
static SCommitIter *tsdbCreateCommitIters(STsdbRepo *pRepo);
|
||||||
static void tsdbDestroyCommitIters(SCommitIter *iters, int maxTables);
|
static void tsdbDestroyCommitIters(SCommitIter *iters, int maxTables);
|
||||||
|
|
||||||
|
@ -544,7 +543,7 @@ static int tsdbHasDataToCommit(SCommitIter *iters, int nIters, TSKEY minKey, TSK
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tsdbGetFidKeyRange(int daysPerFile, int8_t precision, int fileId, TSKEY *minKey, TSKEY *maxKey) {
|
void tsdbGetFidKeyRange(int daysPerFile, int8_t precision, int fileId, TSKEY *minKey, TSKEY *maxKey) {
|
||||||
*minKey = fileId * daysPerFile * tsMsPerDay[precision];
|
*minKey = fileId * daysPerFile * tsMsPerDay[precision];
|
||||||
*maxKey = *minKey + daysPerFile * tsMsPerDay[precision] - 1;
|
*maxKey = *minKey + daysPerFile * tsMsPerDay[precision] - 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "tcompare.h"
|
#include "tcompare.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
|
||||||
#include "../../../query/inc/qast.h" // todo move to common module
|
#include "../../query/inc/qAst.h" // todo move to common module
|
||||||
#include "tlosertree.h"
|
#include "tlosertree.h"
|
||||||
#include "tsdb.h"
|
#include "tsdb.h"
|
||||||
#include "tsdbMain.h"
|
#include "tsdbMain.h"
|
||||||
|
@ -128,8 +128,7 @@ typedef struct STsdbQueryHandle {
|
||||||
|
|
||||||
static void changeQueryHandleForLastrowQuery(TsdbQueryHandleT pqHandle);
|
static void changeQueryHandleForLastrowQuery(TsdbQueryHandleT pqHandle);
|
||||||
static void changeQueryHandleForInterpQuery(TsdbQueryHandleT pHandle);
|
static void changeQueryHandleForInterpQuery(TsdbQueryHandleT pHandle);
|
||||||
static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo* pCheckInfo, SCompBlock* pBlock,
|
static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo* pCheckInfo, SCompBlock* pBlock);
|
||||||
SArray* sa);
|
|
||||||
static int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order);
|
static int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order);
|
||||||
static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int maxRowsToRead, STimeWindow* win,
|
static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int maxRowsToRead, STimeWindow* win,
|
||||||
STsdbQueryHandle* pQueryHandle);
|
STsdbQueryHandle* pQueryHandle);
|
||||||
|
@ -240,7 +239,7 @@ TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STab
|
||||||
|
|
||||||
pQueryHandle->defaultLoadColumn = getDefaultLoadColumns(pQueryHandle, true);
|
pQueryHandle->defaultLoadColumn = getDefaultLoadColumns(pQueryHandle, true);
|
||||||
|
|
||||||
tsdbDebug("%p total numOfTable:%zu in query", pQueryHandle, taosArrayGetSize(pQueryHandle->pTableCheckInfo));
|
tsdbDebug("%p total numOfTable:%zu in query, %p", pQueryHandle, taosArrayGetSize(pQueryHandle->pTableCheckInfo), pQueryHandle->qinfo);
|
||||||
|
|
||||||
tsdbInitDataBlockLoadInfo(&pQueryHandle->dataBlockLoadInfo);
|
tsdbInitDataBlockLoadInfo(&pQueryHandle->dataBlockLoadInfo);
|
||||||
tsdbInitCompBlockLoadInfo(&pQueryHandle->compBlockLoadInfo);
|
tsdbInitCompBlockLoadInfo(&pQueryHandle->compBlockLoadInfo);
|
||||||
|
@ -331,7 +330,8 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
|
||||||
tsdbDebug("%p uid:%" PRId64", tid:%d check data in mem from skey:%" PRId64 ", order:%d, %p", pHandle,
|
tsdbDebug("%p uid:%" PRId64", tid:%d check data in mem from skey:%" PRId64 ", order:%d, %p", pHandle,
|
||||||
pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pHandle->qinfo);
|
pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pHandle->qinfo);
|
||||||
} else {
|
} else {
|
||||||
tsdbDebug("%p uid:%" PRId64 ", tid:%d no data in mem", pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid);
|
tsdbDebug("%p uid:%"PRId64", tid:%d no data in mem, %p", pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid,
|
||||||
|
pHandle->qinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!imemEmpty) {
|
if (!imemEmpty) {
|
||||||
|
@ -343,7 +343,8 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
|
||||||
tsdbDebug("%p uid:%" PRId64", tid:%d check data in imem from skey:%" PRId64 ", order:%d, %p", pHandle,
|
tsdbDebug("%p uid:%" PRId64", tid:%d check data in imem from skey:%" PRId64 ", order:%d, %p", pHandle,
|
||||||
pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pHandle->qinfo);
|
pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pHandle->qinfo);
|
||||||
} else {
|
} else {
|
||||||
tsdbDebug("%p uid:%"PRId64", tid:%d no data in imem", pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid);
|
tsdbDebug("%p uid:%"PRId64", tid:%d no data in imem, %p", pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid,
|
||||||
|
pHandle->qinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -354,7 +355,7 @@ static void destroyTableMemIterator(STableCheckInfo* pCheckInfo) {
|
||||||
tSkipListDestroyIter(pCheckInfo->iiter);
|
tSkipListDestroyIter(pCheckInfo->iiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDataRow getSDataRowInTableMem(STableCheckInfo* pCheckInfo) {
|
SDataRow getSDataRowInTableMem(STableCheckInfo* pCheckInfo, int32_t order) {
|
||||||
SDataRow rmem = NULL, rimem = NULL;
|
SDataRow rmem = NULL, rimem = NULL;
|
||||||
if (pCheckInfo->iter) {
|
if (pCheckInfo->iter) {
|
||||||
SSkipListNode* node = tSkipListIterGet(pCheckInfo->iter);
|
SSkipListNode* node = tSkipListIterGet(pCheckInfo->iter);
|
||||||
|
@ -371,20 +372,35 @@ SDataRow getSDataRowInTableMem(STableCheckInfo* pCheckInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rmem != NULL && rimem != NULL) {
|
if (rmem != NULL && rimem != NULL) {
|
||||||
if (dataRowKey(rmem) < dataRowKey(rimem)) {
|
TSKEY r1 = dataRowKey(rmem);
|
||||||
pCheckInfo->chosen = 0;
|
TSKEY r2 = dataRowKey(rimem);
|
||||||
return rmem;
|
|
||||||
} else if (dataRowKey(rmem) == dataRowKey(rimem)) {
|
if (r1 == r2) { // data ts are duplicated, ignore the data in mem
|
||||||
// data ts are duplicated, ignore the data in mem
|
|
||||||
tSkipListIterNext(pCheckInfo->iter);
|
tSkipListIterNext(pCheckInfo->iter);
|
||||||
pCheckInfo->chosen = 1;
|
pCheckInfo->chosen = 1;
|
||||||
return rimem;
|
return rimem;
|
||||||
|
} else {
|
||||||
|
if (ASCENDING_TRAVERSE(order)) {
|
||||||
|
if (r1 < r2) {
|
||||||
|
pCheckInfo->chosen = 0;
|
||||||
|
return rmem;
|
||||||
} else {
|
} else {
|
||||||
pCheckInfo->chosen = 1;
|
pCheckInfo->chosen = 1;
|
||||||
return rimem;
|
return rimem;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (r1 < r2) {
|
||||||
|
pCheckInfo->chosen = 1;
|
||||||
|
return rimem;
|
||||||
|
} else {
|
||||||
|
pCheckInfo->chosen = 0;
|
||||||
|
return rmem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// at least one (rmem or rimem) is absent here
|
||||||
if (rmem != NULL) {
|
if (rmem != NULL) {
|
||||||
pCheckInfo->chosen = 0;
|
pCheckInfo->chosen = 0;
|
||||||
return rmem;
|
return rmem;
|
||||||
|
@ -398,7 +414,7 @@ SDataRow getSDataRowInTableMem(STableCheckInfo* pCheckInfo) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool moveToNextRow(STableCheckInfo* pCheckInfo) {
|
static bool moveToNextRowInMem(STableCheckInfo* pCheckInfo) {
|
||||||
bool hasNext = false;
|
bool hasNext = false;
|
||||||
if (pCheckInfo->chosen == 0) {
|
if (pCheckInfo->chosen == 0) {
|
||||||
if (pCheckInfo->iter != NULL) {
|
if (pCheckInfo->iter != NULL) {
|
||||||
|
@ -412,8 +428,7 @@ static bool moveToNextRow(STableCheckInfo* pCheckInfo) {
|
||||||
if (pCheckInfo->iiter != NULL) {
|
if (pCheckInfo->iiter != NULL) {
|
||||||
return tSkipListIterGet(pCheckInfo->iiter) != NULL;
|
return tSkipListIterGet(pCheckInfo->iiter) != NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else { //pCheckInfo->chosen == 1
|
||||||
if (pCheckInfo->chosen == 1) {
|
|
||||||
if (pCheckInfo->iiter != NULL) {
|
if (pCheckInfo->iiter != NULL) {
|
||||||
hasNext = tSkipListIterNext(pCheckInfo->iiter);
|
hasNext = tSkipListIterNext(pCheckInfo->iiter);
|
||||||
}
|
}
|
||||||
|
@ -426,7 +441,6 @@ static bool moveToNextRow(STableCheckInfo* pCheckInfo) {
|
||||||
return tSkipListIterGet(pCheckInfo->iter) != NULL;
|
return tSkipListIterGet(pCheckInfo->iter) != NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return hasNext;
|
return hasNext;
|
||||||
}
|
}
|
||||||
|
@ -445,7 +459,7 @@ static bool hasMoreDataInCache(STsdbQueryHandle* pHandle) {
|
||||||
initTableMemIterator(pHandle, pCheckInfo);
|
initTableMemIterator(pHandle, pCheckInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDataRow row = getSDataRowInTableMem(pCheckInfo);
|
SDataRow row = getSDataRowInTableMem(pCheckInfo, pHandle->order);
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -650,7 +664,7 @@ static void handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SCompBlock*
|
||||||
SDataBlockInfo binfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
|
SDataBlockInfo binfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
|
||||||
|
|
||||||
/*bool hasData = */ initTableMemIterator(pQueryHandle, pCheckInfo);
|
/*bool hasData = */ initTableMemIterator(pQueryHandle, pCheckInfo);
|
||||||
SDataRow row = getSDataRowInTableMem(pCheckInfo);
|
SDataRow row = getSDataRowInTableMem(pCheckInfo, pQueryHandle->order);
|
||||||
|
|
||||||
TSKEY key = (row != NULL)? dataRowKey(row):TSKEY_INITIAL_VAL;
|
TSKEY key = (row != NULL)? dataRowKey(row):TSKEY_INITIAL_VAL;
|
||||||
cur->pos = ASCENDING_TRAVERSE(pQueryHandle->order)? 0:(binfo.rows-1);
|
cur->pos = ASCENDING_TRAVERSE(pQueryHandle->order)? 0:(binfo.rows-1);
|
||||||
|
@ -680,7 +694,7 @@ static void handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SCompBlock*
|
||||||
}
|
}
|
||||||
|
|
||||||
doLoadFileDataBlock(pQueryHandle, pBlock, pCheckInfo);
|
doLoadFileDataBlock(pQueryHandle, pBlock, pCheckInfo);
|
||||||
doMergeTwoLevelData(pQueryHandle, pCheckInfo, pBlock, pQueryHandle->defaultLoadColumn);
|
doMergeTwoLevelData(pQueryHandle, pCheckInfo, pBlock);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* no data in cache, only load data from file
|
* no data in cache, only load data from file
|
||||||
|
@ -696,6 +710,7 @@ static void handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SCompBlock*
|
||||||
cur->mixBlock = false;
|
cur->mixBlock = false;
|
||||||
cur->blockCompleted = true;
|
cur->blockCompleted = true;
|
||||||
cur->lastKey = binfo.window.ekey + (ASCENDING_TRAVERSE(pQueryHandle->order)? 1:-1);
|
cur->lastKey = binfo.window.ekey + (ASCENDING_TRAVERSE(pQueryHandle->order)? 1:-1);
|
||||||
|
pCheckInfo->lastKey = cur->lastKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,7 +734,7 @@ static bool loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBlock
|
||||||
cur->pos = 0;
|
cur->pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
doMergeTwoLevelData(pQueryHandle, pCheckInfo, pBlock, pQueryHandle->defaultLoadColumn);
|
doMergeTwoLevelData(pQueryHandle, pCheckInfo, pBlock);
|
||||||
} else { // the whole block is loaded in to buffer
|
} else { // the whole block is loaded in to buffer
|
||||||
handleDataMergeIfNeeded(pQueryHandle, pBlock, pCheckInfo);
|
handleDataMergeIfNeeded(pQueryHandle, pBlock, pCheckInfo);
|
||||||
}
|
}
|
||||||
|
@ -736,7 +751,7 @@ static bool loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBlock
|
||||||
cur->pos = pBlock->numOfRows - 1;
|
cur->pos = pBlock->numOfRows - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
doMergeTwoLevelData(pQueryHandle, pCheckInfo, pBlock, pQueryHandle->defaultLoadColumn);
|
doMergeTwoLevelData(pQueryHandle, pCheckInfo, pBlock);
|
||||||
} else {
|
} else {
|
||||||
handleDataMergeIfNeeded(pQueryHandle, pBlock, pCheckInfo);
|
handleDataMergeIfNeeded(pQueryHandle, pBlock, pCheckInfo);
|
||||||
}
|
}
|
||||||
|
@ -897,7 +912,7 @@ static int32_t copyDataFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t cap
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copyOneRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity, int32_t numOfRows, SDataRow row,
|
static void copyOneRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity, int32_t numOfRows, SDataRow row,
|
||||||
STsdbMeta *pMeta, int32_t numOfCols, STable* pTable) {
|
int32_t numOfCols, STable* pTable) {
|
||||||
char* pData = NULL;
|
char* pData = NULL;
|
||||||
|
|
||||||
// the schema version info is embeded in SDataRow
|
// the schema version info is embeded in SDataRow
|
||||||
|
@ -958,8 +973,7 @@ static void copyOneRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity,
|
||||||
|
|
||||||
// only return the qualified data to client in terms of query time window, data rows in the same block but do not
|
// only return the qualified data to client in terms of query time window, data rows in the same block but do not
|
||||||
// be included in the query time window will be discarded
|
// be included in the query time window will be discarded
|
||||||
static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo* pCheckInfo, SCompBlock* pBlock,
|
static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo* pCheckInfo, SCompBlock* pBlock) {
|
||||||
SArray* sa) {
|
|
||||||
SQueryFilePos* cur = &pQueryHandle->cur;
|
SQueryFilePos* cur = &pQueryHandle->cur;
|
||||||
SDataBlockInfo blockInfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
|
SDataBlockInfo blockInfo = GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
|
||||||
|
|
||||||
|
@ -972,7 +986,6 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
|
||||||
int32_t step = ASCENDING_TRAVERSE(pQueryHandle->order)? 1:-1;
|
int32_t step = ASCENDING_TRAVERSE(pQueryHandle->order)? 1:-1;
|
||||||
int32_t numOfCols = taosArrayGetSize(pQueryHandle->pColumns);
|
int32_t numOfCols = taosArrayGetSize(pQueryHandle->pColumns);
|
||||||
|
|
||||||
STsdbMeta* pMeta = tsdbGetMeta(pQueryHandle->pTsdb);
|
|
||||||
STable* pTable = pCheckInfo->pTableObj;
|
STable* pTable = pCheckInfo->pTableObj;
|
||||||
|
|
||||||
int32_t endPos = cur->pos;
|
int32_t endPos = cur->pos;
|
||||||
|
@ -1033,7 +1046,7 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
|
||||||
} else if (pCheckInfo->iter != NULL || pCheckInfo->iiter != NULL) {
|
} else if (pCheckInfo->iter != NULL || pCheckInfo->iiter != NULL) {
|
||||||
SSkipListNode* node = NULL;
|
SSkipListNode* node = NULL;
|
||||||
do {
|
do {
|
||||||
SDataRow row = getSDataRowInTableMem(pCheckInfo);
|
SDataRow row = getSDataRowInTableMem(pCheckInfo, pQueryHandle->order);
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1051,7 +1064,7 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
|
||||||
|
|
||||||
if ((key < tsArray[pos] && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
if ((key < tsArray[pos] && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
||||||
(key > tsArray[pos] && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
(key > tsArray[pos] && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
||||||
copyOneRowFromMem(pQueryHandle, pQueryHandle->outputCapacity, numOfRows, row, pMeta, numOfCols, pTable);
|
copyOneRowFromMem(pQueryHandle, pQueryHandle->outputCapacity, numOfRows, row, numOfCols, pTable);
|
||||||
numOfRows += 1;
|
numOfRows += 1;
|
||||||
if (cur->win.skey == TSKEY_INITIAL_VAL) {
|
if (cur->win.skey == TSKEY_INITIAL_VAL) {
|
||||||
cur->win.skey = key;
|
cur->win.skey = key;
|
||||||
|
@ -1061,9 +1074,9 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
|
||||||
cur->lastKey = key + step;
|
cur->lastKey = key + step;
|
||||||
cur->mixBlock = true;
|
cur->mixBlock = true;
|
||||||
|
|
||||||
moveToNextRow(pCheckInfo);
|
moveToNextRowInMem(pCheckInfo);
|
||||||
} else if (key == tsArray[pos]) { // data in buffer has the same timestamp of data in file block, ignore it
|
} else if (key == tsArray[pos]) { // data in buffer has the same timestamp of data in file block, ignore it
|
||||||
moveToNextRow(pCheckInfo);
|
moveToNextRowInMem(pCheckInfo);
|
||||||
} else if ((key > tsArray[pos] && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
} else if ((key > tsArray[pos] && ASCENDING_TRAVERSE(pQueryHandle->order)) ||
|
||||||
(key < tsArray[pos] && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
(key < tsArray[pos] && !ASCENDING_TRAVERSE(pQueryHandle->order))) {
|
||||||
if (cur->win.skey == TSKEY_INITIAL_VAL) {
|
if (cur->win.skey == TSKEY_INITIAL_VAL) {
|
||||||
|
@ -1072,7 +1085,7 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
|
||||||
|
|
||||||
int32_t end = doBinarySearchKey(pCols->cols[0].pData, pCols->numOfRows, key, order);
|
int32_t end = doBinarySearchKey(pCols->cols[0].pData, pCols->numOfRows, key, order);
|
||||||
if (tsArray[end] == key) { // the value of key in cache equals to the end timestamp value, ignore it
|
if (tsArray[end] == key) { // the value of key in cache equals to the end timestamp value, ignore it
|
||||||
moveToNextRow(pCheckInfo);
|
moveToNextRowInMem(pCheckInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t start = -1;
|
int32_t start = -1;
|
||||||
|
@ -1376,7 +1389,7 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tsdbDebug("%p %d data blocks sort completed", pQueryHandle, cnt);
|
tsdbDebug("%p %d data blocks sort completed, %p", pQueryHandle, cnt, pQueryHandle->qinfo);
|
||||||
cleanBlockOrderSupporter(&sup, numOfTables);
|
cleanBlockOrderSupporter(&sup, numOfTables);
|
||||||
free(pTree);
|
free(pTree);
|
||||||
|
|
||||||
|
@ -1392,7 +1405,20 @@ static int32_t getDataBlocksInFilesImpl(STsdbQueryHandle* pQueryHandle, bool* ex
|
||||||
int32_t numOfBlocks = 0;
|
int32_t numOfBlocks = 0;
|
||||||
int32_t numOfTables = taosArrayGetSize(pQueryHandle->pTableCheckInfo);
|
int32_t numOfTables = taosArrayGetSize(pQueryHandle->pTableCheckInfo);
|
||||||
|
|
||||||
|
STsdbCfg* pCfg = &pQueryHandle->pTsdb->config;
|
||||||
|
STimeWindow win = TSWINDOW_INITIALIZER;
|
||||||
|
|
||||||
while ((pQueryHandle->pFileGroup = tsdbGetFileGroupNext(&pQueryHandle->fileIter)) != NULL) {
|
while ((pQueryHandle->pFileGroup = tsdbGetFileGroupNext(&pQueryHandle->fileIter)) != NULL) {
|
||||||
|
tsdbGetFidKeyRange(pCfg->daysPerFile, pCfg->precision, pQueryHandle->pFileGroup->fileId, &win.skey, &win.ekey);
|
||||||
|
|
||||||
|
// current file are not overlapped with query time window, ignore remain files
|
||||||
|
if ((ASCENDING_TRAVERSE(pQueryHandle->order) && win.skey > pQueryHandle->window.ekey) ||
|
||||||
|
(!ASCENDING_TRAVERSE(pQueryHandle->order) && win.ekey < pQueryHandle->window.ekey)) {
|
||||||
|
tsdbDebug("%p remain files are not qualified for qrange:%"PRId64"-%"PRId64", ignore, %p", pQueryHandle, pQueryHandle->window.skey, pQueryHandle->window.ekey, pQueryHandle->qinfo)
|
||||||
|
pQueryHandle->pFileGroup = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ((code = getFileCompInfo(pQueryHandle, &numOfBlocks)) != TSDB_CODE_SUCCESS) {
|
if ((code = getFileCompInfo(pQueryHandle, &numOfBlocks)) != TSDB_CODE_SUCCESS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1750,11 +1776,10 @@ static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int
|
||||||
win->skey = TSKEY_INITIAL_VAL;
|
win->skey = TSKEY_INITIAL_VAL;
|
||||||
|
|
||||||
int64_t st = taosGetTimestampUs();
|
int64_t st = taosGetTimestampUs();
|
||||||
STsdbMeta* pMeta = tsdbGetMeta(pQueryHandle->pTsdb);
|
|
||||||
STable* pTable = pCheckInfo->pTableObj;
|
STable* pTable = pCheckInfo->pTableObj;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
SDataRow row = getSDataRowInTableMem(pCheckInfo);
|
SDataRow row = getSDataRowInTableMem(pCheckInfo, pQueryHandle->order);
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1772,14 +1797,14 @@ static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int
|
||||||
}
|
}
|
||||||
|
|
||||||
win->ekey = key;
|
win->ekey = key;
|
||||||
copyOneRowFromMem(pQueryHandle, maxRowsToRead, numOfRows, row, pMeta, numOfCols, pTable);
|
copyOneRowFromMem(pQueryHandle, maxRowsToRead, numOfRows, row, numOfCols, pTable);
|
||||||
|
|
||||||
if (++numOfRows >= maxRowsToRead) {
|
if (++numOfRows >= maxRowsToRead) {
|
||||||
moveToNextRow(pCheckInfo);
|
moveToNextRowInMem(pCheckInfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while(moveToNextRow(pCheckInfo));
|
} while(moveToNextRowInMem(pCheckInfo));
|
||||||
|
|
||||||
assert(numOfRows <= maxRowsToRead);
|
assert(numOfRows <= maxRowsToRead);
|
||||||
|
|
||||||
|
@ -1869,7 +1894,6 @@ int32_t tsdbRetrieveDataBlockStatisInfo(TsdbQueryHandleT* pQueryHandle, SDataSta
|
||||||
pHandle->statis[i].numOfNull = pBlockInfo->compBlock->numOfRows;
|
pHandle->statis[i].numOfNull = pBlockInfo->compBlock->numOfRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo opt perf
|
|
||||||
SColumnInfo* pColInfo = taosArrayGet(pHandle->pColumns, i);
|
SColumnInfo* pColInfo = taosArrayGet(pHandle->pColumns, i);
|
||||||
if (pColInfo->type == TSDB_DATA_TYPE_TIMESTAMP) {
|
if (pColInfo->type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||||
pHandle->statis[i].min = pBlockInfo->compBlock->keyFirst;
|
pHandle->statis[i].min = pBlockInfo->compBlock->keyFirst;
|
||||||
|
@ -1961,43 +1985,20 @@ static void destroyHelper(void* param) {
|
||||||
free(param);
|
free(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TAG_INVALID_COLUMN_INDEX -2
|
|
||||||
static int32_t getTagColumnIndex(STSchema* pTSchema, SSchema* pSchema) {
|
|
||||||
// filter on table name(TBNAME)
|
|
||||||
if (strcasecmp(pSchema->name, TSQL_TBNAME_L) == 0) {
|
|
||||||
return TSDB_TBNAME_COLUMN_INDEX;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int32_t i = 0; i < schemaNCols(pTSchema); ++i) {
|
|
||||||
STColumn* pColumn = &pTSchema->columns[i];
|
|
||||||
if (pColumn->bytes == pSchema->bytes && pColumn->type == pSchema->type && pColumn->colId == pSchema->colId) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void filterPrepare(void* expr, void* param) {
|
void filterPrepare(void* expr, void* param) {
|
||||||
tExprNode* pExpr = (tExprNode*)expr;
|
tExprNode* pExpr = (tExprNode*)expr;
|
||||||
if (pExpr->_node.info != NULL) {
|
if (pExpr->_node.info != NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t i = 0;
|
|
||||||
pExpr->_node.info = calloc(1, sizeof(tQueryInfo));
|
pExpr->_node.info = calloc(1, sizeof(tQueryInfo));
|
||||||
|
|
||||||
STSchema* pTSSchema = (STSchema*) param;
|
STSchema* pTSSchema = (STSchema*) param;
|
||||||
|
|
||||||
tQueryInfo* pInfo = pExpr->_node.info;
|
tQueryInfo* pInfo = pExpr->_node.info;
|
||||||
tVariant* pCond = pExpr->_node.pRight->pVal;
|
tVariant* pCond = pExpr->_node.pRight->pVal;
|
||||||
SSchema* pSchema = pExpr->_node.pLeft->pSchema;
|
SSchema* pSchema = pExpr->_node.pLeft->pSchema;
|
||||||
|
|
||||||
int32_t index = getTagColumnIndex(pTSSchema, pSchema);
|
|
||||||
assert((index >= 0 && i < TSDB_MAX_TAGS) || (index == TSDB_TBNAME_COLUMN_INDEX) || index == TAG_INVALID_COLUMN_INDEX);
|
|
||||||
|
|
||||||
pInfo->sch = *pSchema;
|
pInfo->sch = *pSchema;
|
||||||
pInfo->colIndex = index;
|
|
||||||
pInfo->optr = pExpr->_node.optr;
|
pInfo->optr = pExpr->_node.optr;
|
||||||
pInfo->compare = getComparFunc(pSchema->type, pInfo->optr);
|
pInfo->compare = getComparFunc(pSchema->type, pInfo->optr);
|
||||||
pInfo->param = pTSSchema;
|
pInfo->param = pTSSchema;
|
||||||
|
@ -2143,7 +2144,7 @@ bool indexedNodeFilterFp(const void* pNode, void* param) {
|
||||||
|
|
||||||
char* val = NULL;
|
char* val = NULL;
|
||||||
|
|
||||||
if (pInfo->colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
if (pInfo->sch.colId == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
val = (char*) TABLE_NAME(pTable);
|
val = (char*) TABLE_NAME(pTable);
|
||||||
} else {
|
} else {
|
||||||
val = tdGetKVRowValOfCol(pTable->tagVal, pInfo->sch.colId);
|
val = tdGetKVRowValOfCol(pTable->tagVal, pInfo->sch.colId);
|
||||||
|
|
|
@ -75,7 +75,7 @@ void taosRUnLockLatch(SRWLatch *pLatch);
|
||||||
|
|
||||||
// copy on read
|
// copy on read
|
||||||
#define taosCorBeginRead(x) for (uint32_t i_ = 1; 1; ++i_) { \
|
#define taosCorBeginRead(x) for (uint32_t i_ = 1; 1; ++i_) { \
|
||||||
int32_t old_ = atomic_load_32(x); \
|
int32_t old_ = atomic_add_fetch_32((x), 0); \
|
||||||
if (old_ & 0x00000001) { \
|
if (old_ & 0x00000001) { \
|
||||||
if (i_ % 1000 == 0) { \
|
if (i_ % 1000 == 0) { \
|
||||||
sched_yield(); \
|
sched_yield(); \
|
||||||
|
@ -84,7 +84,7 @@ void taosRUnLockLatch(SRWLatch *pLatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define taosCorEndRead(x) \
|
#define taosCorEndRead(x) \
|
||||||
if (atomic_load_32(x) == old_) { \
|
if (atomic_add_fetch_32((x), 0) == old_) { \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,12 +35,12 @@ extern "C" {
|
||||||
#define WCHAR wchar_t
|
#define WCHAR wchar_t
|
||||||
|
|
||||||
#define tfree(x) \
|
#define tfree(x) \
|
||||||
{ \
|
do { \
|
||||||
if (x) { \
|
if (x) { \
|
||||||
free((void *)(x)); \
|
free((void *)(x)); \
|
||||||
x = 0; \
|
x = 0; \
|
||||||
} \
|
} \
|
||||||
}
|
} while(0);
|
||||||
|
|
||||||
#define tstrncpy(dst, src, size) \
|
#define tstrncpy(dst, src, size) \
|
||||||
do { \
|
do { \
|
||||||
|
|
|
@ -522,7 +522,7 @@ int32_t taosFileRename(char *fullPath, char *suffix, char delimiter, char **dstP
|
||||||
void getTmpfilePath(const char *fileNamePrefix, char *dstPath) {
|
void getTmpfilePath(const char *fileNamePrefix, char *dstPath) {
|
||||||
const char* tdengineTmpFileNamePrefix = "tdengine-";
|
const char* tdengineTmpFileNamePrefix = "tdengine-";
|
||||||
|
|
||||||
char tmpPath[PATH_MAX] = {0};
|
char tmpPath[PATH_MAX];
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
char *tmpDir = getenv("tmp");
|
char *tmpDir = getenv("tmp");
|
||||||
|
|
|
@ -11,5 +11,5 @@ IF (HEADER_GTEST_INCLUDE_DIR AND LIB_GTEST_STATIC_DIR)
|
||||||
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
||||||
|
|
||||||
ADD_EXECUTABLE(utilTest ${SOURCE_LIST})
|
ADD_EXECUTABLE(utilTest ${SOURCE_LIST})
|
||||||
TARGET_LINK_LIBRARIES(utilTest tutil common gtest pthread)
|
TARGET_LINK_LIBRARIES(utilTest tutil common gtest pthread gcov)
|
||||||
ENDIF()
|
ENDIF()
|
|
@ -0,0 +1,474 @@
|
||||||
|
// sample code to verify all TDengine API
|
||||||
|
// to compile: gcc -o apitest apitest.c -ltaos
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <taos.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void prepare_data(TAOS* taos) {
|
||||||
|
taos_query(taos, "drop database if exists test;");
|
||||||
|
usleep(100000);
|
||||||
|
taos_query(taos, "create database test;");
|
||||||
|
usleep(100000);
|
||||||
|
taos_select_db(taos, "test");
|
||||||
|
|
||||||
|
taos_query(taos, "create table meters(ts timestamp, a int) tags(area int);");
|
||||||
|
|
||||||
|
taos_query(taos, "create table t0 using meters tags(0);");
|
||||||
|
taos_query(taos, "create table t1 using meters tags(1);");
|
||||||
|
taos_query(taos, "create table t2 using meters tags(2);");
|
||||||
|
taos_query(taos, "create table t3 using meters tags(3);");
|
||||||
|
taos_query(taos, "create table t4 using meters tags(4);");
|
||||||
|
taos_query(taos, "create table t5 using meters tags(5);");
|
||||||
|
taos_query(taos, "create table t6 using meters tags(6);");
|
||||||
|
taos_query(taos, "create table t7 using meters tags(7);");
|
||||||
|
taos_query(taos, "create table t8 using meters tags(8);");
|
||||||
|
taos_query(taos, "create table t9 using meters tags(9);");
|
||||||
|
|
||||||
|
TAOS_RES* res = taos_query(taos, "insert into t0 values('2020-01-01 00:00:00.000', 0)"
|
||||||
|
" ('2020-01-01 00:01:00.000', 0)"
|
||||||
|
" ('2020-01-01 00:02:00.000', 0)"
|
||||||
|
" t1 values('2020-01-01 00:00:00.000', 0)"
|
||||||
|
" ('2020-01-01 00:01:00.000', 0)"
|
||||||
|
" ('2020-01-01 00:02:00.000', 0)"
|
||||||
|
" ('2020-01-01 00:03:00.000', 0)"
|
||||||
|
" t2 values('2020-01-01 00:00:00.000', 0)"
|
||||||
|
" ('2020-01-01 00:01:00.000', 0)"
|
||||||
|
" ('2020-01-01 00:01:01.000', 0)"
|
||||||
|
" ('2020-01-01 00:01:02.000', 0)"
|
||||||
|
" t3 values('2020-01-01 00:01:02.000', 0)"
|
||||||
|
" t4 values('2020-01-01 00:01:02.000', 0)"
|
||||||
|
" t5 values('2020-01-01 00:01:02.000', 0)"
|
||||||
|
" t6 values('2020-01-01 00:01:02.000', 0)"
|
||||||
|
" t7 values('2020-01-01 00:01:02.000', 0)"
|
||||||
|
" t8 values('2020-01-01 00:01:02.000', 0)"
|
||||||
|
" t9 values('2020-01-01 00:01:02.000', 0)");
|
||||||
|
int affected = taos_affected_rows(res);
|
||||||
|
if (affected != 18) {
|
||||||
|
printf("\033[31m%d rows affected by last insert statement, but it should be 18\033[0m\n", affected);
|
||||||
|
}
|
||||||
|
// super tables subscription
|
||||||
|
usleep(1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int print_result(TAOS_RES* res, int blockFetch) {
|
||||||
|
TAOS_ROW row = NULL;
|
||||||
|
int num_fields = taos_num_fields(res);
|
||||||
|
TAOS_FIELD* fields = taos_fetch_fields(res);
|
||||||
|
int nRows = 0;
|
||||||
|
|
||||||
|
if (blockFetch) {
|
||||||
|
int rows = 0;
|
||||||
|
while ((rows = taos_fetch_block(res, &row))) {
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
char temp[256];
|
||||||
|
taos_print_row(temp, row + i, fields, num_fields);
|
||||||
|
puts(temp);
|
||||||
|
}
|
||||||
|
nRows += rows;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while ((row = taos_fetch_row(res))) {
|
||||||
|
char temp[256];
|
||||||
|
taos_print_row(temp, row, fields, num_fields);
|
||||||
|
puts(temp);
|
||||||
|
nRows++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%d rows consumed.\n", nRows);
|
||||||
|
return nRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void check_row_count(int line, TAOS_RES* res, int expected) {
|
||||||
|
int actual = print_result(res, expected % 2);
|
||||||
|
if (actual != expected) {
|
||||||
|
printf("\033[31mline %d: row count mismatch, expected: %d, actual: %d\033[0m\n", line, expected, actual);
|
||||||
|
} else {
|
||||||
|
printf("line %d: %d rows consumed as expected\n", line, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void verify_query(TAOS* taos) {
|
||||||
|
prepare_data(taos);
|
||||||
|
|
||||||
|
int code = taos_load_table_info(taos, "t0,t1,t2,t3,t4,t5,t6,t7,t8,t9");
|
||||||
|
if (code != 0) {
|
||||||
|
printf("\033[31mfailed to load table info: 0x%08x\033[0m\n", code);
|
||||||
|
}
|
||||||
|
|
||||||
|
code = taos_validate_sql(taos, "select * from nonexisttable");
|
||||||
|
if (code == 0) {
|
||||||
|
printf("\033[31mimpossible, the table does not exists\033[0m\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
code = taos_validate_sql(taos, "select * from meters");
|
||||||
|
if (code != 0) {
|
||||||
|
printf("\033[31mimpossible, the table does exists: 0x%08x\033[0m\n", code);
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_RES* res = taos_query(taos, "select * from meters");
|
||||||
|
check_row_count(__LINE__, res, 18);
|
||||||
|
printf("result precision is: %d\n", taos_result_precision(res));
|
||||||
|
int c = taos_field_count(res);
|
||||||
|
printf("field count is: %d\n", c);
|
||||||
|
int* lengths = taos_fetch_lengths(res);
|
||||||
|
for (int i = 0; i < c; i++) {
|
||||||
|
printf("length of column %d is %d\n", i, lengths[i]);
|
||||||
|
}
|
||||||
|
taos_free_result(res);
|
||||||
|
|
||||||
|
res = taos_query(taos, "select * from t0");
|
||||||
|
check_row_count(__LINE__, res, 3);
|
||||||
|
taos_free_result(res);
|
||||||
|
|
||||||
|
res = taos_query(taos, "select * from nonexisttable");
|
||||||
|
code = taos_errno(res);
|
||||||
|
printf("code=%d, error msg=%s\n", code, taos_errstr(res));
|
||||||
|
taos_free_result(res);
|
||||||
|
|
||||||
|
res = taos_query(taos, "select * from meters");
|
||||||
|
taos_stop_query(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void subscribe_callback(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code) {
|
||||||
|
int rows = print_result(res, *(int*)param);
|
||||||
|
printf("%d rows consumed in subscribe_callback\n", rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void verify_subscribe(TAOS* taos) {
|
||||||
|
prepare_data(taos);
|
||||||
|
|
||||||
|
TAOS_SUB* tsub = taos_subscribe(taos, 0, "test", "select * from meters;", NULL, NULL, 0);
|
||||||
|
TAOS_RES* res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 18);
|
||||||
|
|
||||||
|
res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 0);
|
||||||
|
|
||||||
|
taos_query(taos, "insert into t0 values('2020-01-01 00:02:00.001', 0);");
|
||||||
|
taos_query(taos, "insert into t8 values('2020-01-01 00:01:03.000', 0);");
|
||||||
|
res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 2);
|
||||||
|
|
||||||
|
taos_query(taos, "insert into t2 values('2020-01-01 00:01:02.001', 0);");
|
||||||
|
taos_query(taos, "insert into t1 values('2020-01-01 00:03:00.001', 0);");
|
||||||
|
res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 2);
|
||||||
|
|
||||||
|
taos_query(taos, "insert into t1 values('2020-01-01 00:03:00.002', 0);");
|
||||||
|
res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 1);
|
||||||
|
|
||||||
|
// keep progress information and restart subscription
|
||||||
|
taos_unsubscribe(tsub, 1);
|
||||||
|
taos_query(taos, "insert into t0 values('2020-01-01 00:04:00.000', 0);");
|
||||||
|
tsub = taos_subscribe(taos, 1, "test", "select * from meters;", NULL, NULL, 0);
|
||||||
|
res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 24);
|
||||||
|
|
||||||
|
// keep progress information and continue previous subscription
|
||||||
|
taos_unsubscribe(tsub, 1);
|
||||||
|
tsub = taos_subscribe(taos, 0, "test", "select * from meters;", NULL, NULL, 0);
|
||||||
|
res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 0);
|
||||||
|
|
||||||
|
// don't keep progress information and continue previous subscription
|
||||||
|
taos_unsubscribe(tsub, 0);
|
||||||
|
tsub = taos_subscribe(taos, 0, "test", "select * from meters;", NULL, NULL, 0);
|
||||||
|
res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 24);
|
||||||
|
|
||||||
|
// single meter subscription
|
||||||
|
|
||||||
|
taos_unsubscribe(tsub, 0);
|
||||||
|
tsub = taos_subscribe(taos, 0, "test", "select * from t0;", NULL, NULL, 0);
|
||||||
|
res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 5);
|
||||||
|
|
||||||
|
res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 0);
|
||||||
|
|
||||||
|
taos_query(taos, "insert into t0 values('2020-01-01 00:04:00.001', 0);");
|
||||||
|
res = taos_consume(tsub);
|
||||||
|
check_row_count(__LINE__, res, 1);
|
||||||
|
|
||||||
|
taos_unsubscribe(tsub, 0);
|
||||||
|
|
||||||
|
int blockFetch = 0;
|
||||||
|
tsub = taos_subscribe(taos, 1, "test", "select * from meters;", subscribe_callback, &blockFetch, 1000);
|
||||||
|
usleep(2000000);
|
||||||
|
taos_query(taos, "insert into t0 values('2020-01-01 00:05:00.001', 0);");
|
||||||
|
usleep(2000000);
|
||||||
|
taos_unsubscribe(tsub, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void verify_prepare(TAOS* taos) {
|
||||||
|
TAOS_RES* result = taos_query(taos, "drop database if exists test;");
|
||||||
|
usleep(100000);
|
||||||
|
taos_query(taos, "create database test;");
|
||||||
|
|
||||||
|
int code = taos_errno(result);
|
||||||
|
if (code != 0) {
|
||||||
|
printf("\033[31mfailed to create database, reason:%s\033[0m\n", taos_errstr(result));
|
||||||
|
taos_free_result(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
taos_free_result(result);
|
||||||
|
|
||||||
|
usleep(100000);
|
||||||
|
taos_select_db(taos, "test");
|
||||||
|
|
||||||
|
// create table
|
||||||
|
const char* sql = "create table m1 (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10))";
|
||||||
|
result = taos_query(taos, sql);
|
||||||
|
code = taos_errno(result);
|
||||||
|
if (code != 0) {
|
||||||
|
printf("\033[31mfailed to create table, reason:%s\033[0m\n", taos_errstr(result));
|
||||||
|
taos_free_result(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
taos_free_result(result);
|
||||||
|
|
||||||
|
// insert 10 records
|
||||||
|
struct {
|
||||||
|
int64_t ts;
|
||||||
|
int8_t b;
|
||||||
|
int8_t v1;
|
||||||
|
int16_t v2;
|
||||||
|
int32_t v4;
|
||||||
|
int64_t v8;
|
||||||
|
float f4;
|
||||||
|
double f8;
|
||||||
|
char bin[40];
|
||||||
|
char blob[80];
|
||||||
|
} v = {0};
|
||||||
|
|
||||||
|
TAOS_STMT* stmt = taos_stmt_init(taos);
|
||||||
|
TAOS_BIND params[10];
|
||||||
|
params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||||
|
params[0].buffer_length = sizeof(v.ts);
|
||||||
|
params[0].buffer = &v.ts;
|
||||||
|
params[0].length = ¶ms[0].buffer_length;
|
||||||
|
params[0].is_null = NULL;
|
||||||
|
|
||||||
|
params[1].buffer_type = TSDB_DATA_TYPE_BOOL;
|
||||||
|
params[1].buffer_length = sizeof(v.b);
|
||||||
|
params[1].buffer = &v.b;
|
||||||
|
params[1].length = ¶ms[1].buffer_length;
|
||||||
|
params[1].is_null = NULL;
|
||||||
|
|
||||||
|
params[2].buffer_type = TSDB_DATA_TYPE_TINYINT;
|
||||||
|
params[2].buffer_length = sizeof(v.v1);
|
||||||
|
params[2].buffer = &v.v1;
|
||||||
|
params[2].length = ¶ms[2].buffer_length;
|
||||||
|
params[2].is_null = NULL;
|
||||||
|
|
||||||
|
params[3].buffer_type = TSDB_DATA_TYPE_SMALLINT;
|
||||||
|
params[3].buffer_length = sizeof(v.v2);
|
||||||
|
params[3].buffer = &v.v2;
|
||||||
|
params[3].length = ¶ms[3].buffer_length;
|
||||||
|
params[3].is_null = NULL;
|
||||||
|
|
||||||
|
params[4].buffer_type = TSDB_DATA_TYPE_INT;
|
||||||
|
params[4].buffer_length = sizeof(v.v4);
|
||||||
|
params[4].buffer = &v.v4;
|
||||||
|
params[4].length = ¶ms[4].buffer_length;
|
||||||
|
params[4].is_null = NULL;
|
||||||
|
|
||||||
|
params[5].buffer_type = TSDB_DATA_TYPE_BIGINT;
|
||||||
|
params[5].buffer_length = sizeof(v.v8);
|
||||||
|
params[5].buffer = &v.v8;
|
||||||
|
params[5].length = ¶ms[5].buffer_length;
|
||||||
|
params[5].is_null = NULL;
|
||||||
|
|
||||||
|
params[6].buffer_type = TSDB_DATA_TYPE_FLOAT;
|
||||||
|
params[6].buffer_length = sizeof(v.f4);
|
||||||
|
params[6].buffer = &v.f4;
|
||||||
|
params[6].length = ¶ms[6].buffer_length;
|
||||||
|
params[6].is_null = NULL;
|
||||||
|
|
||||||
|
params[7].buffer_type = TSDB_DATA_TYPE_DOUBLE;
|
||||||
|
params[7].buffer_length = sizeof(v.f8);
|
||||||
|
params[7].buffer = &v.f8;
|
||||||
|
params[7].length = ¶ms[7].buffer_length;
|
||||||
|
params[7].is_null = NULL;
|
||||||
|
|
||||||
|
params[8].buffer_type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
params[8].buffer_length = sizeof(v.bin);
|
||||||
|
params[8].buffer = v.bin;
|
||||||
|
params[8].length = ¶ms[8].buffer_length;
|
||||||
|
params[8].is_null = NULL;
|
||||||
|
|
||||||
|
strcpy(v.blob, "一二三四五六七八九十");
|
||||||
|
params[9].buffer_type = TSDB_DATA_TYPE_NCHAR;
|
||||||
|
params[9].buffer_length = strlen(v.blob);
|
||||||
|
params[9].buffer = v.blob;
|
||||||
|
params[9].length = ¶ms[9].buffer_length;
|
||||||
|
params[9].is_null = NULL;
|
||||||
|
|
||||||
|
int is_null = 1;
|
||||||
|
|
||||||
|
sql = "insert into m1 values(?,?,?,?,?,?,?,?,?,?)";
|
||||||
|
code = taos_stmt_prepare(stmt, sql, 0);
|
||||||
|
if (code != 0){
|
||||||
|
printf("\033[31mfailed to execute taos_stmt_prepare. code:0x%x\033[0m\n", code);
|
||||||
|
}
|
||||||
|
v.ts = 1591060628000;
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
v.ts += 1;
|
||||||
|
for (int j = 1; j < 10; ++j) {
|
||||||
|
params[j].is_null = ((i == j) ? &is_null : 0);
|
||||||
|
}
|
||||||
|
v.b = (int8_t)i % 2;
|
||||||
|
v.v1 = (int8_t)i;
|
||||||
|
v.v2 = (int16_t)(i * 2);
|
||||||
|
v.v4 = (int32_t)(i * 4);
|
||||||
|
v.v8 = (int64_t)(i * 8);
|
||||||
|
v.f4 = (float)(i * 40);
|
||||||
|
v.f8 = (double)(i * 80);
|
||||||
|
for (int j = 0; j < sizeof(v.bin) - 1; ++j) {
|
||||||
|
v.bin[j] = (char)(i + '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
taos_stmt_bind_param(stmt, params);
|
||||||
|
taos_stmt_add_batch(stmt);
|
||||||
|
}
|
||||||
|
if (taos_stmt_execute(stmt) != 0) {
|
||||||
|
printf("\033[31mfailed to execute insert statement.\033[0m\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
taos_stmt_close(stmt);
|
||||||
|
|
||||||
|
// query the records
|
||||||
|
stmt = taos_stmt_init(taos);
|
||||||
|
taos_stmt_prepare(stmt, "SELECT * FROM m1 WHERE v1 > ? AND v2 < ?", 0);
|
||||||
|
v.v1 = 5;
|
||||||
|
v.v2 = 15;
|
||||||
|
taos_stmt_bind_param(stmt, params + 2);
|
||||||
|
if (taos_stmt_execute(stmt) != 0) {
|
||||||
|
printf("\033[31mfailed to execute select statement.\033[0m\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = taos_stmt_use_result(stmt);
|
||||||
|
|
||||||
|
TAOS_ROW row;
|
||||||
|
int rows = 0;
|
||||||
|
int num_fields = taos_num_fields(result);
|
||||||
|
TAOS_FIELD *fields = taos_fetch_fields(result);
|
||||||
|
char temp[256];
|
||||||
|
|
||||||
|
// fetch the records row by row
|
||||||
|
while ((row = taos_fetch_row(result))) {
|
||||||
|
rows++;
|
||||||
|
taos_print_row(temp, row, fields, num_fields);
|
||||||
|
printf("%s\n", temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
taos_free_result(result);
|
||||||
|
taos_stmt_close(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void retrieve_callback(void *param, TAOS_RES *tres, int numOfRows)
|
||||||
|
{
|
||||||
|
if (numOfRows > 0) {
|
||||||
|
printf("%d rows async retrieved\n", numOfRows);
|
||||||
|
taos_fetch_rows_a(tres, retrieve_callback, param);
|
||||||
|
} else {
|
||||||
|
if (numOfRows < 0) {
|
||||||
|
printf("\033[31masync retrieve failed, code: %d\033[0m\n", numOfRows);
|
||||||
|
} else {
|
||||||
|
printf("async retrieve completed\n");
|
||||||
|
}
|
||||||
|
taos_free_result(tres);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void select_callback(void *param, TAOS_RES *tres, int code)
|
||||||
|
{
|
||||||
|
if (code == 0 && tres) {
|
||||||
|
taos_fetch_rows_a(tres, retrieve_callback, param);
|
||||||
|
} else {
|
||||||
|
printf("\033[31masync select failed, code: %d\033[0m\n", code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void verify_async(TAOS* taos) {
|
||||||
|
prepare_data(taos);
|
||||||
|
taos_query_a(taos, "select * from meters", select_callback, NULL);
|
||||||
|
usleep(1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stream_callback(void *param, TAOS_RES *res, TAOS_ROW row) {
|
||||||
|
int num_fields = taos_num_fields(res);
|
||||||
|
TAOS_FIELD* fields = taos_fetch_fields(res);
|
||||||
|
|
||||||
|
printf("got one row from stream_callback\n");
|
||||||
|
char temp[256];
|
||||||
|
taos_print_row(temp, row, fields, num_fields);
|
||||||
|
puts(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void verify_stream(TAOS* taos) {
|
||||||
|
prepare_data(taos);
|
||||||
|
TAOS_STREAM* strm = taos_open_stream(
|
||||||
|
taos,
|
||||||
|
"select count(*) from meters interval(1m)",
|
||||||
|
stream_callback,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
printf("waiting for stream data\n");
|
||||||
|
usleep(100000);
|
||||||
|
taos_query(taos, "insert into t0 values(now, 0)(now+5s,1)(now+10s, 2);");
|
||||||
|
usleep(200000000);
|
||||||
|
taos_close_stream(strm);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
const char* host = "127.0.0.1";
|
||||||
|
const char* user = "root";
|
||||||
|
const char* passwd = "taosdata";
|
||||||
|
|
||||||
|
taos_options(TSDB_OPTION_TIMEZONE, "GMT-8");
|
||||||
|
taos_init();
|
||||||
|
|
||||||
|
TAOS* taos = taos_connect(host, user, passwd, "", 0);
|
||||||
|
if (taos == NULL) {
|
||||||
|
printf("\033[31mfailed to connect to db, reason:%s\033[0m\n", taos_errstr(taos));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* info = taos_get_server_info(taos);
|
||||||
|
printf("server info: %s\n", info);
|
||||||
|
info = taos_get_client_info(taos);
|
||||||
|
printf("client info: %s\n", info);
|
||||||
|
|
||||||
|
printf("************ verify query *************\n");
|
||||||
|
verify_query(taos);
|
||||||
|
|
||||||
|
printf("********* verify async query **********\n");
|
||||||
|
verify_async(taos);
|
||||||
|
|
||||||
|
printf("*********** verify subscribe ************\n");
|
||||||
|
verify_subscribe(taos);
|
||||||
|
|
||||||
|
printf("************ verify prepare *************\n");
|
||||||
|
verify_prepare(taos);
|
||||||
|
|
||||||
|
printf("************ verify stream *************\n");
|
||||||
|
verify_stream(taos);
|
||||||
|
printf("done\n");
|
||||||
|
|
||||||
|
taos_close(taos);
|
||||||
|
taos_cleanup();
|
||||||
|
}
|
|
@ -4,7 +4,6 @@
|
||||||
ROOT=./
|
ROOT=./
|
||||||
TARGET=exe
|
TARGET=exe
|
||||||
LFLAGS = '-Wl,-rpath,/usr/local/taos/driver/' -ltaos -lpthread -lm -lrt
|
LFLAGS = '-Wl,-rpath,/usr/local/taos/driver/' -ltaos -lpthread -lm -lrt
|
||||||
#LFLAGS = '-Wl,-rpath,/home/zbm/project/td/debug/build/lib/' -L/home/zbm/project/td/debug/build/lib -ltaos -lpthread -lm -lrt
|
|
||||||
CFLAGS = -O3 -g -Wall -Wno-deprecated -fPIC -Wno-unused-result -Wconversion -Wno-char-subscripts -D_REENTRANT -Wno-format -D_REENTRANT -DLINUX -msse4.2 -Wno-unused-function -D_M_X64 \
|
CFLAGS = -O3 -g -Wall -Wno-deprecated -fPIC -Wno-unused-result -Wconversion -Wno-char-subscripts -D_REENTRANT -Wno-format -D_REENTRANT -DLINUX -msse4.2 -Wno-unused-function -D_M_X64 \
|
||||||
-I/usr/local/taos/include -std=gnu99
|
-I/usr/local/taos/include -std=gnu99
|
||||||
|
|
||||||
|
@ -16,6 +15,7 @@ exe:
|
||||||
gcc $(CFLAGS) ./prepare.c -o $(ROOT)/prepare $(LFLAGS)
|
gcc $(CFLAGS) ./prepare.c -o $(ROOT)/prepare $(LFLAGS)
|
||||||
gcc $(CFLAGS) ./stream.c -o $(ROOT)/stream $(LFLAGS)
|
gcc $(CFLAGS) ./stream.c -o $(ROOT)/stream $(LFLAGS)
|
||||||
gcc $(CFLAGS) ./subscribe.c -o $(ROOT)subscribe $(LFLAGS)
|
gcc $(CFLAGS) ./subscribe.c -o $(ROOT)subscribe $(LFLAGS)
|
||||||
|
gcc $(CFLAGS) ./apitest.c -o $(ROOT)apitest $(LFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm $(ROOT)/asyncdemo
|
rm $(ROOT)/asyncdemo
|
||||||
|
|
|
@ -29,7 +29,7 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
# Create a database named db
|
# Create a database named db
|
||||||
try:
|
try:
|
||||||
c1.execute('create database db')
|
c1.execute('create database if not exists db ')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
conn.close()
|
conn.close()
|
||||||
raise(err)
|
raise(err)
|
||||||
|
|
|
@ -30,17 +30,12 @@ class TDTestCase:
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
intData = []
|
|
||||||
floatData = []
|
|
||||||
|
|
||||||
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
||||||
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
||||||
tdSql.execute("create table test1 using test tags('beijing')")
|
tdSql.execute("create table test1 using test tags('beijing')")
|
||||||
for i in range(self.rowNum):
|
for i in range(self.rowNum):
|
||||||
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
||||||
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
||||||
intData.append(i + 1)
|
|
||||||
floatData.append(i + 0.1)
|
|
||||||
|
|
||||||
# bottom verifacation
|
# bottom verifacation
|
||||||
tdSql.error("select bottom(ts, 10) from test")
|
tdSql.error("select bottom(ts, 10) from test")
|
||||||
|
|
|
@ -30,17 +30,12 @@ class TDTestCase:
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
intData = []
|
|
||||||
floatData = []
|
|
||||||
|
|
||||||
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
||||||
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
||||||
tdSql.execute("create table test1 using test tags('beijing')")
|
tdSql.execute("create table test1 using test tags('beijing')")
|
||||||
for i in range(self.rowNum):
|
for i in range(self.rowNum):
|
||||||
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
||||||
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
||||||
intData.append(i + 1)
|
|
||||||
floatData.append(i + 0.1)
|
|
||||||
|
|
||||||
# Count verifacation
|
# Count verifacation
|
||||||
tdSql.query("select count(*) from test")
|
tdSql.query("select count(*) from test")
|
||||||
|
|
|
@ -30,13 +30,12 @@ class TDTestCase:
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
intData = []
|
|
||||||
floatData = []
|
|
||||||
|
|
||||||
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
||||||
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
||||||
tdSql.execute("create table test1 using test tags('beijing')")
|
tdSql.execute("create table test1 using test tags('beijing')")
|
||||||
tdSql.execute("insert into test1 values(%d, 0, 0, 0, 0, 0.0, 0.0, False, ' ', ' ')" % (self.ts - 1))
|
tdSql.execute("insert into test1 values(%d, 0, 0, 0, 0, 0.0, 0.0, False, ' ', ' ')" % (self.ts - 1))
|
||||||
|
|
||||||
|
# diff verifacation
|
||||||
tdSql.query("select diff(col1) from test1")
|
tdSql.query("select diff(col1) from test1")
|
||||||
tdSql.checkRows(0)
|
tdSql.checkRows(0)
|
||||||
|
|
||||||
|
@ -58,10 +57,7 @@ class TDTestCase:
|
||||||
for i in range(self.rowNum):
|
for i in range(self.rowNum):
|
||||||
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
||||||
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
||||||
intData.append(i + 1)
|
|
||||||
floatData.append(i + 0.1)
|
|
||||||
|
|
||||||
# diff verifacation
|
|
||||||
tdSql.error("select diff(ts) from test")
|
tdSql.error("select diff(ts) from test")
|
||||||
tdSql.error("select diff(ts) from test1")
|
tdSql.error("select diff(ts) from test1")
|
||||||
tdSql.error("select diff(col1) from test")
|
tdSql.error("select diff(col1) from test")
|
||||||
|
|
|
@ -30,9 +30,6 @@ class TDTestCase:
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
intData = []
|
|
||||||
floatData = []
|
|
||||||
|
|
||||||
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
||||||
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
||||||
tdSql.execute("create table test1 using test tags('beijing')")
|
tdSql.execute("create table test1 using test tags('beijing')")
|
||||||
|
@ -73,8 +70,6 @@ class TDTestCase:
|
||||||
for i in range(self.rowNum):
|
for i in range(self.rowNum):
|
||||||
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
||||||
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
||||||
intData.append(i + 1)
|
|
||||||
floatData.append(i + 0.1)
|
|
||||||
|
|
||||||
tdSql.query("select first(*) from test1")
|
tdSql.query("select first(*) from test1")
|
||||||
tdSql.checkRows(1)
|
tdSql.checkRows(1)
|
||||||
|
|
|
@ -30,15 +30,12 @@ class TDTestCase:
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
intData = []
|
|
||||||
floatData = []
|
|
||||||
|
|
||||||
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
||||||
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
||||||
tdSql.execute("create table test1 using test tags('beijing')")
|
tdSql.execute("create table test1 using test tags('beijing')")
|
||||||
tdSql.execute("insert into test1(ts) values(%d)" % (self.ts - 1))
|
tdSql.execute("insert into test1(ts) values(%d)" % (self.ts - 1))
|
||||||
|
|
||||||
# first verifacation
|
# last verifacation
|
||||||
tdSql.query("select last(*) from test1")
|
tdSql.query("select last(*) from test1")
|
||||||
tdSql.checkRows(1)
|
tdSql.checkRows(1)
|
||||||
tdSql.checkData(0, 1, None)
|
tdSql.checkData(0, 1, None)
|
||||||
|
@ -73,8 +70,6 @@ class TDTestCase:
|
||||||
for i in range(self.rowNum):
|
for i in range(self.rowNum):
|
||||||
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
||||||
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
||||||
intData.append(i + 1)
|
|
||||||
floatData.append(i + 0.1)
|
|
||||||
|
|
||||||
tdSql.query("select last(*) from test1")
|
tdSql.query("select last(*) from test1")
|
||||||
tdSql.checkRows(1)
|
tdSql.checkRows(1)
|
||||||
|
|
|
@ -30,15 +30,12 @@ class TDTestCase:
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
intData = []
|
|
||||||
floatData = []
|
|
||||||
|
|
||||||
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
||||||
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
||||||
tdSql.execute("create table test1 using test tags('beijing')")
|
tdSql.execute("create table test1 using test tags('beijing')")
|
||||||
tdSql.execute("insert into test1(ts) values(%d)" % (self.ts - 1))
|
tdSql.execute("insert into test1(ts) values(%d)" % (self.ts - 1))
|
||||||
|
|
||||||
# first verifacation
|
# last_row verifacation
|
||||||
tdSql.query("select last_row(*) from test1")
|
tdSql.query("select last_row(*) from test1")
|
||||||
tdSql.checkRows(1)
|
tdSql.checkRows(1)
|
||||||
tdSql.checkData(0, 1, None)
|
tdSql.checkData(0, 1, None)
|
||||||
|
@ -82,8 +79,6 @@ class TDTestCase:
|
||||||
for i in range(self.rowNum):
|
for i in range(self.rowNum):
|
||||||
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
||||||
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
||||||
intData.append(i + 1)
|
|
||||||
floatData.append(i + 0.1)
|
|
||||||
|
|
||||||
tdSql.query("select last_row(*) from test1")
|
tdSql.query("select last_row(*) from test1")
|
||||||
tdSql.checkRows(1)
|
tdSql.checkRows(1)
|
||||||
|
|
|
@ -30,17 +30,12 @@ class TDTestCase:
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
intData = []
|
|
||||||
floatData = []
|
|
||||||
|
|
||||||
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
||||||
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
||||||
tdSql.execute("create table test1 using test tags('beijing')")
|
tdSql.execute("create table test1 using test tags('beijing')")
|
||||||
for i in range(self.rowNum):
|
for i in range(self.rowNum):
|
||||||
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
||||||
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
||||||
intData.append(i + 1)
|
|
||||||
floatData.append(i + 0.1)
|
|
||||||
|
|
||||||
# leastsquares verifacation
|
# leastsquares verifacation
|
||||||
tdSql.error("select leastsquares(ts, 1, 1) from test1")
|
tdSql.error("select leastsquares(ts, 1, 1) from test1")
|
||||||
|
@ -72,8 +67,6 @@ class TDTestCase:
|
||||||
tdSql.query("select leastsquares(col6, 1, 1) from test1")
|
tdSql.query("select leastsquares(col6, 1, 1) from test1")
|
||||||
tdSql.checkData(0, 0, '{slop:1.000000, intercept:-0.900000}')
|
tdSql.checkData(0, 0, '{slop:1.000000, intercept:-0.900000}')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
tdSql.close()
|
tdSql.close()
|
||||||
tdLog.success("%s successfully executed" % __file__)
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
|
@ -42,7 +42,7 @@ class TDTestCase:
|
||||||
intData.append(i + 1)
|
intData.append(i + 1)
|
||||||
floatData.append(i + 0.1)
|
floatData.append(i + 0.1)
|
||||||
|
|
||||||
# min verifacation
|
# max verifacation
|
||||||
tdSql.error("select max(ts) from test")
|
tdSql.error("select max(ts) from test")
|
||||||
tdSql.error("select max(ts) from test1")
|
tdSql.error("select max(ts) from test1")
|
||||||
tdSql.error("select max(col7) from test")
|
tdSql.error("select max(col7) from test")
|
||||||
|
|
|
@ -30,17 +30,12 @@ class TDTestCase:
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
intData = []
|
|
||||||
floatData = []
|
|
||||||
|
|
||||||
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
||||||
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
||||||
tdSql.execute("create table test1 using test tags('beijing')")
|
tdSql.execute("create table test1 using test tags('beijing')")
|
||||||
for i in range(self.rowNum):
|
for i in range(self.rowNum):
|
||||||
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
||||||
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
||||||
intData.append(i + 1)
|
|
||||||
floatData.append(i + 0.1)
|
|
||||||
|
|
||||||
# min verifacation
|
# min verifacation
|
||||||
tdSql.error("select ts + col1 from test")
|
tdSql.error("select ts + col1 from test")
|
||||||
|
|
|
@ -30,9 +30,6 @@ class TDTestCase:
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
intData = []
|
|
||||||
floatData = []
|
|
||||||
|
|
||||||
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double,
|
||||||
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
col7 bool, col8 binary(20), col9 nchar(20)) tags(loc nchar(20))''')
|
||||||
tdSql.execute("create table test1 using test tags('beijing')")
|
tdSql.execute("create table test1 using test tags('beijing')")
|
||||||
|
@ -69,8 +66,6 @@ class TDTestCase:
|
||||||
for i in range(self.rowNum):
|
for i in range(self.rowNum):
|
||||||
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')"
|
||||||
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
% (self.ts + i, i + 1, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1))
|
||||||
intData.append(i + 1)
|
|
||||||
floatData.append(i + 0.1)
|
|
||||||
|
|
||||||
tdSql.error("select spread(col7) from test")
|
tdSql.error("select spread(col7) from test")
|
||||||
tdSql.error("select spread(col7) from test1")
|
tdSql.error("select spread(col7) from test1")
|
||||||
|
|
|
@ -57,8 +57,7 @@ class TDTestCase:
|
||||||
tdSql.query("select sum(col4) from test")
|
tdSql.query("select sum(col4) from test")
|
||||||
tdSql.checkData(0, 0, np.sum(intData))
|
tdSql.checkData(0, 0, np.sum(intData))
|
||||||
tdSql.query("select sum(col5) from test")
|
tdSql.query("select sum(col5) from test")
|
||||||
print("query result for folat sum function: %f" % tdSql.getData(0, 0))
|
tdSql.checkData(0, 0, np.sum(floatData))
|
||||||
print("calculation result for numpy sum function: %f" % np.sum(floatData))
|
|
||||||
tdSql.query("select sum(col6) from test")
|
tdSql.query("select sum(col6) from test")
|
||||||
tdSql.checkData(0, 0, np.sum(floatData))
|
tdSql.checkData(0, 0, np.sum(floatData))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue