[tbase-1282]
This commit is contained in:
parent
952cbdb2d6
commit
2f9d055696
|
@ -95,6 +95,8 @@ SMeterSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx);
|
|||
bool tscIsPointInterpQuery(SSqlCmd* pCmd);
|
||||
bool tscIsTWAQuery(SSqlCmd* pCmd);
|
||||
bool tscProjectionQueryOnMetric(SSqlCmd* pCmd);
|
||||
bool tscProjectionQueryOnTable(SSqlCmd* pCmd);
|
||||
|
||||
bool tscIsTwoStageMergeMetricQuery(SSqlCmd* pCmd);
|
||||
bool tscQueryOnMetric(SSqlCmd* pCmd);
|
||||
bool tscQueryMetricTags(SSqlCmd* pCmd);
|
||||
|
|
|
@ -477,6 +477,8 @@ void tscProcessMultiVnodesInsertForFile(SSqlObj *pSql);
|
|||
void tscKillMetricQuery(SSqlObj *pSql);
|
||||
void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen);
|
||||
bool tscIsUpdateQuery(STscObj *pObj);
|
||||
bool tscHasReachLimitation(SSqlObj* pSql);
|
||||
|
||||
int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql);
|
||||
|
||||
// transfer SSqlInfo to SqlCmd struct
|
||||
|
|
|
@ -112,8 +112,9 @@ static tSQLSyntaxNode *tSQLSyntaxNodeCreate(SSchema *pSchema, int32_t numOfCols,
|
|||
tSQLSyntaxNode *pNode = NULL;
|
||||
|
||||
if (pToken->type == TK_ID || pToken->type == TK_TBNAME) {
|
||||
if (pToken->type == TK_ID) {
|
||||
int32_t i = 0;
|
||||
|
||||
if (pToken->type == TK_ID) {
|
||||
do {
|
||||
size_t len = strlen(pSchema[i].name);
|
||||
if (strncmp(pToken->z, pSchema[i].name, pToken->n) == 0 && pToken->n == len) break;
|
||||
|
@ -326,8 +327,8 @@ static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, cha
|
|||
uint8_t localOptr = getBinaryExprOptr(&t0);
|
||||
if (localOptr == 0) {
|
||||
pError("not support binary operator:%d", t0.type);
|
||||
free(pBinExpr);
|
||||
return NULL;
|
||||
free(pBinExpr)
|
||||
}
|
||||
|
||||
return parseRemainStr(str, pBinExpr, pSchema, localOptr, numOfCols, i);
|
||||
|
@ -652,7 +653,6 @@ void tSQLListTraverseOnResult(struct tSQLBinaryExpr *pExpr, bool (*fp)(tSkipList
|
|||
// brutal force search
|
||||
int64_t num = pResult->num;
|
||||
for (int32_t i = 0, j = 0; i < pResult->num; ++i) {
|
||||
//if (fp == NULL || (fp != NULL && fp(pResult->pRes[i], pExpr->info) == true)) {
|
||||
if (fp == NULL || (fp(pResult->pRes[i], pExpr->info) == true)) {
|
||||
pResult->pRes[j++] = pResult->pRes[i];
|
||||
} else {
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tscJoinProcess.h"
|
||||
#include "os.h"
|
||||
#include "tcache.h"
|
||||
#include "tscJoinProcess.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tsclient.h"
|
||||
#include "tscompression.h"
|
||||
|
@ -45,8 +45,8 @@ static bool doCompare(int32_t order, int64_t left, int64_t right) {
|
|||
}
|
||||
}
|
||||
|
||||
static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSubquerySupporter* pSupporter1, SJoinSubquerySupporter* pSupporter2,
|
||||
TSKEY* st, TSKEY* et) {
|
||||
static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSubquerySupporter* pSupporter1,
|
||||
SJoinSubquerySupporter* pSupporter2, TSKEY* st, TSKEY* et) {
|
||||
STSBuf* output1 = tsBufCreate(true);
|
||||
STSBuf* output2 = tsBufCreate(true);
|
||||
|
||||
|
@ -150,14 +150,15 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSubquerySupporter* pSuppor
|
|||
tsBufDestory(pSupporter1->pTSBuf);
|
||||
tsBufDestory(pSupporter2->pTSBuf);
|
||||
|
||||
tscTrace("%p input1:%lld, input2:%lld, final:%lld for secondary query after ts blocks intersecting",
|
||||
pSql, numOfInput1, numOfInput2, output1->numOfTotal);
|
||||
tscTrace("%p input1:%lld, input2:%lld, final:%lld for secondary query after ts blocks intersecting", pSql,
|
||||
numOfInput1, numOfInput2, output1->numOfTotal);
|
||||
|
||||
return output1->numOfTotal;
|
||||
}
|
||||
|
||||
//todo handle failed to create sub query
|
||||
SJoinSubquerySupporter* tscCreateJoinSupporter(SSqlObj* pSql, SSubqueryState* pState, /*int32_t* numOfComplete, int32_t* gc,*/ int32_t index) {
|
||||
// todo handle failed to create sub query
|
||||
SJoinSubquerySupporter* tscCreateJoinSupporter(SSqlObj* pSql, SSubqueryState* pState,
|
||||
/*int32_t* numOfComplete, int32_t* gc,*/ int32_t index) {
|
||||
SJoinSubquerySupporter* pSupporter = calloc(1, sizeof(SJoinSubquerySupporter));
|
||||
if (pSupporter == NULL) {
|
||||
return NULL;
|
||||
|
@ -241,8 +242,10 @@ int32_t tscLaunchSecondSubquery(SSqlObj* pSql) {
|
|||
}
|
||||
|
||||
// scan all subquery, if one sub query has only ts, ignore it
|
||||
tscTrace("%p start to launch secondary subqueries, total:%d, only:%d needs to query, others are not retrieve in "
|
||||
"select clause", pSql, pSql->numOfSubs, numOfSub);
|
||||
tscTrace(
|
||||
"%p start to launch secondary subqueries, total:%d, only:%d needs to query, others are not retrieve in "
|
||||
"select clause",
|
||||
pSql, pSql->numOfSubs, numOfSub);
|
||||
|
||||
int32_t j = 0;
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
|
@ -258,7 +261,7 @@ int32_t tscLaunchSecondSubquery(SSqlObj* pSql) {
|
|||
|
||||
SSqlObj* pNew = createSubqueryObj(pSql, (int16_t)i, tscJoinQueryCallback, pSupporter, NULL);
|
||||
if (pNew == NULL) {
|
||||
pSql->numOfSubs = i; //revise the number of subquery
|
||||
pSql->numOfSubs = i; // revise the number of subquery
|
||||
pSupporter->pState->numOfTotal = i;
|
||||
|
||||
pSupporter->pState->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
|
@ -420,7 +423,7 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
|
|||
taos_fetch_rows_a(tres, joinRetrieveCallback, param);
|
||||
} else if (numOfRows == 0) { // no data from this vnode anymore
|
||||
if (tscProjectionQueryOnMetric(&pParentSql->cmd)) {
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
assert(pSql->cmd.numOfTables == 1);
|
||||
|
||||
// for projection query, need to try next vnode
|
||||
|
@ -434,7 +437,6 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
|
|||
}
|
||||
|
||||
if (atomic_add_fetch_32(&pSupporter->pState->numOfCompleted, 1) >= pSupporter->pState->numOfTotal) {
|
||||
|
||||
if (pSupporter->pState->code != TSDB_CODE_SUCCESS) {
|
||||
tscTrace("%p sub:%p, numOfSub:%d, quit from further procedure due to other queries failure", pParentSql, tres,
|
||||
pSupporter->subqueryIndex);
|
||||
|
@ -472,13 +474,16 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
|
|||
tscError("%p retrieve failed, code:%d, index:%d", pSql, numOfRows, pSupporter->subqueryIndex);
|
||||
}
|
||||
|
||||
if (numOfRows >= 0) {
|
||||
pSql->res.numOfTotal += pSql->res.numOfRows;
|
||||
}
|
||||
|
||||
if (tscProjectionQueryOnMetric(&pSql->cmd) && numOfRows == 0) {
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
assert(pSql->cmd.numOfTables == 1);
|
||||
|
||||
// for projection query, need to try next vnode if current vnode is exhausted
|
||||
if ((++pMeterMetaInfo->vnodeIndex) < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
|
||||
pSupporter->pState->numOfCompleted = 0;
|
||||
pSupporter->pState->numOfTotal = 1;
|
||||
|
||||
|
@ -512,21 +517,29 @@ void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
|
|||
assert(pSql->numOfSubs >= 1);
|
||||
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
SSqlRes* pRes = &pSql->pSubs[i]->res;
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->pSubs[i]->cmd, 0);
|
||||
SSqlRes *pRes = &pSql->pSubs[i]->res;
|
||||
SSqlCmd *pCmd = &pSql->pSubs[i]->cmd;
|
||||
|
||||
if (UTIL_METER_IS_METRIC(pMeterMetaInfo)) {
|
||||
if (pRes->row >= pRes->numOfRows && pMeterMetaInfo->vnodeIndex < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
|
||||
if (tscProjectionQueryOnMetric(pCmd)) {
|
||||
if (pRes->row >= pRes->numOfRows && pMeterMetaInfo->vnodeIndex < pMeterMetaInfo->pMetricMeta->numOfVnodes &&
|
||||
(!tscHasReachLimitation(pSql->pSubs[i]))) {
|
||||
numOfFetch++;
|
||||
}
|
||||
} else {
|
||||
if (pRes->row >= pRes->numOfRows) {
|
||||
if ((pRes->row >= pRes->numOfRows && (!tscHasReachLimitation(pSql->pSubs[i])) && tscProjectionQueryOnTable(pSql))
|
||||
|| (pRes->numOfRows == 0)) {
|
||||
numOfFetch++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numOfFetch > 0) {
|
||||
if (numOfFetch <= 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
// TODO multi-vnode retrieve for projection query with limitation has bugs, since the global limiation is not handled
|
||||
tscTrace("%p retrieve data from %d subqueries", pSql, numOfFetch);
|
||||
|
||||
SJoinSubquerySupporter* pSupporter = (SJoinSubquerySupporter*)pSql->pSubs[0]->param;
|
||||
|
@ -543,16 +556,15 @@ void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
|
|||
|
||||
// wait for all subqueries completed
|
||||
pSupporter->pState->numOfTotal = numOfFetch;
|
||||
|
||||
assert(pRes1->numOfRows >= 0 && pCmd1->numOfTables == 1);
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd1, 0);
|
||||
|
||||
if (pRes1->row >= pRes1->numOfRows) {
|
||||
tscTrace("%p subquery:%p retrieve data from vnode, subquery:%d, vnodeIndex:%d", pSql, pSql1,
|
||||
pSupporter->subqueryIndex, pMeterMetaInfo->vnodeIndex);
|
||||
|
||||
tscResetForNextRetrieve(pRes1);
|
||||
|
||||
pSql1->fp = joinRetrieveCallback;
|
||||
|
||||
if (pCmd1->command < TSDB_SQL_LOCAL) {
|
||||
|
@ -565,7 +577,6 @@ void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
|
|||
|
||||
// wait for all subquery completed
|
||||
tsem_wait(&pSql->rspSem);
|
||||
}
|
||||
}
|
||||
|
||||
// all subqueries return, set the result output index
|
||||
|
@ -671,7 +682,8 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
|||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
|
||||
/**
|
||||
* if the query is a continue query (vnodeIndex > 0 for projection query) for next vnode, do the retrieval of data instead of returning to its invoker
|
||||
* if the query is a continue query (vnodeIndex > 0 for projection query) for next vnode, do the retrieval of
|
||||
* data instead of returning to its invoker
|
||||
*/
|
||||
if (pMeterMetaInfo->vnodeIndex > 0 && tscProjectionQueryOnMetric(&pSql->cmd)) {
|
||||
assert(pMeterMetaInfo->vnodeIndex < pMeterMetaInfo->pMetricMeta->numOfVnodes);
|
||||
|
@ -864,7 +876,7 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) {
|
|||
struct stat fileStat;
|
||||
fstat(fileno(pTSBuf->f), &fileStat);
|
||||
|
||||
pTSBuf->fileSize = (uint32_t) fileStat.st_size;
|
||||
pTSBuf->fileSize = (uint32_t)fileStat.st_size;
|
||||
tsBufResetPos(pTSBuf);
|
||||
|
||||
// ascending by default
|
||||
|
@ -899,7 +911,6 @@ void tsBufDestory(STSBuf* pTSBuf) {
|
|||
}
|
||||
|
||||
free(pTSBuf);
|
||||
|
||||
}
|
||||
|
||||
static STSVnodeBlockInfoEx* tsBufGetLastVnodeInfo(STSBuf* pTSBuf) {
|
||||
|
@ -944,8 +955,8 @@ static STSVnodeBlockInfoEx* addOneVnodeInfo(STSBuf* pTSBuf, int32_t vnodeId) {
|
|||
pTSBuf->numOfVnodes += 1;
|
||||
|
||||
// update the header info
|
||||
STSBufFileHeader header =
|
||||
{.magic = TS_COMP_FILE_MAGIC, .numOfVnode = pTSBuf->numOfVnodes, .tsOrder = pTSBuf->tsOrder};
|
||||
STSBufFileHeader header = {
|
||||
.magic = TS_COMP_FILE_MAGIC, .numOfVnode = pTSBuf->numOfVnodes, .tsOrder = pTSBuf->tsOrder};
|
||||
|
||||
STSBufUpdateHeader(pTSBuf, &header);
|
||||
return tsBufGetLastVnodeInfo(pTSBuf);
|
||||
|
@ -1397,8 +1408,6 @@ STSElem tsBufGetElem(STSBuf* pTSBuf) {
|
|||
return elem1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* current only support ts comp data from two vnode merge
|
||||
* @param pDestBuf
|
||||
|
@ -1487,12 +1496,12 @@ int32_t tsBufMerge(STSBuf* pDestBuf, const STSBuf* pSrcBuf, int32_t vnodeId) {
|
|||
|
||||
struct stat fileStat;
|
||||
fstat(fileno(pDestBuf->f), &fileStat);
|
||||
pDestBuf->fileSize = (uint32_t) fileStat.st_size;
|
||||
pDestBuf->fileSize = (uint32_t)fileStat.st_size;
|
||||
|
||||
assert(pDestBuf->fileSize == oldSize + size);
|
||||
|
||||
tscTrace("tsBuf merge success, %p, path:%s, fd:%d, file size:%d, numOfVnode:%d, autoDelete:%d", pDestBuf, pDestBuf->path,
|
||||
fileno(pDestBuf->f), pDestBuf->fileSize, pDestBuf->numOfVnodes, pDestBuf->autoDelete);
|
||||
tscTrace("tsBuf merge success, %p, path:%s, fd:%d, file size:%d, numOfVnode:%d, autoDelete:%d", pDestBuf,
|
||||
pDestBuf->path, fileno(pDestBuf->f), pDestBuf->fileSize, pDestBuf->numOfVnodes, pDestBuf->autoDelete);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1510,7 +1519,7 @@ STSBuf* tsBufCreateFromCompBlocks(const char* pData, int32_t numOfBlocks, int32_
|
|||
TSBufUpdateVnodeInfo(pTSBuf, pTSBuf->numOfVnodes - 1, pBlockInfo);
|
||||
|
||||
fseek(pTSBuf->f, pBlockInfo->offset, SEEK_SET);
|
||||
fwrite((void*) pData, 1, len, pTSBuf->f);
|
||||
fwrite((void*)pData, 1, len, pTSBuf->f);
|
||||
pTSBuf->fileSize += len;
|
||||
|
||||
pTSBuf->tsOrder = order;
|
||||
|
|
|
@ -5008,6 +5008,8 @@ int32_t parseLimitClause(SSqlObj* pSql, SQuerySQL* pQuerySql) {
|
|||
|
||||
// handle the limit offset value, validate the limit
|
||||
pCmd->limit = pQuerySql->limit;
|
||||
pCmd->globalLimit = pCmd->limit.limit;
|
||||
|
||||
pCmd->slimit = pQuerySql->slimit;
|
||||
|
||||
if (pCmd->slimit.offset < 0 || pCmd->limit.offset < 0) {
|
||||
|
|
|
@ -16,21 +16,21 @@
|
|||
#include "os.h"
|
||||
#include "tcache.h"
|
||||
#include "tlog.h"
|
||||
#include "tnote.h"
|
||||
#include "trpc.h"
|
||||
#include "tscJoinProcess.h"
|
||||
#include "tscProfile.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "tscSecondaryMerge.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tsclient.h"
|
||||
#include "tscompression.h"
|
||||
#include "tsocket.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
#include "tnote.h"
|
||||
|
||||
TAOS *taos_connect_imp(const char *ip, const char *user, const char *pass, const char *db, uint16_t port, void (*fp)(void *, TAOS_RES *, int),
|
||||
void *param, void **taos) {
|
||||
TAOS *taos_connect_imp(const char *ip, const char *user, const char *pass, const char *db, uint16_t port,
|
||||
void (*fp)(void *, TAOS_RES *, int), void *param, void **taos) {
|
||||
STscObj *pObj;
|
||||
|
||||
taos_init();
|
||||
|
@ -162,7 +162,7 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha
|
|||
|
||||
void *taos = taos_connect_imp(ip, user, pass, db, port, NULL, NULL, NULL);
|
||||
if (taos != NULL) {
|
||||
STscObj* pObj = (STscObj*) taos;
|
||||
STscObj *pObj = (STscObj *)taos;
|
||||
|
||||
// version compare only requires the first 3 segments of the version string
|
||||
int32_t comparedSegments = 3;
|
||||
|
@ -188,7 +188,7 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha
|
|||
return NULL;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < comparedSegments; ++i) {
|
||||
for (int32_t i = 0; i < comparedSegments; ++i) {
|
||||
if (clientVersionNumber[i] != serverVersionNumber[i]) {
|
||||
tscError("taos:%p, the %d-th number of server version:%s not matched with client version:%s, close connection",
|
||||
taos, i, server_version, version);
|
||||
|
@ -225,7 +225,7 @@ void taos_close(TAOS *taos) {
|
|||
}
|
||||
}
|
||||
|
||||
int taos_query_imp(STscObj* pObj, SSqlObj* pSql) {
|
||||
int taos_query_imp(STscObj *pObj, SSqlObj *pSql) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
pRes->numOfRows = 1;
|
||||
|
@ -271,7 +271,8 @@ int taos_query(TAOS *taos, const char *sqlstr) {
|
|||
|
||||
size_t sqlLen = strlen(sqlstr);
|
||||
if (sqlLen > tsMaxSQLStringLen) {
|
||||
pRes->code = tscInvalidSQLErrMsg(pSql->cmd.payload, "sql too long", NULL); // set the additional error msg for invalid sql
|
||||
pRes->code =
|
||||
tscInvalidSQLErrMsg(pSql->cmd.payload, "sql too long", NULL); // set the additional error msg for invalid sql
|
||||
tscError("%p SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(taos), pObj);
|
||||
|
||||
return pRes->code;
|
||||
|
@ -451,59 +452,56 @@ static void **getOneRowFromBuf(SSqlObj *pSql) {
|
|||
return pRes->tsrow;
|
||||
}
|
||||
|
||||
static void **tscJoinResultsetFromBuf(SSqlObj *pSql) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
while (1) {
|
||||
static bool tscHashRemainDataInSubqueryResultSet(SSqlObj *pSql) {
|
||||
bool hasData = true;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
if (tscProjectionQueryOnMetric(pCmd)) {
|
||||
bool allSubqueryExhausted = true;
|
||||
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->pSubs[i]->cmd, 0);
|
||||
if (pMeterMetaInfo->vnodeIndex < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
SSqlRes *pRes1 = &pSql->pSubs[i]->res;
|
||||
SSqlCmd *pCmd1 = &pSql->pSubs[i]->cmd;
|
||||
|
||||
SMeterMetaInfo *pMetaInfo = tscGetMeterMetaInfo(pCmd1, 0);
|
||||
assert(pCmd1->numOfTables == 1);
|
||||
|
||||
/*
|
||||
* if the global limitation is not reached, and current result has not exhausted, or next more vnodes are
|
||||
* available, go on
|
||||
*/
|
||||
if (pMetaInfo->vnodeIndex < pMetaInfo->pMetricMeta->numOfVnodes && pRes1->row < pRes1->numOfRows &&
|
||||
(!tscHasReachLimitation(pSql->pSubs[i]))) {
|
||||
allSubqueryExhausted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hasData = !allSubqueryExhausted;
|
||||
} else { //otherwise, in case inner join, if any subquery exhausted, query completed.
|
||||
} else { // otherwise, in case inner join, if any subquery exhausted, query completed.
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
SSqlRes *pRes1 = &pSql->pSubs[i]->res;
|
||||
if (pRes1->numOfRows == 0) {
|
||||
|
||||
if ((pRes1->row >= pRes1->numOfRows && tscHasReachLimitation(pSql->pSubs[i]) &&
|
||||
tscProjectionQueryOnTable(&pSql->pSubs[i]->cmd)) ||
|
||||
(pRes1->numOfRows == 0)) {
|
||||
|
||||
hasData = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
SSqlRes *pRes1 = &pSql->pSubs[i]->res;
|
||||
SMeterMetaInfo* pMeterMeta = tscGetMeterMetaInfo(&pSql->pSubs[i]->cmd, 0);
|
||||
return hasData;
|
||||
}
|
||||
|
||||
if (tscProjectionQueryOnMetric(pCmd)) {
|
||||
//For multi-vnode projection query, the results may locate in following vnode, so we needs to go on
|
||||
if (pMeterMeta->vnodeIndex < pMeterMeta->pMetricMeta->numOfVnodes) {
|
||||
break;
|
||||
}
|
||||
} else { //otherwise, in case inner join, if any subquery exhausted, query completed.
|
||||
if (pRes1->numOfRows == 0) {
|
||||
hasData = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if (pRes1->numOfRows == 0 && !tscProjectionQueryOnMetric(pCmd) ||
|
||||
// (pMeterMeta->vnodeIndex >= pMeterMeta->pMetricMeta->numOfVnodes && )) {
|
||||
// hasData = false;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
static void **tscJoinResultsetFromBuf(SSqlObj *pSql) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
if (!hasData) { // free all sub sqlobj
|
||||
tscTrace("%p one subquery exhausted, free other %d subquery", pSql, pSql->numOfSubs - 1);
|
||||
while (1) {
|
||||
if (!tscHashRemainDataInSubqueryResultSet(pSql)) { // free all sub sqlobj
|
||||
tscTrace("%p at least one subquery exhausted, free all other %d subqueries", pSql, pSql->numOfSubs - 1);
|
||||
|
||||
SSubqueryState *pState = NULL;
|
||||
|
||||
|
@ -532,14 +530,13 @@ static void **tscJoinResultsetFromBuf(SSqlObj *pSql) {
|
|||
if (pRes1->row < pRes1->numOfRows && pRes2->row < pRes2->numOfRows) {
|
||||
doSetResultRowData(pSql->pSubs[0]);
|
||||
doSetResultRowData(pSql->pSubs[1]);
|
||||
// TSKEY key1 = *(TSKEY *)pRes1->tsrow[0];
|
||||
// TSKEY key2 = *(TSKEY *)pRes2->tsrow[0];
|
||||
// printf("first:%lld, second:%lld\n", key1, key2);
|
||||
// TSKEY key1 = *(TSKEY *)pRes1->tsrow[0];
|
||||
// TSKEY key2 = *(TSKEY *)pRes2->tsrow[0];
|
||||
// printf("first:%lld, second:%lld\n", key1, key2);
|
||||
success = true;
|
||||
pRes1->row++;
|
||||
pRes2->row++;
|
||||
}
|
||||
|
||||
} else { // only one subquery
|
||||
SSqlRes *pRes1 = &pSql->pSubs[0]->res;
|
||||
doSetResultRowData(pSql->pSubs[0]);
|
||||
|
@ -547,7 +544,7 @@ static void **tscJoinResultsetFromBuf(SSqlObj *pSql) {
|
|||
success = (pRes1->row++ < pRes1->numOfRows);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
if (success) { // current row of final output has been built, return to app
|
||||
for (int32_t i = 0; i < pCmd->exprsInfo.numOfExprs; ++i) {
|
||||
int32_t tableIndex = pRes->pColumnIndex[i].tableIndex;
|
||||
int32_t columnIndex = pRes->pColumnIndex[i].columnIndex;
|
||||
|
@ -557,7 +554,7 @@ static void **tscJoinResultsetFromBuf(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
} else { // continue retrieve data from vnode
|
||||
tscFetchDatablockFromSubquery(pSql);
|
||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
|
@ -625,7 +622,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
|||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
|
||||
// reach the maximum number of output rows, abort
|
||||
if (pCmd->globalLimit > 0 && pRes->numOfTotal >= pCmd->globalLimit) {
|
||||
if (tscHasReachLimitation(pSql)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -680,7 +677,7 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
|
|||
nRows = taos_fetch_block_impl(res, rows);
|
||||
while (*rows == NULL && tscProjectionQueryOnMetric(pCmd)) {
|
||||
/* reach the maximum number of output rows, abort */
|
||||
if (pCmd->globalLimit > 0 && pRes->numOfTotal >= pCmd->globalLimit) {
|
||||
if (tscHasReachLimitation(pSql)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -690,7 +687,6 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
|
|||
pCmd->limit.limit = pSql->cmd.globalLimit - pRes->numOfTotal;
|
||||
pCmd->limit.offset = pRes->offset;
|
||||
|
||||
|
||||
if ((++pMeterMetaInfo->vnodeIndex) < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
pSql->cmd.command = TSDB_SQL_SELECT;
|
||||
assert(pSql->fp == NULL);
|
||||
|
@ -925,12 +921,11 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
size_t xlen = strlen(row[i]);
|
||||
size_t trueLen = MIN(xlen, fields[i].bytes);
|
||||
|
||||
memcpy(str + len, (char*) row[i], trueLen);
|
||||
memcpy(str + len, (char *)row[i], trueLen);
|
||||
|
||||
str[len + trueLen] = ' ';
|
||||
len += (trueLen + 1);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
len += sprintf(str + len, "%lld ", *((int64_t *)row[i]));
|
||||
|
@ -987,7 +982,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int tscParseTblNameList(SSqlObj *pSql, const char* tblNameList, int32_t tblListLen) {
|
||||
static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t tblListLen) {
|
||||
// must before clean the sqlcmd object
|
||||
tscRemoveAllMeterMetaInfo(&pSql->cmd, false);
|
||||
tscCleanSqlCmd(&pSql->cmd);
|
||||
|
@ -998,11 +993,11 @@ static int tscParseTblNameList(SSqlObj *pSql, const char* tblNameList, int32_t t
|
|||
pCmd->count = 0;
|
||||
|
||||
int code = TSDB_CODE_INVALID_METER_ID;
|
||||
char *str = (char*) tblNameList;
|
||||
char *str = (char *)tblNameList;
|
||||
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscAddEmptyMeterMetaInfo(pCmd);
|
||||
|
||||
if ((code = tscAllocPayload(pCmd, tblListLen+16)) != TSDB_CODE_SUCCESS) {
|
||||
if ((code = tscAllocPayload(pCmd, tblListLen + 16)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1068,7 +1063,7 @@ static int tscParseTblNameList(SSqlObj *pSql, const char* tblNameList, int32_t t
|
|||
}
|
||||
|
||||
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||
const int32_t MAX_TABLE_NAME_LENGTH = 12*1024*1024; // 12MB list
|
||||
const int32_t MAX_TABLE_NAME_LENGTH = 12 * 1024 * 1024; // 12MB list
|
||||
|
||||
STscObj *pObj = (STscObj *)taos;
|
||||
if (pObj == NULL || pObj->signature != pObj) {
|
||||
|
@ -1092,7 +1087,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
|||
return pRes->code;
|
||||
}
|
||||
|
||||
char* str = calloc(1, tblListLen + 1);
|
||||
char *str = calloc(1, tblListLen + 1);
|
||||
if (str == NULL) {
|
||||
pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
tscError("%p failed to malloc sql string buffer", pSql);
|
||||
|
@ -1100,7 +1095,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
|||
}
|
||||
|
||||
strtolower(str, tableNameList);
|
||||
pRes->code = (uint8_t) tscParseTblNameList(pSql, str, tblListLen);
|
||||
pRes->code = (uint8_t)tscParseTblNameList(pSql, str, tblListLen);
|
||||
|
||||
/*
|
||||
* set the qhandle to 0 before return in order to erase the qhandle value assigned in the previous successful query.
|
||||
|
|
|
@ -244,8 +244,7 @@ bool tscProjectionQueryOnMetric(SSqlCmd* pCmd) {
|
|||
|
||||
//for project query, only the following two function is allowed
|
||||
for (int32_t i = 0; i < pCmd->fieldsInfo.numOfOutputCols; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pCmd, i);
|
||||
int32_t functionId = pExpr->functionId;
|
||||
int32_t functionId = tscSqlExprGet(pCmd, i)->functionId;
|
||||
if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TAGPRJ &&
|
||||
functionId != TSDB_FUNC_TAG && functionId != TSDB_FUNC_TS) {
|
||||
return false;
|
||||
|
@ -255,6 +254,17 @@ bool tscProjectionQueryOnMetric(SSqlCmd* pCmd) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool tscProjectionQueryOnTable(SSqlCmd* pCmd) {
|
||||
for (int32_t i = 0; i < pCmd->fieldsInfo.numOfOutputCols; ++i) {
|
||||
int32_t functionId = tscSqlExprGet(pCmd, i)->functionId;
|
||||
if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tscIsPointInterpQuery(SSqlCmd* pCmd) {
|
||||
for (int32_t i = 0; i < pCmd->exprsInfo.numOfExprs; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pCmd, i);
|
||||
|
@ -1673,7 +1683,10 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
|
||||
char key[TSDB_MAX_TAGS_LEN + 1] = {0};
|
||||
tscGetMetricMetaCacheKey(pCmd, key, pMetermetaInfo->pMeterMeta->uid);
|
||||
printf("-----%s\n", key);
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
printf("the metricmeta key is:%s\n", key);
|
||||
#endif
|
||||
|
||||
char* name = pMeterMetaInfo->name;
|
||||
SMeterMetaInfo* pFinalInfo = NULL;
|
||||
|
@ -1768,3 +1781,12 @@ int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *s
|
|||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
|
||||
bool tscHasReachLimitation(SSqlObj* pSql) {
|
||||
assert(pSql != NULL && pSql->cmd.globalLimit != 0);
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
return (pCmd->globalLimit > 0 && pRes->numOfTotal >= pCmd->globalLimit);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue