commit
1a8025666f
|
@ -86,15 +86,16 @@ enum _sql_cmd {
|
|||
TSDB_SQL_MAX //48
|
||||
};
|
||||
|
||||
#define MAX_TOKEN_LEN 30
|
||||
|
||||
// token type
|
||||
enum {
|
||||
TSQL_NODE_TYPE_EXPR = 0x1,
|
||||
TSQL_NODE_TYPE_ID = 0x2,
|
||||
TSQL_NODE_TYPE_VALUE = 0x4,
|
||||
};
|
||||
|
||||
#define NON_ARITHMEIC_EXPR 0
|
||||
#define NORMAL_ARITHMETIC 1
|
||||
#define AGG_ARIGHTMEIC 2
|
||||
|
||||
extern char tTokenTypeSwitcher[13];
|
||||
|
||||
#define toTSDBType(x) \
|
||||
|
@ -112,7 +113,7 @@ typedef struct SLimitVal {
|
|||
} SLimitVal;
|
||||
|
||||
typedef struct SOrderVal {
|
||||
int32_t order;
|
||||
uint32_t order;
|
||||
int32_t orderColId;
|
||||
} SOrderVal;
|
||||
|
||||
|
|
|
@ -128,6 +128,8 @@ void tscFieldInfoSetValFromSchema(SFieldInfo* pFieldInfo, int32_t index, SSchema
|
|||
void tscFieldInfoSetValFromField(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIELD* pField);
|
||||
void tscFieldInfoSetValue(SFieldInfo* pFieldInfo, int32_t index, int8_t type, const char* name, int16_t bytes);
|
||||
void tscFieldInfoUpdateVisible(SFieldInfo* pFieldInfo, int32_t index, bool visible);
|
||||
void tscFieldInfoSetExpr(SFieldInfo* pFieldInfo, int32_t index, SSqlExpr* pExpr);
|
||||
void tscFieldInfoSetBinExpr(SFieldInfo* pFieldInfo, int32_t index, SSqlFunctionExpr* pExpr);
|
||||
|
||||
void tscFieldInfoCalOffset(SQueryInfo* pQueryInfo);
|
||||
void tscFieldInfoUpdateOffsetForInterResult(SQueryInfo* pQueryInfo);
|
||||
|
@ -149,9 +151,10 @@ SSqlExpr* tscSqlExprInsertEmpty(SQueryInfo* pQueryInfo, int32_t index, int16_t f
|
|||
|
||||
SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type,
|
||||
int16_t size);
|
||||
int32_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo);
|
||||
|
||||
SSqlExpr* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index);
|
||||
void tscSqlExprCopy(SSqlExprInfo* dst, const SSqlExprInfo* src, uint64_t uid);
|
||||
void tscSqlExprCopy(SSqlExprInfo* dst, const SSqlExprInfo* src, uint64_t uid, bool deepcopy);
|
||||
void* tscSqlExprDestroy(SSqlExpr* pExpr);
|
||||
void tscSqlExprInfoDestroy(SSqlExprInfo* pExprInfo);
|
||||
|
||||
|
|
|
@ -31,9 +31,8 @@ extern "C" {
|
|||
#include "tsqlfunction.h"
|
||||
#include "tutil.h"
|
||||
|
||||
#define TSC_GET_RESPTR_BASE(res, _queryinfo, col, ord) \
|
||||
(res->data + tscFieldInfoGetOffset(_queryinfo, col) * res->numOfRows)
|
||||
|
||||
#define TSC_GET_RESPTR_BASE(res, _queryinfo, col) (res->data + ((_queryinfo)->fieldsInfo.pSqlExpr[col]->offset) * res->numOfRows)
|
||||
|
||||
// forward declaration
|
||||
struct SSqlInfo;
|
||||
|
||||
|
@ -70,13 +69,19 @@ typedef struct SSqlExpr {
|
|||
int16_t interResBytes; // inter result buffer size
|
||||
int16_t numOfParams; // argument value of each function
|
||||
tVariant param[3]; // parameters are not more than 3
|
||||
int32_t offset; // sub result column value of arithmetic expression.
|
||||
} SSqlExpr;
|
||||
|
||||
typedef struct SColumnIndex {
|
||||
int16_t tableIndex;
|
||||
int16_t columnIndex;
|
||||
} SColumnIndex;
|
||||
|
||||
typedef struct SFieldInfo {
|
||||
int16_t numOfOutputCols; // number of column in result
|
||||
int16_t numOfAlloc; // allocated size
|
||||
TAOS_FIELD *pFields;
|
||||
short * pOffset;
|
||||
// short * pOffset;
|
||||
|
||||
/*
|
||||
* define if this column is belong to the queried result, it may be add by parser to faciliate
|
||||
|
@ -85,20 +90,17 @@ typedef struct SFieldInfo {
|
|||
* NOTE: these hidden columns always locate at the end of the output columns
|
||||
*/
|
||||
bool * pVisibleCols;
|
||||
int32_t numOfHiddenCols; // the number of column not belongs to the queried result columns
|
||||
int32_t numOfHiddenCols; // the number of column not belongs to the queried result columns
|
||||
SSqlFunctionExpr** pExpr; // used for aggregation arithmetic express,such as count(*)+count(*)
|
||||
SSqlExpr** pSqlExpr;
|
||||
} SFieldInfo;
|
||||
|
||||
typedef struct SSqlExprInfo {
|
||||
int16_t numOfAlloc;
|
||||
int16_t numOfExprs;
|
||||
SSqlExpr *pExprs;
|
||||
int16_t numOfAlloc;
|
||||
int16_t numOfExprs;
|
||||
SSqlExpr** pExprs;
|
||||
} SSqlExprInfo;
|
||||
|
||||
typedef struct SColumnIndex {
|
||||
int16_t tableIndex;
|
||||
int16_t columnIndex;
|
||||
} SColumnIndex;
|
||||
|
||||
typedef struct SColumnBase {
|
||||
SColumnIndex colIndex;
|
||||
int32_t numOfFilters;
|
||||
|
@ -163,7 +165,7 @@ typedef struct STableDataBlocks {
|
|||
|
||||
int32_t rowSize; // row size for current table
|
||||
uint32_t nAllocSize;
|
||||
uint32_t headerSize; // header for metadata (submit metadata)
|
||||
uint32_t headerSize; // header for metadata (submit metadata)
|
||||
uint32_t size;
|
||||
|
||||
/*
|
||||
|
@ -198,9 +200,9 @@ typedef struct SQueryInfo {
|
|||
char intervalTimeUnit;
|
||||
|
||||
int64_t etime, stime;
|
||||
int64_t nAggTimeInterval; // aggregation time interval
|
||||
int64_t nSlidingTime; // sliding window in mseconds
|
||||
SSqlGroupbyExpr groupbyExpr; // group by tags info
|
||||
int64_t intervalTime; // aggregation time interval
|
||||
int64_t slidingTime; // sliding window in mseconds
|
||||
SSqlGroupbyExpr groupbyExpr; // group by tags info
|
||||
|
||||
SColumnBaseInfo colList;
|
||||
SFieldInfo fieldsInfo;
|
||||
|
@ -216,9 +218,9 @@ typedef struct SQueryInfo {
|
|||
int64_t * defaultVal; // default value for interpolation
|
||||
char * msg; // pointer to the pCmd->payload to keep error message temporarily
|
||||
int64_t clauseLimit; // limit for current sub clause
|
||||
|
||||
|
||||
// offset value in the original sql expression, NOT sent to virtual node, only applied at client side
|
||||
int64_t prjOffset;
|
||||
int64_t prjOffset;
|
||||
} SQueryInfo;
|
||||
|
||||
// data source from sql string or from file
|
||||
|
@ -269,29 +271,28 @@ typedef struct SResRec {
|
|||
struct STSBuf;
|
||||
|
||||
typedef struct {
|
||||
uint8_t code;
|
||||
int64_t numOfRows; // num of results in current retrieved
|
||||
int64_t numOfTotal; // num of total results
|
||||
int64_t numOfTotalInCurrentClause; // num of total result in current subclause
|
||||
|
||||
char * pRsp;
|
||||
int rspType;
|
||||
int rspLen;
|
||||
uint64_t qhandle;
|
||||
int64_t uid;
|
||||
int64_t useconds;
|
||||
int64_t offset; // offset value from vnode during projection query of stable
|
||||
int row;
|
||||
int16_t numOfnchar;
|
||||
int16_t precision;
|
||||
int32_t numOfGroups;
|
||||
SResRec * pGroupRec;
|
||||
char * data;
|
||||
short * bytes;
|
||||
void ** tsrow;
|
||||
char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t)
|
||||
uint8_t code;
|
||||
int64_t numOfRows; // num of results in current retrieved
|
||||
int64_t numOfTotal; // num of total results
|
||||
int64_t numOfTotalInCurrentClause; // num of total result in current subclause
|
||||
char * pRsp;
|
||||
int rspType;
|
||||
int rspLen;
|
||||
uint64_t qhandle;
|
||||
int64_t uid;
|
||||
int64_t useconds;
|
||||
int64_t offset; // offset value from vnode during projection query of stable
|
||||
int row;
|
||||
int16_t numOfCols;
|
||||
int16_t precision;
|
||||
int32_t numOfGroups;
|
||||
SResRec * pGroupRec;
|
||||
char * data;
|
||||
void ** tsrow;
|
||||
char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t)
|
||||
SColumnIndex *pColumnIndex;
|
||||
|
||||
struct SLocalReducer *pLocalReducer;
|
||||
SColumnIndex * pColumnIndex;
|
||||
} SSqlRes;
|
||||
|
||||
typedef struct _tsc_obj {
|
||||
|
@ -404,19 +405,17 @@ int taos_retrieve(TAOS_RES *res);
|
|||
int32_t tscTansformSQLFunctionForSTableQuery(SQueryInfo *pQueryInfo);
|
||||
void tscRestoreSQLFunctionForMetricQuery(SQueryInfo *pQueryInfo);
|
||||
|
||||
void tscClearSqlMetaInfoForce(SSqlCmd *pCmd);
|
||||
|
||||
int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
|
||||
void tscDestroyResPointerInfo(SSqlRes *pRes);
|
||||
|
||||
void tscFreeSqlCmdData(SSqlCmd *pCmd);
|
||||
void tscFreeResData(SSqlObj* pSql);
|
||||
void tscFreeResData(SSqlObj *pSql);
|
||||
|
||||
/**
|
||||
* free query result of the sql object
|
||||
* @param pObj
|
||||
*/
|
||||
void tscFreeSqlResult(SSqlObj* pSql);
|
||||
void tscFreeSqlResult(SSqlObj *pSql);
|
||||
|
||||
/**
|
||||
* only free part of resources allocated during query.
|
||||
|
|
|
@ -158,7 +158,7 @@ static tSQLSyntaxNode *tSQLSyntaxNodeCreate(SSchema *pSchema, int32_t numOfCols,
|
|||
return pNode;
|
||||
}
|
||||
|
||||
static uint8_t getBinaryExprOptr(SSQLToken *pToken) {
|
||||
uint8_t getBinaryExprOptr(SSQLToken *pToken) {
|
||||
switch (pToken->type) {
|
||||
case TK_LT:
|
||||
return TSDB_RELATION_LESS;
|
||||
|
@ -183,6 +183,7 @@ static uint8_t getBinaryExprOptr(SSQLToken *pToken) {
|
|||
case TK_STAR:
|
||||
return TSDB_BINARY_OP_MULTIPLY;
|
||||
case TK_SLASH:
|
||||
case TK_DIVIDE:
|
||||
return TSDB_BINARY_OP_DIVIDE;
|
||||
case TK_REM:
|
||||
return TSDB_BINARY_OP_REMAINDER;
|
||||
|
|
|
@ -283,8 +283,15 @@ void tscAsyncFetchSingleRowProxy(void *param, TAOS_RES *tres, int numOfRows) {
|
|||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < pCmd->numOfCols; ++i)
|
||||
pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i, pQueryInfo->order) + pRes->bytes[i] * pRes->row;
|
||||
for (int i = 0; i < pCmd->numOfCols; ++i){
|
||||
SSqlExpr* pExpr = pQueryInfo->fieldsInfo.pSqlExpr[i];
|
||||
if (pExpr != NULL) {
|
||||
pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i) + pExpr->resBytes * pRes->row;
|
||||
} else {
|
||||
//todo add
|
||||
}
|
||||
}
|
||||
|
||||
pRes->row++;
|
||||
|
||||
(*pSql->fetchFp)(pSql->param, pSql, pSql->res.tsrow);
|
||||
|
@ -298,7 +305,12 @@ void tscProcessFetchRow(SSchedMsg *pMsg) {
|
|||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
for (int i = 0; i < pCmd->numOfCols; ++i) {
|
||||
pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i, pQueryInfo->order) + pRes->bytes[i] * pRes->row;
|
||||
SSqlExpr* pExpr = pQueryInfo->fieldsInfo.pSqlExpr[i];
|
||||
if (pExpr != NULL) {
|
||||
pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i) + pExpr->resBytes * pRes->row;
|
||||
} else {
|
||||
//todo add
|
||||
}
|
||||
}
|
||||
|
||||
pRes->row++;
|
||||
|
|
|
@ -322,6 +322,10 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
bool stableQueryFunctChanged(int32_t funcId) {
|
||||
return (aAggs[funcId].stableFuncId != funcId);
|
||||
}
|
||||
|
||||
/**
|
||||
* the numOfRes should be kept, since it may be used later
|
||||
* and allow the ResultInfo to be re initialized
|
||||
|
@ -719,12 +723,15 @@ static int32_t first_dist_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY
|
|||
return BLK_DATA_NO_NEEDED;
|
||||
}
|
||||
|
||||
SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes);
|
||||
if (pInfo->hasResult != DATA_SET_FLAG) {
|
||||
return BLK_DATA_ALL_NEEDED;
|
||||
} else { // data in current block is not earlier than current result
|
||||
return (pInfo->ts <= start) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED;
|
||||
}
|
||||
// result buffer has not been set yet.
|
||||
return BLK_DATA_ALL_NEEDED;
|
||||
//todo optimize the filter info
|
||||
// SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes);
|
||||
// if (pInfo->hasResult != DATA_SET_FLAG) {
|
||||
// return BLK_DATA_ALL_NEEDED;
|
||||
// } else { // data in current block is not earlier than current result
|
||||
// return (pInfo->ts <= start) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED;
|
||||
// }
|
||||
}
|
||||
|
||||
static int32_t last_dist_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId,
|
||||
|
@ -733,12 +740,13 @@ static int32_t last_dist_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY
|
|||
return BLK_DATA_NO_NEEDED;
|
||||
}
|
||||
|
||||
SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes);
|
||||
if (pInfo->hasResult != DATA_SET_FLAG) {
|
||||
return BLK_DATA_ALL_NEEDED;
|
||||
} else {
|
||||
return (pInfo->ts > end) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED;
|
||||
}
|
||||
return BLK_DATA_ALL_NEEDED;
|
||||
// SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes);
|
||||
// if (pInfo->hasResult != DATA_SET_FLAG) {
|
||||
// return BLK_DATA_ALL_NEEDED;
|
||||
// } else {
|
||||
// return (pInfo->ts > end) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED;
|
||||
// }
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1437,7 +1445,9 @@ static void stddev_next_step(SQLFunctionCtx *pCtx) {
|
|||
*/
|
||||
pStd->stage++;
|
||||
avg_finalizer(pCtx);
|
||||
|
||||
|
||||
pResInfo->initialized = true; // set it initialized to avoid re-initialization
|
||||
|
||||
// save average value into tmpBuf, for second stage scan
|
||||
SAvgInfo *pAvg = pResInfo->interResultBuf;
|
||||
|
||||
|
@ -2184,7 +2194,7 @@ static STopBotInfo *getTopBotOutputInfo(SQLFunctionCtx *pCtx) {
|
|||
// only the first_stage_merge is directly written data into final output buffer
|
||||
if (pResInfo->superTableQ && pCtx->currentStage != SECONDARY_STAGE_MERGE) {
|
||||
return (STopBotInfo*) pCtx->aOutputBuf;
|
||||
} else { // for normal table query and super table at the secondary_stage, result is written to intermediate buffer
|
||||
} else { // during normal table query and super table at the secondary_stage, result is written to intermediate buffer
|
||||
return pResInfo->interResultBuf;
|
||||
}
|
||||
}
|
||||
|
@ -3312,7 +3322,7 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) {
|
|||
tSQLBinaryExprCalcTraverse(sas->pExpr->pBinExprInfo.pBinExpr, pCtx->size, pCtx->aOutputBuf, sas, pCtx->order,
|
||||
arithmetic_callback_function);
|
||||
|
||||
pCtx->aOutputBuf += pCtx->outputBytes * pCtx->size/* * GET_FORWARD_DIRECTION_FACTOR(pCtx->order)*/;
|
||||
pCtx->aOutputBuf += pCtx->outputBytes * pCtx->size;
|
||||
pCtx->param[1].pz = NULL;
|
||||
}
|
||||
|
||||
|
@ -3573,6 +3583,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
|
|||
}
|
||||
|
||||
GET_RES_INFO(pCtx)->numOfRes = 1; // todo add test case
|
||||
doFinalizer(pCtx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -100,7 +100,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSubquerySupporter* pSuppor
|
|||
* in case of stable query, limit/offset is not applied here. the limit/offset is applied to the
|
||||
* final results which is acquired after the secondry merge of in the client.
|
||||
*/
|
||||
if (pLimit->offset == 0 || pQueryInfo->nAggTimeInterval > 0 || QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
|
||||
if (pLimit->offset == 0 || pQueryInfo->intervalTime > 0 || QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
|
||||
if (*st > elem1.ts) {
|
||||
*st = elem1.ts;
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ SJoinSubquerySupporter* tscCreateJoinSupporter(SSqlObj* pSql, SSubqueryState* pS
|
|||
pSupporter->subqueryIndex = index;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex);
|
||||
|
||||
pSupporter->interval = pQueryInfo->nAggTimeInterval;
|
||||
pSupporter->interval = pQueryInfo->intervalTime;
|
||||
pSupporter->limit = pQueryInfo->limit;
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, pSql->cmd.clauseIndex, index);
|
||||
|
@ -275,6 +275,7 @@ int32_t tscLaunchSecondPhaseSubqueries(SSqlObj* pSql) {
|
|||
pSubQueryInfo->tsBuf = NULL;
|
||||
|
||||
// free result for async object will also free sqlObj
|
||||
assert(pSubQueryInfo->exprsInfo.numOfExprs == 1); // ts_comp query only requires one resutl columns
|
||||
taos_free_result(pPrevSub);
|
||||
|
||||
SSqlObj *pNew = createSubqueryObj(pSql, (int16_t) i, tscJoinQueryCallback, pSupporter, NULL);
|
||||
|
@ -293,24 +294,26 @@ int32_t tscLaunchSecondPhaseSubqueries(SSqlObj* pSql) {
|
|||
// set the second stage sub query for join process
|
||||
pQueryInfo->type |= TSDB_QUERY_TYPE_JOIN_SEC_STAGE;
|
||||
|
||||
pQueryInfo->nAggTimeInterval = pSupporter->interval;
|
||||
pQueryInfo->intervalTime = pSupporter->interval;
|
||||
pQueryInfo->groupbyExpr = pSupporter->groupbyExpr;
|
||||
|
||||
tscColumnBaseInfoCopy(&pQueryInfo->colList, &pSupporter->colList, 0);
|
||||
tscTagCondCopy(&pQueryInfo->tagCond, &pSupporter->tagCond);
|
||||
|
||||
tscSqlExprCopy(&pQueryInfo->exprsInfo, &pSupporter->exprsInfo, pSupporter->uid);
|
||||
tscSqlExprCopy(&pQueryInfo->exprsInfo, &pSupporter->exprsInfo, pSupporter->uid, false);
|
||||
tscFieldInfoCopyAll(&pQueryInfo->fieldsInfo, &pSupporter->fieldsInfo);
|
||||
|
||||
|
||||
pSupporter->exprsInfo.numOfExprs = 0;
|
||||
pSupporter->fieldsInfo.numOfOutputCols = 0;
|
||||
|
||||
/*
|
||||
* if the first column of the secondary query is not ts function, add this function.
|
||||
* Because this column is required to filter with timestamp after intersecting.
|
||||
*/
|
||||
if (pSupporter->exprsInfo.pExprs[0].functionId != TSDB_FUNC_TS) {
|
||||
if (pSupporter->exprsInfo.pExprs[0]->functionId != TSDB_FUNC_TS) {
|
||||
tscAddTimestampColumn(pQueryInfo, TSDB_FUNC_TS, 0);
|
||||
}
|
||||
|
||||
// todo refactor function name
|
||||
SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0);
|
||||
assert(pNew->numOfSubs == 0 && pNew->cmd.numOfClause == 1 && pNewQueryInfo->numOfTables == 1);
|
||||
|
||||
|
|
|
@ -251,6 +251,13 @@ static int32_t tscBuildMeterSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
|
||||
tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 3, TSDB_DATA_TYPE_BINARY, "Note", noteColLength);
|
||||
rowLen += noteColLength;
|
||||
|
||||
//set the sqlexpr part
|
||||
SColumnIndex index = {0};
|
||||
pQueryInfo->fieldsInfo.pSqlExpr[0] = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, TSDB_COL_NAME_LEN, TSDB_COL_NAME_LEN);
|
||||
pQueryInfo->fieldsInfo.pSqlExpr[1] = tscSqlExprInsert(pQueryInfo, 1, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, typeColLength, typeColLength);
|
||||
pQueryInfo->fieldsInfo.pSqlExpr[2] = tscSqlExprInsert(pQueryInfo, 2, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), sizeof(int32_t));
|
||||
pQueryInfo->fieldsInfo.pSqlExpr[3] = tscSqlExprInsert(pQueryInfo, 3, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, noteColLength, noteColLength);
|
||||
|
||||
return rowLen;
|
||||
}
|
||||
|
@ -455,6 +462,8 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa
|
|||
tscInitResObjForLocalQuery(pSql, 1, valueLength);
|
||||
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, 0);
|
||||
pQueryInfo->fieldsInfo.pSqlExpr[0] = pQueryInfo->exprsInfo.pExprs[0];
|
||||
|
||||
strncpy(pRes->data, val, pField->bytes);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,10 +13,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tscSecondaryMerge.h"
|
||||
#include "os.h"
|
||||
#include "tlosertree.h"
|
||||
#include "tscSecondaryMerge.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tschemautil.h"
|
||||
#include "tsclient.h"
|
||||
#include "tutil.h"
|
||||
|
||||
|
@ -58,40 +59,37 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SSqlRes *pRes, SLocalReducer *pRedu
|
|||
* the fields and offset attributes in pCmd and pModel may be different due to
|
||||
* merge requirement. So, the final result in pRes structure is formatted in accordance with the pCmd object.
|
||||
*/
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
SQLFunctionCtx *pCtx = &pReducer->pCtx[i];
|
||||
SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
pCtx->aOutputBuf = pReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pReducer->resColModel->capacity;
|
||||
pCtx->aOutputBuf =
|
||||
pReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pReducer->resColModel->capacity;
|
||||
pCtx->order = pQueryInfo->order.order;
|
||||
pCtx->functionId = pQueryInfo->exprsInfo.pExprs[i].functionId;
|
||||
pCtx->functionId = pExpr->functionId;
|
||||
|
||||
// input buffer hold only one point data
|
||||
int16_t offset = getColumnModelOffset(pDesc->pColumnModel, i);
|
||||
SSchema* pSchema = getColumnModelSchema(pDesc->pColumnModel, i);
|
||||
|
||||
int16_t offset = getColumnModelOffset(pDesc->pColumnModel, i);
|
||||
SSchema *pSchema = getColumnModelSchema(pDesc->pColumnModel, i);
|
||||
|
||||
pCtx->aInputElemBuf = pReducer->pTempBuffer->data + offset;
|
||||
|
||||
// input data format comes from pModel
|
||||
pCtx->inputType = pSchema->type;
|
||||
pCtx->inputBytes = pSchema->bytes;
|
||||
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
// output data format yet comes from pCmd.
|
||||
pCtx->outputBytes = pField->bytes;
|
||||
pCtx->outputType = pField->type;
|
||||
pCtx->outputBytes = pExpr->resBytes;
|
||||
pCtx->outputType = pExpr->resType;
|
||||
|
||||
pCtx->startOffset = 0;
|
||||
pCtx->size = 1;
|
||||
pCtx->hasNull = true;
|
||||
pCtx->currentStage = SECONDARY_STAGE_MERGE;
|
||||
|
||||
pRes->bytes[i] = pField->bytes;
|
||||
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
// for top/bottom function, the output of timestamp is the first column
|
||||
int32_t functionId = pExpr->functionId;
|
||||
int32_t functionId = pExpr->functionId;
|
||||
if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) {
|
||||
pCtx->ptsOutputBuf = pReducer->pCtx[0].aOutputBuf;
|
||||
pCtx->param[2].i64Key = pQueryInfo->order.order;
|
||||
|
@ -107,12 +105,12 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SSqlRes *pRes, SLocalReducer *pRedu
|
|||
pCtx->resultInfo->superTableQ = true;
|
||||
}
|
||||
|
||||
int16_t n = 0;
|
||||
int16_t tagLen = 0;
|
||||
SQLFunctionCtx** pTagCtx = calloc(pQueryInfo->fieldsInfo.numOfOutputCols, POINTER_BYTES);
|
||||
int16_t n = 0;
|
||||
int16_t tagLen = 0;
|
||||
SQLFunctionCtx **pTagCtx = calloc(pQueryInfo->fieldsInfo.numOfOutputCols, POINTER_BYTES);
|
||||
|
||||
SQLFunctionCtx* pCtx = NULL;
|
||||
for(int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
SQLFunctionCtx *pCtx = NULL;
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
if (pExpr->functionId == TSDB_FUNC_TAG_DUMMY || pExpr->functionId == TSDB_FUNC_TS_DUMMY) {
|
||||
tagLen += pExpr->resBytes;
|
||||
|
@ -218,12 +216,12 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
#ifdef _DEBUG_VIEW
|
||||
printf("load data page into mem for build loser tree: %" PRIu64 " rows\n", pDS->filePage.numOfElems);
|
||||
SSrcColumnInfo colInfo[256] = {0};
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
tscGetSrcColumnInfo(colInfo, pQueryInfo);
|
||||
|
||||
tColModelDisplayEx(pDesc->pColumnModel, pDS->filePage.data, pDS->filePage.numOfElems, pMemBuffer[0]->numOfElemsPerPage,
|
||||
colInfo);
|
||||
tColModelDisplayEx(pDesc->pColumnModel, pDS->filePage.data, pDS->filePage.numOfElems,
|
||||
pMemBuffer[0]->numOfElemsPerPage, colInfo);
|
||||
#endif
|
||||
if (pDS->filePage.numOfElems == 0) { // no data in this flush
|
||||
tscTrace("%p flush data is empty, ignore %d flush record", pSqlObjAddr, idx);
|
||||
|
@ -244,8 +242,8 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
param->pLocalData = pReducer->pLocalDataSrc;
|
||||
param->pDesc = pReducer->pDesc;
|
||||
param->numOfElems = pReducer->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
param->groupOrderType = pQueryInfo->groupbyExpr.orderType;
|
||||
|
||||
pRes->code = tLoserTreeCreate(&pReducer->pLoserTree, pReducer->numOfBuffer, param, treeComparator);
|
||||
|
@ -255,7 +253,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
|
||||
// the input data format follows the old format, but output in a new format.
|
||||
// so, all the input must be parsed as old format
|
||||
pReducer->pCtx = (SQLFunctionCtx *)calloc(pQueryInfo->fieldsInfo.numOfOutputCols, sizeof(SQLFunctionCtx));
|
||||
pReducer->pCtx = (SQLFunctionCtx *)calloc(pQueryInfo->exprsInfo.numOfExprs, sizeof(SQLFunctionCtx));
|
||||
|
||||
pReducer->rowSize = pMemBuffer[0]->nElemSize;
|
||||
|
||||
|
@ -279,7 +277,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
|
||||
pReducer->nResultBufSize = pMemBuffer[0]->pageSize * 16;
|
||||
pReducer->pResultBuf = (tFilePage *)calloc(1, pReducer->nResultBufSize + sizeof(tFilePage));
|
||||
|
||||
|
||||
int32_t finalRowLength = tscGetResRowLength(pQueryInfo);
|
||||
pReducer->resColModel = finalmodel;
|
||||
pReducer->resColModel->capacity = pReducer->nResultBufSize / finalRowLength;
|
||||
|
@ -288,12 +286,12 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity);
|
||||
pReducer->pBufForInterpo = calloc(1, pReducer->nResultBufSize);
|
||||
|
||||
if (pReducer->pTempBuffer == NULL|| pReducer->discardData == NULL || pReducer->pResultBuf == NULL ||
|
||||
if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL ||
|
||||
pReducer->pBufForInterpo == NULL || pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
|
||||
tfree(pReducer->pTempBuffer);
|
||||
tfree(pReducer->discardData);
|
||||
tfree(pReducer->pResultBuf);
|
||||
tfree(pReducer->pFinalRes);
|
||||
tfree(pReducer->pFinalRes);
|
||||
tfree(pReducer->pBufForInterpo);
|
||||
tfree(pReducer->prevRowOfInput);
|
||||
|
||||
|
@ -302,30 +300,31 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
}
|
||||
|
||||
pReducer->pTempBuffer->numOfElems = 0;
|
||||
pReducer->pResInfo = calloc((size_t)pQueryInfo->fieldsInfo.numOfOutputCols, sizeof(SResultInfo));
|
||||
pReducer->pResInfo = calloc((size_t)pQueryInfo->exprsInfo.numOfExprs, sizeof(SResultInfo));
|
||||
|
||||
tscCreateResPointerInfo(pRes, pQueryInfo);
|
||||
tscInitSqlContext(pCmd, pRes, pReducer, pDesc);
|
||||
|
||||
// we change the capacity of schema to denote that there is only one row in temp buffer
|
||||
pReducer->pDesc->pColumnModel->capacity = 1;
|
||||
|
||||
//restore the limitation value at the last stage
|
||||
|
||||
// restore the limitation value at the last stage
|
||||
if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||
pQueryInfo->limit.limit = pQueryInfo->clauseLimit;
|
||||
pQueryInfo->limit.offset = pQueryInfo->prjOffset;
|
||||
}
|
||||
|
||||
|
||||
pReducer->offset = pQueryInfo->limit.offset;
|
||||
|
||||
|
||||
pRes->pLocalReducer = pReducer;
|
||||
pRes->numOfGroups = 0;
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0);
|
||||
int16_t prec = pMeterMetaInfo->pMeterMeta->precision;
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0);
|
||||
int16_t prec = pMeterMetaInfo->pMeterMeta->precision;
|
||||
|
||||
int64_t stime = (pQueryInfo->stime < pQueryInfo->etime) ? pQueryInfo->stime : pQueryInfo->etime;
|
||||
int64_t revisedSTime = taosGetIntervalStartTimestamp(stime, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, prec);
|
||||
int64_t revisedSTime =
|
||||
taosGetIntervalStartTimestamp(stime, pQueryInfo->intervalTime, pQueryInfo->intervalTimeUnit, prec);
|
||||
|
||||
SInterpolationInfo *pInterpoInfo = &pReducer->interpolationInfo;
|
||||
taosInitInterpoInfo(pInterpoInfo, pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols,
|
||||
|
@ -336,7 +335,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||
pInterpoInfo->pTags[0] = (char *)pInterpoInfo->pTags + POINTER_BYTES * pQueryInfo->groupbyExpr.numOfGroupCols;
|
||||
for (int32_t i = 1; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||
SSchema* pSchema = getColumnModelSchema(pReducer->resColModel, startIndex + i - 1);
|
||||
SSchema *pSchema = getColumnModelSchema(pReducer->resColModel, startIndex + i - 1);
|
||||
pInterpoInfo->pTags[i] = pSchema->bytes + pInterpoInfo->pTags[i - 1];
|
||||
}
|
||||
} else {
|
||||
|
@ -388,7 +387,7 @@ int32_t tscFlushTmpBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tF
|
|||
int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data,
|
||||
int32_t numOfRows, int32_t orderType) {
|
||||
SColumnModel *pModel = pDesc->pColumnModel;
|
||||
|
||||
|
||||
if (pPage->numOfElems + numOfRows <= pModel->capacity) {
|
||||
tColModelAppend(pModel, pPage, data, 0, numOfRows, numOfRows);
|
||||
return 0;
|
||||
|
@ -445,11 +444,11 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
|
|||
return;
|
||||
}
|
||||
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
// there is no more result, so we release all allocated resource
|
||||
SLocalReducer *pLocalReducer = (SLocalReducer*)atomic_exchange_ptr(&pRes->pLocalReducer, NULL);
|
||||
SLocalReducer *pLocalReducer = (SLocalReducer *)atomic_exchange_ptr(&pRes->pLocalReducer, NULL);
|
||||
if (pLocalReducer != NULL) {
|
||||
int32_t status = 0;
|
||||
while ((status = atomic_val_compare_exchange_32(&pLocalReducer->status, TSC_LOCALREDUCE_READY,
|
||||
|
@ -461,19 +460,18 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
|
|||
taosDestoryInterpoInfo(&pLocalReducer->interpolationInfo);
|
||||
|
||||
if (pLocalReducer->pCtx != NULL) {
|
||||
for(int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
SQLFunctionCtx *pCtx = &pLocalReducer->pCtx[i];
|
||||
|
||||
|
||||
tVariantDestroy(&pCtx->tag);
|
||||
if (pCtx->tagInfo.pTagCtxList != NULL) {
|
||||
tfree(pCtx->tagInfo.pTagCtxList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tfree(pLocalReducer->pCtx);
|
||||
}
|
||||
|
||||
|
||||
tfree(pLocalReducer->prevRowOfInput);
|
||||
|
||||
tfree(pLocalReducer->pTempBuffer);
|
||||
|
@ -514,15 +512,15 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCmd, SColumnModel *pModel) {
|
||||
int32_t numOfGroupByCols = 0;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
int32_t numOfGroupByCols = 0;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||
numOfGroupByCols = pQueryInfo->groupbyExpr.numOfGroupCols;
|
||||
}
|
||||
|
||||
// primary timestamp column is involved in final result
|
||||
if (pQueryInfo->nAggTimeInterval != 0 || tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||
if (pQueryInfo->intervalTime != 0 || tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||
numOfGroupByCols++;
|
||||
}
|
||||
|
||||
|
@ -539,7 +537,7 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
|||
orderIdx[i] = startCols++;
|
||||
}
|
||||
|
||||
if (pQueryInfo->nAggTimeInterval != 0) {
|
||||
if (pQueryInfo->intervalTime != 0) {
|
||||
// the first column is the timestamp, handles queries like "interval(10m) group by tags"
|
||||
orderIdx[numOfGroupByCols - 1] = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
||||
}
|
||||
|
@ -556,17 +554,17 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm
|
|||
}
|
||||
|
||||
bool isSameGroup(SSqlCmd *pCmd, SLocalReducer *pReducer, char *pPrev, tFilePage *tmpBuffer) {
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
int16_t functionId = tscSqlExprGet(pQueryInfo, 0)->functionId;
|
||||
|
||||
// disable merge procedure for column projection query
|
||||
assert(functionId != TSDB_FUNC_ARITHM);
|
||||
|
||||
|
||||
if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_ARITHM) {
|
||||
return false;
|
||||
}
|
||||
|
@ -581,10 +579,10 @@ bool isSameGroup(SSqlCmd *pCmd, SLocalReducer *pReducer, char *pPrev, tFilePage
|
|||
|
||||
if (pOrderDesc->orderIdx.pData[numOfCols - 1] == PRIMARYKEY_TIMESTAMP_COL_INDEX) { //<= 0
|
||||
// super table interval query
|
||||
assert(pQueryInfo->nAggTimeInterval > 0);
|
||||
assert(pQueryInfo->intervalTime > 0);
|
||||
pOrderDesc->orderIdx.numOfCols -= 1;
|
||||
} else { // simple group by query
|
||||
assert(pQueryInfo->nAggTimeInterval == 0);
|
||||
assert(pQueryInfo->intervalTime == 0);
|
||||
}
|
||||
|
||||
// only one row exists
|
||||
|
@ -599,11 +597,11 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
SSchema * pSchema = NULL;
|
||||
SSchema * pSchema = NULL;
|
||||
SColumnModel *pModel = NULL;
|
||||
*pFinalModel = NULL;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0);
|
||||
|
||||
(*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * pMeterMetaInfo->pMetricMeta->numOfVnodes);
|
||||
|
@ -613,7 +611,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
return pRes->code;
|
||||
}
|
||||
|
||||
pSchema = (SSchema *)calloc(1, sizeof(SSchema) * pQueryInfo->fieldsInfo.numOfOutputCols);
|
||||
pSchema = (SSchema *)calloc(1, sizeof(SSchema) * pQueryInfo->exprsInfo.numOfExprs);
|
||||
if (pSchema == NULL) {
|
||||
tscError("%p failed to allocate memory", pSql);
|
||||
pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
|
@ -621,7 +619,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
}
|
||||
|
||||
int32_t rlen = 0;
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
pSchema[i].bytes = pExpr->resBytes;
|
||||
|
@ -634,8 +632,8 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
if (rlen != 0) {
|
||||
capacity = nBufferSizes / rlen;
|
||||
}
|
||||
|
||||
pModel = createColumnModel(pSchema, pQueryInfo->fieldsInfo.numOfOutputCols, capacity);
|
||||
|
||||
pModel = createColumnModel(pSchema, pQueryInfo->exprsInfo.numOfExprs, capacity);
|
||||
|
||||
for (int32_t i = 0; i < pMeterMetaInfo->pMetricMeta->numOfVnodes; ++i) {
|
||||
(*pMemBuffer)[i] = createExtMemBuffer(nBufferSizes, rlen, pModel);
|
||||
|
@ -647,16 +645,43 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
return pRes->code;
|
||||
}
|
||||
|
||||
memset(pSchema, 0, sizeof(SSchema) * pQueryInfo->fieldsInfo.numOfOutputCols);
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
// final result depends on the fields number
|
||||
memset(pSchema, 0, sizeof(SSchema) * pQueryInfo->exprsInfo.numOfExprs);
|
||||
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
pSchema[i].type = pField->type;
|
||||
pSchema[i].bytes = pField->bytes;
|
||||
strcpy(pSchema[i].name, pField->name);
|
||||
SSchema *p1 = tsGetColumnSchema(pMeterMetaInfo->pMeterMeta, pExpr->colInfo.colIdx);
|
||||
|
||||
int16_t inter = 0;
|
||||
int16_t type = -1;
|
||||
int16_t bytes = 0;
|
||||
|
||||
// if ((pExpr->functionId >= TSDB_FUNC_FIRST_DST && pExpr->functionId <= TSDB_FUNC_LAST_DST) ||
|
||||
// (pExpr->functionId >= TSDB_FUNC_SUM && pExpr->functionId <= TSDB_FUNC_MAX) ||
|
||||
// pExpr->functionId == TSDB_FUNC_LAST_ROW) {
|
||||
// the final result size and type in the same as query on single table.
|
||||
// so here, set the flag to be false;
|
||||
|
||||
int32_t functionId = pExpr->functionId;
|
||||
if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) {
|
||||
type = pModel->pFields[i].field.type;
|
||||
bytes = pModel->pFields[i].field.bytes;
|
||||
} else {
|
||||
if (functionId == TSDB_FUNC_FIRST_DST) {
|
||||
functionId = TSDB_FUNC_FIRST;
|
||||
} else if (functionId == TSDB_FUNC_LAST_DST) {
|
||||
functionId = TSDB_FUNC_LAST;
|
||||
}
|
||||
|
||||
getResultDataInfo(p1->type, p1->bytes, functionId, 0, &type, &bytes, &inter, 0, false);
|
||||
}
|
||||
|
||||
pSchema[i].type = type;
|
||||
pSchema[i].bytes = bytes;
|
||||
strcpy(pSchema[i].name, pModel->pFields[i].field.name);
|
||||
}
|
||||
|
||||
*pFinalModel = createColumnModel(pSchema, pQueryInfo->fieldsInfo.numOfOutputCols, capacity);
|
||||
*pFinalModel = createColumnModel(pSchema, pQueryInfo->exprsInfo.numOfExprs, capacity);
|
||||
tfree(pSchema);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -746,13 +771,15 @@ void adjustLoserTreeFromNewData(SLocalReducer *pLocalReducer, SLocalDataSource *
|
|||
}
|
||||
}
|
||||
|
||||
void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo* pQueryInfo, SInterpolationInfo *pInterpoInfo) {
|
||||
void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo *pQueryInfo,
|
||||
SInterpolationInfo *pInterpoInfo) {
|
||||
// discard following dataset in the same group and reset the interpolation information
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0);
|
||||
int16_t prec = pMeterMetaInfo->pMeterMeta->precision;
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0);
|
||||
int16_t prec = pMeterMetaInfo->pMeterMeta->precision;
|
||||
|
||||
int64_t stime = (pQueryInfo->stime < pQueryInfo->etime) ? pQueryInfo->stime : pQueryInfo->etime;
|
||||
int64_t revisedSTime = taosGetIntervalStartTimestamp(stime, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, prec);
|
||||
int64_t revisedSTime =
|
||||
taosGetIntervalStartTimestamp(stime, pQueryInfo->intervalTime, pQueryInfo->intervalTimeUnit, prec);
|
||||
|
||||
taosInitInterpoInfo(pInterpoInfo, pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols,
|
||||
pLocalReducer->rowSize);
|
||||
|
@ -765,24 +792,25 @@ void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo*
|
|||
}
|
||||
|
||||
// todo merge with following function
|
||||
static void reversedCopyResultToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tFilePage *pFinalDataPage) {
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
// static void reversedCopyResultToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tFilePage *pFinalDataPage) {
|
||||
//
|
||||
// for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
// TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
//
|
||||
// int32_t offset = tscFieldInfoGetOffset(pQueryInfo, i);
|
||||
// char * src = pFinalDataPage->data + (pRes->numOfRows - 1) * pField->bytes + pRes->numOfRows * offset;
|
||||
// char * dst = pRes->data + pRes->numOfRows * offset;
|
||||
//
|
||||
// for (int32_t j = 0; j < pRes->numOfRows; ++j) {
|
||||
// memcpy(dst, src, (size_t)pField->bytes);
|
||||
// dst += pField->bytes;
|
||||
// src -= pField->bytes;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
int32_t offset = tscFieldInfoGetOffset(pQueryInfo, i);
|
||||
char * src = pFinalDataPage->data + (pRes->numOfRows - 1) * pField->bytes + pRes->numOfRows * offset;
|
||||
char * dst = pRes->data + pRes->numOfRows * offset;
|
||||
|
||||
for (int32_t j = 0; j < pRes->numOfRows; ++j) {
|
||||
memcpy(dst, src, (size_t)pField->bytes);
|
||||
dst += pField->bytes;
|
||||
src -= pField->bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void reversedCopyFromInterpolationToDstBuf(SQueryInfo* pQueryInfo, SSqlRes *pRes, tFilePage **pResPages, SLocalReducer *pLocalReducer) {
|
||||
static void reversedCopyFromInterpolationToDstBuf(SQueryInfo *pQueryInfo, SSqlRes *pRes, tFilePage **pResPages,
|
||||
SLocalReducer *pLocalReducer) {
|
||||
assert(0);
|
||||
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
|
@ -806,11 +834,11 @@ static void reversedCopyFromInterpolationToDstBuf(SQueryInfo* pQueryInfo, SSqlRe
|
|||
* by "interuptHandler" function in shell
|
||||
*/
|
||||
static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneOutput) {
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
SSqlRes * pRes = &pSql->res;
|
||||
tFilePage *pFinalDataPage = pLocalReducer->pResultBuf;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
SSqlRes * pRes = &pSql->res;
|
||||
tFilePage * pFinalDataPage = pLocalReducer->pResultBuf;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
if (pRes->pLocalReducer != pLocalReducer) {
|
||||
/*
|
||||
* Release the SSqlObj is called, and it is int destroying function invoked by other thread.
|
||||
|
@ -820,7 +848,7 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
|||
assert(pRes->pLocalReducer == NULL);
|
||||
}
|
||||
|
||||
if (pQueryInfo->nAggTimeInterval == 0 || pQueryInfo->interpoType == TSDB_INTERPO_NONE) {
|
||||
if (pQueryInfo->intervalTime == 0 || pQueryInfo->interpoType == TSDB_INTERPO_NONE) {
|
||||
// no interval query, no interpolation
|
||||
pRes->data = pLocalReducer->pFinalRes;
|
||||
pRes->numOfRows = pFinalDataPage->numOfElems;
|
||||
|
@ -862,19 +890,14 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
|||
}
|
||||
|
||||
int32_t rowSize = tscGetResRowLength(pQueryInfo);
|
||||
// handle the descend order output
|
||||
// if (pQueryInfo->order.order == TSQL_SO_ASC) {
|
||||
memcpy(pRes->data, pFinalDataPage->data, pRes->numOfRows * rowSize);
|
||||
// } else {
|
||||
// reversedCopyResultToDstBuf(pQueryInfo, pRes, pFinalDataPage);
|
||||
// }
|
||||
memcpy(pRes->data, pFinalDataPage->data, pRes->numOfRows * rowSize);
|
||||
|
||||
pFinalDataPage->numOfElems = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t *pPrimaryKeys = (int64_t *)pLocalReducer->pBufForInterpo;
|
||||
|
||||
|
||||
SInterpolationInfo *pInterpoInfo = &pLocalReducer->interpolationInfo;
|
||||
|
||||
int64_t actualETime = (pQueryInfo->stime < pQueryInfo->etime) ? pQueryInfo->etime : pQueryInfo->stime;
|
||||
|
@ -889,22 +912,23 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
|||
int32_t *functions = (int32_t *)((char *)srcData + pQueryInfo->fieldsInfo.numOfOutputCols * sizeof(void *));
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
srcData[i] = pLocalReducer->pBufForInterpo + tscFieldInfoGetOffset(pQueryInfo, i) * pInterpoInfo->numOfRawDataInRows;
|
||||
srcData[i] =
|
||||
pLocalReducer->pBufForInterpo + tscFieldInfoGetOffset(pQueryInfo, i) * pInterpoInfo->numOfRawDataInRows;
|
||||
functions[i] = tscSqlExprGet(pQueryInfo, i)->functionId;
|
||||
}
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0);
|
||||
int8_t precision = pMeterMetaInfo->pMeterMeta->precision;
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0);
|
||||
int8_t precision = pMeterMetaInfo->pMeterMeta->precision;
|
||||
|
||||
while (1) {
|
||||
int32_t remains = taosNumOfRemainPoints(pInterpoInfo);
|
||||
TSKEY etime = taosGetRevisedEndKey(actualETime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit,
|
||||
precision);
|
||||
int32_t nrows = taosGetNumOfResultWithInterpo(pInterpoInfo, pPrimaryKeys, remains, pQueryInfo->nAggTimeInterval, etime,
|
||||
TSKEY etime = taosGetRevisedEndKey(actualETime, pQueryInfo->order.order, pQueryInfo->intervalTime,
|
||||
pQueryInfo->intervalTimeUnit, precision);
|
||||
int32_t nrows = taosGetNumOfResultWithInterpo(pInterpoInfo, pPrimaryKeys, remains, pQueryInfo->intervalTime, etime,
|
||||
pLocalReducer->resColModel->capacity);
|
||||
|
||||
int32_t newRows = taosDoInterpoResult(pInterpoInfo, pQueryInfo->interpoType, pResPages, remains, nrows,
|
||||
pQueryInfo->nAggTimeInterval, pPrimaryKeys, pLocalReducer->resColModel, srcData,
|
||||
pQueryInfo->intervalTime, pPrimaryKeys, pLocalReducer->resColModel, srcData,
|
||||
pQueryInfo->defaultVal, functions, pLocalReducer->resColModel->capacity);
|
||||
assert(newRows <= nrows);
|
||||
|
||||
|
@ -914,7 +938,8 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
|||
if (pQueryInfo->limit.offset > 0) {
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
memmove(pResPages[i]->data, pResPages[i]->data + pField->bytes * pQueryInfo->limit.offset, newRows * pField->bytes);
|
||||
memmove(pResPages[i]->data, pResPages[i]->data + pField->bytes * pQueryInfo->limit.offset,
|
||||
newRows * pField->bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -937,7 +962,7 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
|||
|
||||
/* all output for current group are completed */
|
||||
int32_t totalRemainRows =
|
||||
taosGetNumOfResWithoutLimit(pInterpoInfo, pPrimaryKeys, rpoints, pQueryInfo->nAggTimeInterval, actualETime);
|
||||
taosGetNumOfResWithoutLimit(pInterpoInfo, pPrimaryKeys, rpoints, pQueryInfo->intervalTime, actualETime);
|
||||
if (totalRemainRows <= 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -962,10 +987,10 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
|||
if (pQueryInfo->order.order == TSQL_SO_ASC) {
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
int16_t offset = getColumnModelOffset(pLocalReducer->resColModel, i);
|
||||
int16_t offset = getColumnModelOffset(pLocalReducer->resColModel, i);
|
||||
memcpy(pRes->data + offset * pRes->numOfRows, pResPages[i]->data, pField->bytes * pRes->numOfRows);
|
||||
}
|
||||
} else {//todo bug??
|
||||
} else { // todo bug??
|
||||
reversedCopyFromInterpolationToDstBuf(pQueryInfo, pRes, pResPages, pLocalReducer);
|
||||
}
|
||||
}
|
||||
|
@ -985,9 +1010,9 @@ static void savePreviousRow(SLocalReducer *pLocalReducer, tFilePage *tmpBuffer)
|
|||
|
||||
// copy to previous temp buffer
|
||||
for (int32_t i = 0; i < pColumnModel->numOfCols; ++i) {
|
||||
SSchema* pSchema = getColumnModelSchema(pColumnModel, i);
|
||||
int16_t offset = getColumnModelOffset(pColumnModel, i);
|
||||
|
||||
SSchema *pSchema = getColumnModelSchema(pColumnModel, i);
|
||||
int16_t offset = getColumnModelOffset(pColumnModel, i);
|
||||
|
||||
memcpy(pLocalReducer->prevRowOfInput + offset, tmpBuffer->data + offset, pSchema->bytes);
|
||||
}
|
||||
|
||||
|
@ -995,19 +1020,19 @@ static void savePreviousRow(SLocalReducer *pLocalReducer, tFilePage *tmpBuffer)
|
|||
pLocalReducer->hasPrevRow = true;
|
||||
}
|
||||
|
||||
static void doExecuteSecondaryMerge(SSqlCmd* pCmd, SLocalReducer *pLocalReducer, bool needInit) {
|
||||
static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalReducer *pLocalReducer, bool needInit) {
|
||||
// the tag columns need to be set before all functions execution
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
for(int32_t j = 0; j < pQueryInfo->fieldsInfo.numOfOutputCols; ++j) {
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) {
|
||||
SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, j);
|
||||
SQLFunctionCtx *pCtx = &pLocalReducer->pCtx[j];
|
||||
|
||||
tVariantAssign(&pCtx->param[0], &pExpr->param[0]);
|
||||
|
||||
// tags/tags_dummy function, the tag field of SQLFunctionCtx is from the input buffer
|
||||
if (pExpr->functionId == TSDB_FUNC_TAG_DUMMY || pExpr->functionId == TSDB_FUNC_TAG ||
|
||||
pExpr->functionId == TSDB_FUNC_TS_DUMMY) {
|
||||
int32_t functionId = pExpr->functionId;
|
||||
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS_DUMMY) {
|
||||
tVariantDestroy(&pCtx->tag);
|
||||
tVariantCreateFromBinary(&pCtx->tag, pCtx->aInputElemBuf, pCtx->inputBytes, pCtx->inputType);
|
||||
}
|
||||
|
@ -1019,7 +1044,7 @@ static void doExecuteSecondaryMerge(SSqlCmd* pCmd, SLocalReducer *pLocalReducer,
|
|||
}
|
||||
}
|
||||
|
||||
for (int32_t j = 0; j < pQueryInfo->fieldsInfo.numOfOutputCols; ++j) {
|
||||
for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) {
|
||||
int32_t functionId = tscSqlExprGet(pQueryInfo, j)->functionId;
|
||||
if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) {
|
||||
continue;
|
||||
|
@ -1029,7 +1054,7 @@ static void doExecuteSecondaryMerge(SSqlCmd* pCmd, SLocalReducer *pLocalReducer,
|
|||
}
|
||||
}
|
||||
|
||||
static void handleUnprocessedRow(SSqlCmd* pCmd, SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) {
|
||||
static void handleUnprocessedRow(SSqlCmd *pCmd, SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) {
|
||||
if (pLocalReducer->hasUnprocessedRow) {
|
||||
pLocalReducer->hasUnprocessedRow = false;
|
||||
doExecuteSecondaryMerge(pCmd, pLocalReducer, true);
|
||||
|
@ -1039,14 +1064,22 @@ static void handleUnprocessedRow(SSqlCmd* pCmd, SLocalReducer *pLocalReducer, tF
|
|||
|
||||
static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx) {
|
||||
int64_t maxOutput = 0;
|
||||
|
||||
|
||||
for (int32_t j = 0; j < pQueryInfo->exprsInfo.numOfExprs; ++j) {
|
||||
int32_t functionId = tscSqlExprGet(pQueryInfo, j)->functionId;
|
||||
// SSqlExpr* pExpr = pQueryInfo->fieldsInfo.pSqlExpr[j];
|
||||
// if (pExpr == NULL) {
|
||||
// assert(pQueryInfo->fieldsInfo.pExpr[j] != NULL);
|
||||
//
|
||||
// maxOutput = 1;
|
||||
// continue;
|
||||
// }
|
||||
|
||||
/*
|
||||
* ts, tag, tagprj function can not decide the output number of current query
|
||||
* the number of output result is decided by main output
|
||||
*/
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, j);
|
||||
int32_t functionId = pExpr->functionId;
|
||||
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAGPRJ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1055,6 +1088,7 @@ static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx)
|
|||
maxOutput = GET_RES_INFO(&pCtx[j])->numOfRes;
|
||||
}
|
||||
}
|
||||
|
||||
return maxOutput;
|
||||
}
|
||||
|
||||
|
@ -1064,9 +1098,9 @@ static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx)
|
|||
* filled with the same result, which is the tags, specified in group by clause
|
||||
*
|
||||
*/
|
||||
static void fillMultiRowsOfTagsVal(SQueryInfo* pQueryInfo, int32_t numOfRes, SLocalReducer *pLocalReducer) {
|
||||
static void fillMultiRowsOfTagsVal(SQueryInfo *pQueryInfo, int32_t numOfRes, SLocalReducer *pLocalReducer) {
|
||||
int32_t maxBufSize = 0; // find the max tags column length to prepare the buffer
|
||||
for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) {
|
||||
for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
if (maxBufSize < pExpr->resBytes && pExpr->functionId == TSDB_FUNC_TAG) {
|
||||
maxBufSize = pExpr->resBytes;
|
||||
|
@ -1075,8 +1109,8 @@ static void fillMultiRowsOfTagsVal(SQueryInfo* pQueryInfo, int32_t numOfRes, SLo
|
|||
|
||||
assert(maxBufSize >= 0);
|
||||
|
||||
char *buf = malloc((size_t) maxBufSize);
|
||||
for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) {
|
||||
char *buf = malloc((size_t)maxBufSize);
|
||||
for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
if (pExpr->functionId != TSDB_FUNC_TAG) {
|
||||
continue;
|
||||
|
@ -1097,13 +1131,10 @@ static void fillMultiRowsOfTagsVal(SQueryInfo* pQueryInfo, int32_t numOfRes, SLo
|
|||
free(buf);
|
||||
}
|
||||
|
||||
int32_t finalizeRes(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer) {
|
||||
for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) {
|
||||
int32_t finalizeRes(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) {
|
||||
for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
aAggs[pExpr->functionId].xFinalize(&pLocalReducer->pCtx[k]);
|
||||
|
||||
// allow to re-initialize for the next round
|
||||
pLocalReducer->pCtx[k].resultInfo->initialized = false;
|
||||
}
|
||||
|
||||
pLocalReducer->hasPrevRow = false;
|
||||
|
@ -1122,7 +1153,7 @@ int32_t finalizeRes(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer) {
|
|||
* results generated by simple aggregation function, we merge them all into one points
|
||||
* *Exception*: column projection query, required no merge procedure
|
||||
*/
|
||||
bool needToMerge(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) {
|
||||
bool needToMerge(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer, tFilePage *tmpBuffer) {
|
||||
int32_t ret = 0; // merge all result by default
|
||||
int16_t functionId = tscSqlExprGet(pQueryInfo, 0)->functionId;
|
||||
|
||||
|
@ -1144,7 +1175,7 @@ bool needToMerge(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer, tFilePage
|
|||
return (ret == 0);
|
||||
}
|
||||
|
||||
static bool reachGroupResultLimit(SQueryInfo* pQueryInfo, SSqlRes *pRes) {
|
||||
static bool reachGroupResultLimit(SQueryInfo *pQueryInfo, SSqlRes *pRes) {
|
||||
return (pRes->numOfGroups >= pQueryInfo->slimit.limit && pQueryInfo->slimit.limit >= 0);
|
||||
}
|
||||
|
||||
|
@ -1152,7 +1183,7 @@ static bool saveGroupResultInfo(SSqlObj *pSql) {
|
|||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
pRes->numOfGroups += 1;
|
||||
|
||||
// the output group is limited by the slimit clause
|
||||
|
@ -1175,11 +1206,11 @@ static bool saveGroupResultInfo(SSqlObj *pSql) {
|
|||
* @return if current group is skipped, return false, and do NOT record it into pRes->numOfGroups
|
||||
*/
|
||||
bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool noMoreCurrentGroupRes) {
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
SSqlRes * pRes = &pSql->res;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
tFilePage *pResBuf = pLocalReducer->pResultBuf;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
tFilePage * pResBuf = pLocalReducer->pResultBuf;
|
||||
SColumnModel *pModel = pLocalReducer->resColModel;
|
||||
|
||||
pRes->code = TSDB_CODE_SUCCESS;
|
||||
|
@ -1207,11 +1238,10 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
|
|||
int32_t startIndex = pQueryInfo->fieldsInfo.numOfOutputCols - pQueryInfo->groupbyExpr.numOfGroupCols;
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||
int16_t offset = getColumnModelOffset(pModel, startIndex + i);
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, startIndex + i);
|
||||
|
||||
memcpy(pInterpoInfo->pTags[i],
|
||||
pLocalReducer->pBufForInterpo + offset * pResBuf->numOfElems, pSchema->bytes);
|
||||
int16_t offset = getColumnModelOffset(pModel, startIndex + i);
|
||||
SSchema *pSchema = getColumnModelSchema(pModel, startIndex + i);
|
||||
|
||||
memcpy(pInterpoInfo->pTags[i], pLocalReducer->pBufForInterpo + offset * pResBuf->numOfElems, pSchema->bytes);
|
||||
}
|
||||
|
||||
taosInterpoSetStartInfo(&pLocalReducer->interpolationInfo, pResBuf->numOfElems, pQueryInfo->interpoType);
|
||||
|
@ -1220,7 +1250,7 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
|
|||
return true;
|
||||
}
|
||||
|
||||
void resetOutputBuf(SQueryInfo* pQueryInfo, SLocalReducer *pLocalReducer) { // reset output buffer to the beginning
|
||||
void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) { // reset output buffer to the beginning
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
pLocalReducer->pCtx[i].aOutputBuf =
|
||||
pLocalReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pLocalReducer->resColModel->capacity;
|
||||
|
@ -1233,21 +1263,22 @@ static void resetEnvForNewResultset(SSqlRes *pRes, SSqlCmd *pCmd, SLocalReducer
|
|||
// In handling data in other groups, we need to reset the interpolation information for a new group data
|
||||
pRes->numOfRows = 0;
|
||||
pRes->numOfTotalInCurrentClause = 0;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
pQueryInfo->limit.offset = pLocalReducer->offset;
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0);
|
||||
int16_t precision = pMeterMetaInfo->pMeterMeta->precision;
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0);
|
||||
int16_t precision = pMeterMetaInfo->pMeterMeta->precision;
|
||||
|
||||
// for group result interpolation, do not return if not data is generated
|
||||
if (pQueryInfo->interpoType != TSDB_INTERPO_NONE) {
|
||||
int64_t stime = (pQueryInfo->stime < pQueryInfo->etime) ? pQueryInfo->stime : pQueryInfo->etime;
|
||||
int64_t newTime = taosGetIntervalStartTimestamp(stime, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, precision);
|
||||
int64_t newTime =
|
||||
taosGetIntervalStartTimestamp(stime, pQueryInfo->intervalTime, pQueryInfo->intervalTimeUnit, precision);
|
||||
|
||||
taosInitInterpoInfo(&pLocalReducer->interpolationInfo, pQueryInfo->order.order, newTime, pQueryInfo->groupbyExpr.numOfGroupCols,
|
||||
pLocalReducer->rowSize);
|
||||
taosInitInterpoInfo(&pLocalReducer->interpolationInfo, pQueryInfo->order.order, newTime,
|
||||
pQueryInfo->groupbyExpr.numOfGroupCols, pLocalReducer->rowSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1259,12 +1290,12 @@ static bool doInterpolationForCurrentGroup(SSqlObj *pSql) {
|
|||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
SLocalReducer * pLocalReducer = pRes->pLocalReducer;
|
||||
SInterpolationInfo *pInterpoInfo = &pLocalReducer->interpolationInfo;
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0);
|
||||
int8_t p = pMeterMetaInfo->pMeterMeta->precision;
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0);
|
||||
int8_t p = pMeterMetaInfo->pMeterMeta->precision;
|
||||
|
||||
if (taosHasRemainsDataForInterpolation(pInterpoInfo)) {
|
||||
assert(pQueryInfo->interpoType != TSDB_INTERPO_NONE);
|
||||
|
@ -1273,9 +1304,10 @@ static bool doInterpolationForCurrentGroup(SSqlObj *pSql) {
|
|||
int64_t etime = *(int64_t *)(pFinalDataBuf->data + TSDB_KEYSIZE * (pInterpoInfo->numOfRawDataInRows - 1));
|
||||
|
||||
int32_t remain = taosNumOfRemainPoints(pInterpoInfo);
|
||||
TSKEY ekey = taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, p);
|
||||
TSKEY ekey =
|
||||
taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->intervalTime, pQueryInfo->intervalTimeUnit, p);
|
||||
int32_t rows = taosGetNumOfResultWithInterpo(pInterpoInfo, (TSKEY *)pLocalReducer->pBufForInterpo, remain,
|
||||
pQueryInfo->nAggTimeInterval, ekey, pLocalReducer->resColModel->capacity);
|
||||
pQueryInfo->intervalTime, ekey, pLocalReducer->resColModel->capacity);
|
||||
if (rows > 0) { // do interpo
|
||||
doInterpolateResult(pSql, pLocalReducer, false);
|
||||
}
|
||||
|
@ -1295,9 +1327,9 @@ static bool doHandleLastRemainData(SSqlObj *pSql) {
|
|||
|
||||
bool prevGroupCompleted = (!pLocalReducer->discard) && pLocalReducer->hasUnprocessedRow;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0);
|
||||
int8_t precision = pMeterMetaInfo->pMeterMeta->precision;
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0);
|
||||
int8_t precision = pMeterMetaInfo->pMeterMeta->precision;
|
||||
|
||||
if ((isAllSourcesCompleted(pLocalReducer) && !pLocalReducer->hasPrevRow) || pLocalReducer->pLocalDataSrc[0] == NULL ||
|
||||
prevGroupCompleted) {
|
||||
|
@ -1305,8 +1337,9 @@ static bool doHandleLastRemainData(SSqlObj *pSql) {
|
|||
if (pQueryInfo->interpoType != TSDB_INTERPO_NONE) {
|
||||
int64_t etime = (pQueryInfo->stime < pQueryInfo->etime) ? pQueryInfo->etime : pQueryInfo->stime;
|
||||
|
||||
etime = taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->nAggTimeInterval, pQueryInfo->intervalTimeUnit, precision);
|
||||
int32_t rows = taosGetNumOfResultWithInterpo(pInterpoInfo, NULL, 0, pQueryInfo->nAggTimeInterval, etime,
|
||||
etime = taosGetRevisedEndKey(etime, pQueryInfo->order.order, pQueryInfo->intervalTime,
|
||||
pQueryInfo->intervalTimeUnit, precision);
|
||||
int32_t rows = taosGetNumOfResultWithInterpo(pInterpoInfo, NULL, 0, pQueryInfo->intervalTime, etime,
|
||||
pLocalReducer->resColModel->capacity);
|
||||
if (rows > 0) { // do interpo
|
||||
doInterpolateResult(pSql, pLocalReducer, true);
|
||||
|
@ -1334,15 +1367,15 @@ static bool doHandleLastRemainData(SSqlObj *pSql) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static void doMergeWithPrevRows(SSqlObj *pSql, int32_t numOfRes) {
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
SSqlRes * pRes = &pSql->res;
|
||||
|
||||
static void doProcessResultInNextWindow(SSqlObj *pSql, int32_t numOfRes) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
SLocalReducer *pLocalReducer = pRes->pLocalReducer;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
for (int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) {
|
||||
SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
SQLFunctionCtx *pCtx = &pLocalReducer->pCtx[k];
|
||||
|
||||
pCtx->aOutputBuf += pCtx->outputBytes * numOfRes;
|
||||
|
@ -1359,24 +1392,24 @@ static void doMergeWithPrevRows(SSqlObj *pSql, int32_t numOfRes) {
|
|||
int32_t tscDoLocalreduce(SSqlObj *pSql) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
|
||||
tscResetForNextRetrieve(pRes);
|
||||
|
||||
|
||||
if (pSql->signature != pSql || pRes == NULL || pRes->pLocalReducer == NULL) { // all data has been processed
|
||||
tscTrace("%s call the drop local reducer", __FUNCTION__);
|
||||
|
||||
tscDestroyLocalReducer(pSql);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SLocalReducer *pLocalReducer = pRes->pLocalReducer;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
// set the data merge in progress
|
||||
int32_t prevStatus =
|
||||
atomic_val_compare_exchange_32(&pLocalReducer->status, TSC_LOCALREDUCE_READY, TSC_LOCALREDUCE_IN_PROGRESS);
|
||||
if (prevStatus != TSC_LOCALREDUCE_READY || pLocalReducer == NULL) {
|
||||
assert(prevStatus == TSC_LOCALREDUCE_TOBE_FREED); // it is in tscDestroyLocalReducer function already
|
||||
assert(prevStatus == TSC_LOCALREDUCE_TOBE_FREED); // it is in tscDestroyLocalReducer function already
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1474,8 +1507,7 @@ int32_t tscDoLocalreduce(SSqlObj *pSql) {
|
|||
* if the previous group does NOT generate any result (pResBuf->numOfElems == 0),
|
||||
* continue to process results instead of return results.
|
||||
*/
|
||||
if ((!sameGroup && pResBuf->numOfElems > 0) ||
|
||||
(pResBuf->numOfElems == pLocalReducer->resColModel->capacity)) {
|
||||
if ((!sameGroup && pResBuf->numOfElems > 0) || (pResBuf->numOfElems == pLocalReducer->resColModel->capacity)) {
|
||||
// does not belong to the same group
|
||||
bool notSkipped = doGenerateFinalResults(pSql, pLocalReducer, !sameGroup);
|
||||
|
||||
|
@ -1528,7 +1560,7 @@ int32_t tscDoLocalreduce(SSqlObj *pSql) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
} else { // result buffer is not full
|
||||
doMergeWithPrevRows(pSql, numOfRes);
|
||||
doProcessResultInNextWindow(pSql, numOfRes);
|
||||
savePreviousRow(pLocalReducer, tmpBuffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ void tscGetConnToVnode(SSqlObj *pSql, uint8_t *pCode) {
|
|||
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pCmd->clauseIndex, 0);
|
||||
|
||||
|
||||
if (UTIL_METER_IS_SUPERTABLE(pMeterMetaInfo)) { // multiple vnode query
|
||||
SVnodeSidList *vnodeList = tscGetVnodeSidList(pMeterMetaInfo->pMetricMeta, pMeterMetaInfo->vnodeIndex);
|
||||
if (vnodeList != NULL) {
|
||||
|
@ -254,6 +254,8 @@ void tscGetConnToVnode(SSqlObj *pSql, uint8_t *pCode) {
|
|||
|
||||
while (pSql->retry < pSql->maxRetry) {
|
||||
(pSql->retry)++;
|
||||
pSql->index = pSql->index%TSDB_VNODES_SUPPORT;
|
||||
|
||||
char ipstr[40] = {0};
|
||||
if (pVPeersDesc[pSql->index].ip == 0) {
|
||||
/*
|
||||
|
@ -643,19 +645,23 @@ int32_t tscLaunchJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSubquerySu
|
|||
tscColumnBaseInfoUpdateTableIndex(&pNewQueryInfo->colList, 0);
|
||||
tscColumnBaseInfoCopy(&pSupporter->colList, &pNewQueryInfo->colList, 0);
|
||||
|
||||
tscSqlExprCopy(&pSupporter->exprsInfo, &pNewQueryInfo->exprsInfo, pSupporter->uid);
|
||||
|
||||
tscSqlExprCopy(&pSupporter->exprsInfo, &pNewQueryInfo->exprsInfo, pSupporter->uid, false);
|
||||
tscFieldInfoCopyAll(&pSupporter->fieldsInfo, &pNewQueryInfo->fieldsInfo);
|
||||
|
||||
tscTagCondCopy(&pSupporter->tagCond, &pNewQueryInfo->tagCond);
|
||||
|
||||
pNew->cmd.numOfCols = 0;
|
||||
pNewQueryInfo->nAggTimeInterval = 0;
|
||||
pNewQueryInfo->intervalTime = 0;
|
||||
memset(&pNewQueryInfo->limit, 0, sizeof(SLimitVal));
|
||||
|
||||
// backup the data and clear it in the sqlcmd object
|
||||
pSupporter->groupbyExpr = pNewQueryInfo->groupbyExpr;
|
||||
memset(&pNewQueryInfo->groupbyExpr, 0, sizeof(SSqlGroupbyExpr));
|
||||
|
||||
// this data needs to be transfer to support struct
|
||||
pNewQueryInfo->fieldsInfo.numOfOutputCols = 0;
|
||||
pNewQueryInfo->exprsInfo.numOfExprs = 0;
|
||||
|
||||
// set the ts,tags that involved in join, as the output column of intermediate result
|
||||
tscClearSubqueryInfo(&pNew->cmd);
|
||||
|
||||
|
@ -901,7 +907,7 @@ int tscLaunchSTableSubqueries(SSqlObj *pSql) {
|
|||
|
||||
tExtMemBuffer ** pMemoryBuf = NULL;
|
||||
tOrderDescriptor *pDesc = NULL;
|
||||
SColumnModel * pModel = NULL;
|
||||
SColumnModel * pModel = NULL;
|
||||
|
||||
pRes->qhandle = 1; // hack the qhandle check
|
||||
|
||||
|
@ -1318,8 +1324,6 @@ void tscKillMetricQuery(SSqlObj *pSql) {
|
|||
taosStopRpcConn(pSql->pSubs[i]->thandle);
|
||||
}
|
||||
|
||||
pSql->numOfSubs = 0;
|
||||
|
||||
/*
|
||||
* 1. if the subqueries are not launched or partially launched, we need to waiting the launched
|
||||
* query return to successfully free allocated resources.
|
||||
|
@ -1537,7 +1541,7 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
|||
|
||||
int32_t srcColListSize = pQueryInfo->colList.numOfCols * sizeof(SColumnInfo);
|
||||
|
||||
int32_t exprSize = sizeof(SSqlFuncExprMsg) * pQueryInfo->fieldsInfo.numOfOutputCols;
|
||||
int32_t exprSize = sizeof(SSqlFuncExprMsg) * pQueryInfo->exprsInfo.numOfExprs;
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfoFromQueryInfo(pQueryInfo, 0);
|
||||
|
||||
// meter query without tags values
|
||||
|
@ -1546,11 +1550,10 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
|
|||
}
|
||||
|
||||
SMetricMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta;
|
||||
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pMeterMetaInfo->vnodeIndex);
|
||||
|
||||
int32_t meterInfoSize = (pMetricMeta->tagLen + sizeof(SMeterSidExtInfo)) * pVnodeSidList->numOfSids;
|
||||
int32_t outputColumnSize = pQueryInfo->fieldsInfo.numOfOutputCols * sizeof(SSqlFuncExprMsg);
|
||||
int32_t outputColumnSize = pQueryInfo->exprsInfo.numOfExprs * sizeof(SSqlFuncExprMsg);
|
||||
|
||||
int32_t size = meterInfoSize + outputColumnSize + srcColListSize + exprSize + MIN_QUERY_MSG_PKT_SIZE;
|
||||
if (pQueryInfo->tsBuf != NULL) {
|
||||
|
@ -1566,7 +1569,7 @@ static char *doSerializeTableInfo(SSqlObj *pSql, int32_t numOfMeters, int32_t vn
|
|||
SMeterMeta * pMeterMeta = pMeterMetaInfo->pMeterMeta;
|
||||
SMetricMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta;
|
||||
|
||||
tscTrace("%p vid:%d, query on %d meters", pSql, htons(vnodeId), numOfMeters);
|
||||
tscTrace("%p vid:%d, query on %d meters", pSql, vnodeId, numOfMeters);
|
||||
if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) {
|
||||
#ifdef _DEBUG_VIEW
|
||||
tscTrace("%p sid:%d, uid:%" PRIu64, pSql, pMeterMetaInfo->pMeterMeta->sid, pMeterMetaInfo->pMeterMeta->uid);
|
||||
|
@ -1683,12 +1686,12 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
pQueryMsg->nAggTimeInterval = htobe64(pQueryInfo->nAggTimeInterval);
|
||||
pQueryMsg->intervalTime = htobe64(pQueryInfo->intervalTime);
|
||||
pQueryMsg->intervalTimeUnit = pQueryInfo->intervalTimeUnit;
|
||||
pQueryMsg->slidingTime = htobe64(pQueryInfo->nSlidingTime);
|
||||
pQueryMsg->slidingTime = htobe64(pQueryInfo->slidingTime);
|
||||
|
||||
if (pQueryInfo->nAggTimeInterval < 0) {
|
||||
tscError("%p illegal value of aggregation time interval in query msg: %ld", pSql, pQueryInfo->nAggTimeInterval);
|
||||
if (pQueryInfo->intervalTime < 0) {
|
||||
tscError("%p illegal value of aggregation time interval in query msg: %ld", pSql, pQueryInfo->intervalTime);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1768,7 +1771,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
|
||||
SSqlFuncExprMsg *pSqlFuncExpr = (SSqlFuncExprMsg *)pMsg;
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
for (int32_t i = 0; i < tscSqlExprNumOfExprs(pQueryInfo); ++i) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
if (pExpr->functionId == TSDB_FUNC_ARITHM) {
|
||||
|
@ -1862,6 +1865,9 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
|
||||
*((int16_t *)pMsg) += pCol->flag;
|
||||
pMsg += sizeof(pCol->flag);
|
||||
|
||||
memcpy(pMsg, pCol->name, tListLen(pCol->name));
|
||||
pMsg += tListLen(pCol->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2491,16 +2497,8 @@ static int tscSetResultPointer(SQueryInfo *pQueryInfo, SSqlRes *pRes) {
|
|||
}
|
||||
|
||||
for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
int16_t offset = tscFieldInfoGetOffset(pQueryInfo, i);
|
||||
|
||||
pRes->bytes[i] = pField->bytes;
|
||||
// if (pQueryInfo->order.order == TSQL_SO_DESC) {
|
||||
// pRes->bytes[i] = -pRes->bytes[i];
|
||||
// pRes->tsrow[i] = ((pRes->data + offset * pRes->numOfRows) + (pRes->numOfRows - 1) * pField->bytes);
|
||||
// } else {
|
||||
pRes->tsrow[i] = (pRes->data + offset * pRes->numOfRows);
|
||||
// }
|
||||
int16_t offset = tscFieldInfoGetOffset(pQueryInfo, i);
|
||||
pRes->tsrow[i] = (pRes->data + offset * pRes->numOfRows);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2725,8 +2723,10 @@ static int32_t tscEstimateMetricMetaMsgSize(SSqlCmd *pCmd) {
|
|||
|
||||
int32_t joinCondLen = (TSDB_METER_ID_LEN + sizeof(int16_t)) * 2;
|
||||
int32_t elemSize = sizeof(SMetricMetaElemMsg) * pQueryInfo->numOfTables;
|
||||
|
||||
int32_t colSize = pQueryInfo->groupbyExpr.numOfGroupCols*sizeof(SColIndexEx);
|
||||
|
||||
int32_t len = tagLen + joinCondLen + elemSize + defaultSize;
|
||||
int32_t len = tagLen + joinCondLen + elemSize + colSize + defaultSize;
|
||||
|
||||
return MAX(len, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||
}
|
||||
|
@ -2795,7 +2795,7 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
int32_t condLen = 0;
|
||||
if (pTagCond->numOfTagCond > 0) {
|
||||
SCond *pCond = tsGetMetricQueryCondPos(pTagCond, uid);
|
||||
if (pCond != NULL) {
|
||||
if (pCond != NULL && pCond->cond != NULL) {
|
||||
condLen = strlen(pCond->cond) + 1;
|
||||
|
||||
bool ret = taosMbsToUcs4(pCond->cond, condLen, pMsg, condLen * TSDB_NCHAR_SIZE);
|
||||
|
@ -2817,11 +2817,14 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
offset = pMsg - (char *)pMetaMsg;
|
||||
|
||||
pElem->tableCond = htonl(offset);
|
||||
|
||||
uint32_t len = strlen(pTagCond->tbnameCond.cond);
|
||||
|
||||
uint32_t len = 0;
|
||||
if (pTagCond->tbnameCond.cond != NULL) {
|
||||
len = strlen(pTagCond->tbnameCond.cond);
|
||||
memcpy(pMsg, pTagCond->tbnameCond.cond, len);
|
||||
}
|
||||
|
||||
pElem->tableCondLen = htonl(len);
|
||||
|
||||
memcpy(pMsg, pTagCond->tbnameCond.cond, len);
|
||||
pMsg += len;
|
||||
}
|
||||
|
||||
|
@ -2851,6 +2854,7 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pDestCol->colIdx = htons(pCol->colIdx);
|
||||
pDestCol->colId = htons(pDestCol->colId);
|
||||
pDestCol->flag = htons(pDestCol->flag);
|
||||
strncpy(pDestCol->name, pCol->name, tListLen(pCol->name));
|
||||
|
||||
pMsg += sizeof(SColIndexEx);
|
||||
}
|
||||
|
@ -3288,6 +3292,7 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
|||
int32_t size = pMeta->numOfColumns * sizeof(SSchema) + sizeof(SMeterMeta);
|
||||
pMeterMetaInfo->pMeterMeta =
|
||||
(SMeterMeta *)taosAddDataIntoCache(tscCacheHandle, key, (char *)pMeta, size, tsMeterMetaKeepTimer);
|
||||
|
||||
pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutputCols;
|
||||
SSchema *pMeterSchema = tsGetSchema(pMeterMetaInfo->pMeterMeta);
|
||||
|
||||
|
@ -3298,6 +3303,9 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
|||
index.columnIndex = i;
|
||||
tscColumnBaseInfoInsert(pQueryInfo, &index);
|
||||
tscFieldInfoSetValFromSchema(&pQueryInfo->fieldsInfo, i, &pMeterSchema[i]);
|
||||
|
||||
pQueryInfo->fieldsInfo.pSqlExpr[i] = tscSqlExprInsert(pQueryInfo, i, TSDB_FUNC_TS_DUMMY, &index,
|
||||
pMeterSchema[i].type, pMeterSchema[i].bytes, pMeterSchema[i].bytes);
|
||||
}
|
||||
|
||||
tscFieldInfoCalOffset(pQueryInfo);
|
||||
|
|
|
@ -13,8 +13,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include <tast.h>
|
||||
#include "hash.h"
|
||||
#include "os.h"
|
||||
#include "tcache.h"
|
||||
#include "tlog.h"
|
||||
#include "tnote.h"
|
||||
|
@ -200,7 +201,7 @@ int taos_query_imp(STscObj *pObj, SSqlObj *pSql) {
|
|||
taosCleanUpHashTable(pSql->pTableHashList);
|
||||
pSql->pTableHashList = NULL;
|
||||
}
|
||||
|
||||
|
||||
tscDump("%p pObj:%p, SQL: %s", pSql, pObj, pSql->sqlstr);
|
||||
|
||||
pRes->code = (uint8_t)tsParseSql(pSql, false);
|
||||
|
@ -367,9 +368,7 @@ int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) {
|
|||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
// pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i, pQueryInfo->order) +
|
||||
// pRes->bytes[i] * (1 - pQueryInfo->order.order) * (pRes->numOfRows - 1);
|
||||
pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i, pQueryInfo->order);
|
||||
pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i);
|
||||
}
|
||||
|
||||
*rows = pRes->tsrow;
|
||||
|
@ -377,54 +376,115 @@ int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) {
|
|||
return (pQueryInfo->order.order == TSQL_SO_DESC) ? pRes->numOfRows : -pRes->numOfRows;
|
||||
}
|
||||
|
||||
static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pField) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
if (isNull(pRes->tsrow[columnIndex], pField->type)) {
|
||||
pRes->tsrow[columnIndex] = NULL;
|
||||
} else if (pField->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
// convert unicode to native code in a temporary buffer extra one byte for terminated symbol
|
||||
if (pRes->buffer[columnIndex] == NULL) {
|
||||
pRes->buffer[columnIndex] = malloc(pField->bytes + TSDB_NCHAR_SIZE);
|
||||
}
|
||||
|
||||
/* string terminated char for binary data*/
|
||||
memset(pRes->buffer[columnIndex], 0, pField->bytes + TSDB_NCHAR_SIZE);
|
||||
|
||||
if (taosUcs4ToMbs(pRes->tsrow[columnIndex], pField->bytes, pRes->buffer[columnIndex])) {
|
||||
pRes->tsrow[columnIndex] = pRes->buffer[columnIndex];
|
||||
} else {
|
||||
tscError("%p charset:%s to %s. val:%ls convert failed.", pSql, DEFAULT_UNICODE_ENCODEC, tsCharset, pRes->tsrow);
|
||||
pRes->tsrow[columnIndex] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *getArithemicInputSrc(void *param, char *name, int32_t colId) {
|
||||
SArithmeticSupport *pSupport = (SArithmeticSupport *)param;
|
||||
SSqlFunctionExpr * pExpr = pSupport->pExpr;
|
||||
|
||||
int32_t index = -1;
|
||||
for (int32_t i = 0; i < pExpr->pBinExprInfo.numOfCols; ++i) {
|
||||
if (strcmp(name, pExpr->pBinExprInfo.pReqColumns[i].name) == 0) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(index >= 0 && index < pExpr->pBinExprInfo.numOfCols);
|
||||
return pSupport->data[index] + pSupport->offset * pSupport->elemSize[index];
|
||||
}
|
||||
|
||||
static void **doSetResultRowData(SSqlObj *pSql) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
|
||||
assert(pRes->row >= 0 && pRes->row <= pRes->numOfRows);
|
||||
|
||||
|
||||
if (pRes->row >= pRes->numOfRows) { // all the results has returned to invoker
|
||||
tfree(pRes->tsrow);
|
||||
return pRes->tsrow;
|
||||
}
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
//todo refactor move away
|
||||
for(int32_t k = 0; k < pQueryInfo->exprsInfo.numOfExprs; ++k) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
|
||||
if (k > 0) {
|
||||
SSqlExpr* pPrev = tscSqlExprGet(pQueryInfo, k - 1);
|
||||
pExpr->offset = pPrev->offset + pPrev->resBytes;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t num = 0;
|
||||
for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i, pQueryInfo->order) + pRes->bytes[i] * pRes->row;
|
||||
for (int i = 0; i < tscNumOfFields(pQueryInfo); ++i) {
|
||||
if (pQueryInfo->fieldsInfo.pSqlExpr[i] != NULL) {
|
||||
SSqlExpr* pExpr = pQueryInfo->fieldsInfo.pSqlExpr[i];
|
||||
pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i) + pExpr->resBytes * pRes->row;
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// primary key column cannot be null in interval query, no need to check
|
||||
if (i == 0 && pQueryInfo->nAggTimeInterval > 0) {
|
||||
if (i == 0 && pQueryInfo->intervalTime > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
if (isNull(pRes->tsrow[i], pField->type)) {
|
||||
pRes->tsrow[i] = NULL;
|
||||
} else if (pField->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
// convert unicode to native code in a temporary buffer extra one byte for terminated symbol
|
||||
if (pRes->buffer[num] == NULL) {
|
||||
pRes->buffer[num] = malloc(pField->bytes + TSDB_NCHAR_SIZE);
|
||||
}
|
||||
transferNcharData(pSql, i, pField);
|
||||
|
||||
/* string terminated char for binary data*/
|
||||
memset(pRes->buffer[num], 0, pField->bytes + TSDB_NCHAR_SIZE);
|
||||
|
||||
if (taosUcs4ToMbs(pRes->tsrow[i], pField->bytes, pRes->buffer[num])) {
|
||||
pRes->tsrow[i] = pRes->buffer[num];
|
||||
} else {
|
||||
tscError("%p charset:%s to %s. val:%ls convert failed.", pSql, DEFAULT_UNICODE_ENCODEC, tsCharset, pRes->tsrow);
|
||||
pRes->tsrow[i] = NULL;
|
||||
// calculate the result from serveral other columns
|
||||
if (pQueryInfo->fieldsInfo.pExpr != NULL && pQueryInfo->fieldsInfo.pExpr[i] != NULL) {
|
||||
SArithmeticSupport *sas = (SArithmeticSupport *)calloc(1, sizeof(SArithmeticSupport));
|
||||
sas->offset = 0;
|
||||
sas->pExpr = pQueryInfo->fieldsInfo.pExpr[i];
|
||||
|
||||
sas->numOfCols = sas->pExpr->pBinExprInfo.numOfCols;
|
||||
|
||||
if (pRes->buffer[i] == NULL) {
|
||||
pRes->buffer[i] = malloc(tscFieldInfoGetField(pQueryInfo, i)->bytes);
|
||||
}
|
||||
|
||||
num++;
|
||||
for(int32_t k = 0; k < sas->numOfCols; ++k) {
|
||||
int32_t columnIndex = sas->pExpr->pBinExprInfo.pReqColumns[k].colIdxInBuf;
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, columnIndex);
|
||||
|
||||
sas->elemSize[k] = pExpr->resBytes;
|
||||
sas->data[k] = (pRes->data + pRes->numOfRows* pExpr->offset) + pRes->row*pExpr->resBytes;
|
||||
}
|
||||
|
||||
tSQLBinaryExprCalcTraverse(sas->pExpr->pBinExprInfo.pBinExpr, 1, pRes->buffer[i], sas, TSQL_SO_ASC, getArithemicInputSrc);
|
||||
pRes->tsrow[i] = pRes->buffer[i];
|
||||
|
||||
free(sas); //todo optimization
|
||||
}
|
||||
}
|
||||
|
||||
assert(num <= pQueryInfo->fieldsInfo.numOfOutputCols);
|
||||
|
||||
pRes->row++; // index increase one-step
|
||||
|
||||
pRes->row++; // index increase one-step
|
||||
return pRes->tsrow;
|
||||
}
|
||||
|
||||
|
@ -466,7 +526,7 @@ static bool tscHashRemainDataInSubqueryResultSet(SSqlObj *pSql) {
|
|||
if (pSql->pSubs[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
SSqlRes * pRes1 = &pSql->pSubs[i]->res;
|
||||
SQueryInfo *pQueryInfo1 = tscGetQueryInfoDetail(&pSql->pSubs[i]->cmd, 0);
|
||||
|
||||
|
@ -502,11 +562,10 @@ static void **tscBuildResFromSubqueries(SSqlObj *pSql) {
|
|||
|
||||
if (numOfTableHasRes >= 2) { // do merge result
|
||||
|
||||
success = (doSetResultRowData(pSql->pSubs[0]) != NULL) &&
|
||||
(doSetResultRowData(pSql->pSubs[1]) != NULL);
|
||||
// TSKEY key1 = *(TSKEY *)pRes1->tsrow[0];
|
||||
// TSKEY key2 = *(TSKEY *)pRes2->tsrow[0];
|
||||
// printf("first:%" PRId64 ", second:%" PRId64 "\n", key1, key2);
|
||||
success = (doSetResultRowData(pSql->pSubs[0]) != NULL) && (doSetResultRowData(pSql->pSubs[1]) != NULL);
|
||||
// TSKEY key1 = *(TSKEY *)pRes1->tsrow[0];
|
||||
// TSKEY key2 = *(TSKEY *)pRes2->tsrow[0];
|
||||
// printf("first:%" PRId64 ", second:%" PRId64 "\n", key1, key2);
|
||||
} else { // only one subquery
|
||||
SSqlObj *pSub = pSql->pSubs[0];
|
||||
if (pSub == NULL) {
|
||||
|
@ -596,7 +655,7 @@ TAOS_ROW taos_fetch_row_impl(TAOS_RES *res) {
|
|||
|
||||
tscProcessSql(pSql); // retrieve data from virtual node
|
||||
|
||||
//if failed to retrieve data from current virtual node, try next one if exists
|
||||
// if failed to retrieve data from current virtual node, try next one if exists
|
||||
if (hasMoreVnodesToTry(pSql)) {
|
||||
tscTryQueryNextVnode(pSql, NULL);
|
||||
}
|
||||
|
@ -638,7 +697,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
|||
// current subclause is completed, try the next subclause
|
||||
while (rows == NULL && pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
||||
tscTryQueryNextClause(pSql, NULL);
|
||||
|
||||
|
||||
// if the rows is not NULL, return immediately
|
||||
rows = taos_fetch_row_impl(res);
|
||||
}
|
||||
|
@ -701,7 +760,7 @@ int taos_select_db(TAOS *taos, const char *db) {
|
|||
return taos_query(taos, sql);
|
||||
}
|
||||
|
||||
void taos_free_result_imp(TAOS_RES* res, int keepCmd) {
|
||||
void taos_free_result_imp(TAOS_RES *res, int keepCmd) {
|
||||
if (res == NULL) return;
|
||||
|
||||
SSqlObj *pSql = (SSqlObj *)res;
|
||||
|
@ -755,7 +814,7 @@ void taos_free_result_imp(TAOS_RES* res, int keepCmd) {
|
|||
pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
|
||||
|
||||
tscTrace("%p code:%d, numOfRows:%d, command:%d", pSql, pRes->code, pRes->numOfRows, pCmd->command);
|
||||
|
||||
|
||||
void *fp = pSql->fp;
|
||||
if (fp != NULL) {
|
||||
pSql->freed = 1;
|
||||
|
@ -804,9 +863,7 @@ void taos_free_result_imp(TAOS_RES* res, int keepCmd) {
|
|||
}
|
||||
}
|
||||
|
||||
void taos_free_result(TAOS_RES *res) {
|
||||
taos_free_result_imp(res, 0);
|
||||
}
|
||||
void taos_free_result(TAOS_RES *res) { taos_free_result_imp(res, 0); }
|
||||
|
||||
int taos_errno(TAOS *taos) {
|
||||
STscObj *pObj = (STscObj *)taos;
|
||||
|
@ -822,26 +879,24 @@ int taos_errno(TAOS *taos) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static bool validErrorCode(int32_t code) {
|
||||
return code >= TSDB_CODE_SUCCESS && code < TSDB_CODE_MAX_ERROR_CODE;
|
||||
}
|
||||
static bool validErrorCode(int32_t code) { return code >= TSDB_CODE_SUCCESS && code < TSDB_CODE_MAX_ERROR_CODE; }
|
||||
|
||||
/*
|
||||
* In case of invalid sql error, additional information is attached to explain
|
||||
* why the sql is invalid
|
||||
*/
|
||||
static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd* pCmd) {
|
||||
static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) {
|
||||
if (code != TSDB_CODE_INVALID_SQL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = strlen(pCmd->payload);
|
||||
|
||||
char* z = NULL;
|
||||
|
||||
char *z = NULL;
|
||||
if (len > 0) {
|
||||
z = strstr (pCmd->payload, "invalid SQL");
|
||||
z = strstr(pCmd->payload, "invalid SQL");
|
||||
}
|
||||
|
||||
|
||||
return z != NULL;
|
||||
}
|
||||
|
||||
|
@ -851,12 +906,12 @@ char *taos_errstr(TAOS *taos) {
|
|||
|
||||
if (pObj == NULL || pObj->signature != pObj) return tsError[globalCode];
|
||||
|
||||
SSqlObj* pSql = pObj->pSql;
|
||||
|
||||
SSqlObj *pSql = pObj->pSql;
|
||||
|
||||
if (validErrorCode(pSql->res.code)) {
|
||||
code = pSql->res.code;
|
||||
} else {
|
||||
code = TSDB_CODE_OTHERS; //unknown error
|
||||
code = TSDB_CODE_OTHERS; // unknown error
|
||||
}
|
||||
|
||||
if (hasAdditionalErrorInfo(code, &pSql->cmd)) {
|
||||
|
@ -954,14 +1009,14 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
size_t xlen = 0;
|
||||
for (xlen = 0; xlen <= fields[i].bytes; xlen++) {
|
||||
char c = ((char*)row[i])[xlen];
|
||||
if (c == 0) break;
|
||||
str[len++] = c;
|
||||
}
|
||||
str[len] = 0;
|
||||
} break;
|
||||
size_t xlen = 0;
|
||||
for (xlen = 0; xlen <= fields[i].bytes; xlen++) {
|
||||
char c = ((char *)row[i])[xlen];
|
||||
if (c == 0) break;
|
||||
str[len++] = c;
|
||||
}
|
||||
str[len] = 0;
|
||||
} break;
|
||||
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
len += sprintf(str + len, "%" PRId64, *((int64_t *)row[i]));
|
||||
|
|
|
@ -246,8 +246,6 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
|||
int32_t retry = tsProjectExecInterval;
|
||||
tscError("%p stream:%p, retrieve no data, code:%d, retry in %" PRId64 "ms", pSql, pStream, numOfRows, retry);
|
||||
|
||||
tscClearSqlMetaInfoForce(&(pStream->pSql->cmd));
|
||||
|
||||
tscSetRetryTimer(pStream, pStream->pSql, retry);
|
||||
return;
|
||||
}
|
||||
|
@ -381,41 +379,41 @@ static void tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
|||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||
|
||||
if (pQueryInfo->nAggTimeInterval < minIntervalTime) {
|
||||
if (pQueryInfo->intervalTime < minIntervalTime) {
|
||||
tscWarn("%p stream:%p, original sample interval:%ld too small, reset to:%" PRId64 "", pSql, pStream,
|
||||
pQueryInfo->nAggTimeInterval, minIntervalTime);
|
||||
pQueryInfo->nAggTimeInterval = minIntervalTime;
|
||||
pQueryInfo->intervalTime, minIntervalTime);
|
||||
pQueryInfo->intervalTime = minIntervalTime;
|
||||
}
|
||||
|
||||
pStream->interval = pQueryInfo->nAggTimeInterval; // it shall be derived from sql string
|
||||
pStream->interval = pQueryInfo->intervalTime; // it shall be derived from sql string
|
||||
|
||||
if (pQueryInfo->nSlidingTime == 0) {
|
||||
pQueryInfo->nSlidingTime = pQueryInfo->nAggTimeInterval;
|
||||
if (pQueryInfo->slidingTime == 0) {
|
||||
pQueryInfo->slidingTime = pQueryInfo->intervalTime;
|
||||
}
|
||||
|
||||
int64_t minSlidingTime =
|
||||
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinSlidingTime * 1000L : tsMinSlidingTime;
|
||||
|
||||
if (pQueryInfo->nSlidingTime == -1) {
|
||||
pQueryInfo->nSlidingTime = pQueryInfo->nAggTimeInterval;
|
||||
} else if (pQueryInfo->nSlidingTime < minSlidingTime) {
|
||||
if (pQueryInfo->slidingTime == -1) {
|
||||
pQueryInfo->slidingTime = pQueryInfo->intervalTime;
|
||||
} else if (pQueryInfo->slidingTime < minSlidingTime) {
|
||||
tscWarn("%p stream:%p, original sliding value:%" PRId64 " too small, reset to:%" PRId64 "", pSql, pStream,
|
||||
pQueryInfo->nSlidingTime, minSlidingTime);
|
||||
pQueryInfo->slidingTime, minSlidingTime);
|
||||
|
||||
pQueryInfo->nSlidingTime = minSlidingTime;
|
||||
pQueryInfo->slidingTime = minSlidingTime;
|
||||
}
|
||||
|
||||
if (pQueryInfo->nSlidingTime > pQueryInfo->nAggTimeInterval) {
|
||||
if (pQueryInfo->slidingTime > pQueryInfo->intervalTime) {
|
||||
tscWarn("%p stream:%p, sliding value:%" PRId64 " can not be larger than interval range, reset to:%" PRId64 "", pSql, pStream,
|
||||
pQueryInfo->nSlidingTime, pQueryInfo->nAggTimeInterval);
|
||||
pQueryInfo->slidingTime, pQueryInfo->intervalTime);
|
||||
|
||||
pQueryInfo->nSlidingTime = pQueryInfo->nAggTimeInterval;
|
||||
pQueryInfo->slidingTime = pQueryInfo->intervalTime;
|
||||
}
|
||||
|
||||
pStream->slidingTime = pQueryInfo->nSlidingTime;
|
||||
pStream->slidingTime = pQueryInfo->slidingTime;
|
||||
|
||||
pQueryInfo->nAggTimeInterval = 0; // clear the interval value to avoid the force time window split by query processor
|
||||
pQueryInfo->nSlidingTime = 0;
|
||||
pQueryInfo->intervalTime = 0; // clear the interval value to avoid the force time window split by query processor
|
||||
pQueryInfo->slidingTime = 0;
|
||||
}
|
||||
|
||||
static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "tsclient.h"
|
||||
#include "tsqldef.h"
|
||||
#include "ttimer.h"
|
||||
#include "tast.h"
|
||||
|
||||
/*
|
||||
* the detailed information regarding metric meta key is:
|
||||
|
@ -64,7 +65,7 @@ void tscGetMetricMetaCacheKey(SQueryInfo* pQueryInfo, char* str, uint64_t uid) {
|
|||
size_t redundantLen = 20;
|
||||
|
||||
size_t bufSize = strlen(pMeterMetaInfo->name) + tbnameCondLen + strlen(join) + strlen(tagIdBuf);
|
||||
if (cond != NULL) {
|
||||
if (cond != NULL && cond->cond != NULL) {
|
||||
bufSize += strlen(cond->cond);
|
||||
}
|
||||
|
||||
|
@ -72,7 +73,7 @@ void tscGetMetricMetaCacheKey(SQueryInfo* pQueryInfo, char* str, uint64_t uid) {
|
|||
char* tmp = calloc(1, bufSize);
|
||||
|
||||
int32_t keyLen = snprintf(tmp, bufSize, "%s,%s,%s,%d,%s,[%s],%d", pMeterMetaInfo->name,
|
||||
(cond != NULL ? cond->cond : NULL), (tbnameCondLen > 0 ? pTagCond->tbnameCond.cond : NULL),
|
||||
((cond != NULL && cond->cond != NULL) ? cond->cond : NULL), (tbnameCondLen > 0 ? pTagCond->tbnameCond.cond : NULL),
|
||||
pTagCond->relType, join, tagIdBuf, pQueryInfo->groupbyExpr.orderType);
|
||||
|
||||
assert(keyLen <= bufSize);
|
||||
|
@ -202,6 +203,9 @@ SMeterSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx) {
|
|||
tscError("illegal sidIdx:%d, reset to 0, sidIdx range:%d-%d", idx, 0, sidRange);
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
assert(pSidList->pSidExtInfoList[idx] >= 0);
|
||||
|
||||
return (SMeterSidExtInfo*)(pSidList->pSidExtInfoList[idx] + (char*)pSidList);
|
||||
}
|
||||
|
||||
|
@ -335,35 +339,17 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo) {
|
|||
tfree(pQueryInfo->defaultVal);
|
||||
}
|
||||
|
||||
void tscClearSqlMetaInfoForce(SSqlCmd* pCmd) {
|
||||
/* remove the metermeta/metricmeta in cache */
|
||||
// taosRemoveDataFromCache(tscCacheHandle, (void**)&(pCmd->pMeterMeta), true);
|
||||
// taosRemoveDataFromCache(tscCacheHandle, (void**)&(pCmd->pMetricMeta), true);
|
||||
}
|
||||
|
||||
int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
|
||||
if (pRes->tsrow == NULL) {
|
||||
pRes->numOfnchar = 0;
|
||||
|
||||
int32_t numOfOutputCols = pQueryInfo->fieldsInfo.numOfOutputCols;
|
||||
for (int32_t i = 0; i < numOfOutputCols; ++i) {
|
||||
TAOS_FIELD* pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
if (pField->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
pRes->numOfnchar++;
|
||||
}
|
||||
}
|
||||
pRes->numOfCols = numOfOutputCols;
|
||||
|
||||
pRes->tsrow = calloc(1, (POINTER_BYTES + sizeof(short)) * numOfOutputCols + POINTER_BYTES * pRes->numOfnchar);
|
||||
pRes->bytes = calloc(numOfOutputCols, sizeof(short));
|
||||
|
||||
if (pRes->numOfnchar > 0) {
|
||||
pRes->buffer = calloc(POINTER_BYTES, pRes->numOfnchar);
|
||||
}
|
||||
pRes->tsrow = calloc(POINTER_BYTES, numOfOutputCols);
|
||||
pRes->buffer = calloc(POINTER_BYTES, numOfOutputCols);
|
||||
|
||||
// not enough memory
|
||||
if (pRes->tsrow == NULL || pRes->bytes == NULL || (pRes->buffer == NULL && pRes->numOfnchar > 0)) {
|
||||
if (pRes->tsrow == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) {
|
||||
tfree(pRes->tsrow);
|
||||
tfree(pRes->bytes);
|
||||
tfree(pRes->buffer);
|
||||
|
||||
pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
|
@ -376,13 +362,12 @@ int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
|
|||
|
||||
void tscDestroyResPointerInfo(SSqlRes* pRes) {
|
||||
if (pRes->buffer != NULL) {
|
||||
assert(pRes->numOfnchar > 0);
|
||||
// free all buffers containing the multibyte string
|
||||
for (int i = 0; i < pRes->numOfnchar; i++) {
|
||||
for (int i = 0; i < pRes->numOfCols; i++) {
|
||||
tfree(pRes->buffer[i]);
|
||||
}
|
||||
|
||||
pRes->numOfnchar = 0;
|
||||
pRes->numOfCols = 0;
|
||||
}
|
||||
|
||||
tfree(pRes->pRsp);
|
||||
|
@ -391,7 +376,6 @@ void tscDestroyResPointerInfo(SSqlRes* pRes) {
|
|||
tfree(pRes->pGroupRec);
|
||||
tfree(pRes->pColumnIndex);
|
||||
tfree(pRes->buffer);
|
||||
tfree(pRes->bytes);
|
||||
|
||||
pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free
|
||||
}
|
||||
|
@ -831,11 +815,18 @@ static void ensureSpace(SFieldInfo* pFieldInfo, int32_t size) {
|
|||
pFieldInfo->pFields = realloc(pFieldInfo->pFields, newSize * sizeof(TAOS_FIELD));
|
||||
memset(&pFieldInfo->pFields[oldSize], 0, inc * sizeof(TAOS_FIELD));
|
||||
|
||||
pFieldInfo->pOffset = realloc(pFieldInfo->pOffset, newSize * sizeof(int16_t));
|
||||
memset(&pFieldInfo->pOffset[oldSize], 0, inc * sizeof(int16_t));
|
||||
// pFieldInfo->pOffset = realloc(pFieldInfo->pOffset, newSize * sizeof(int16_t));
|
||||
// memset(&pFieldInfo->pOffset[oldSize], 0, inc * sizeof(int16_t));
|
||||
|
||||
pFieldInfo->pVisibleCols = realloc(pFieldInfo->pVisibleCols, newSize * sizeof(bool));
|
||||
memset(&pFieldInfo->pVisibleCols[oldSize], 0, inc * sizeof(bool));
|
||||
|
||||
pFieldInfo->pSqlExpr = realloc(pFieldInfo->pSqlExpr, POINTER_BYTES*newSize);
|
||||
pFieldInfo->pExpr = realloc(pFieldInfo->pExpr, POINTER_BYTES*newSize);
|
||||
|
||||
memset(&pFieldInfo->pSqlExpr[oldSize], 0, inc * POINTER_BYTES);
|
||||
memset(&pFieldInfo->pExpr[oldSize], 0, inc * POINTER_BYTES);
|
||||
|
||||
pFieldInfo->numOfAlloc = newSize;
|
||||
}
|
||||
}
|
||||
|
@ -844,6 +835,15 @@ static void evic(SFieldInfo* pFieldInfo, int32_t index) {
|
|||
if (index < pFieldInfo->numOfOutputCols) {
|
||||
memmove(&pFieldInfo->pFields[index + 1], &pFieldInfo->pFields[index],
|
||||
sizeof(pFieldInfo->pFields[0]) * (pFieldInfo->numOfOutputCols - index));
|
||||
|
||||
memmove(&pFieldInfo->pVisibleCols[index + 1], &pFieldInfo->pVisibleCols[index],
|
||||
sizeof(pFieldInfo->pVisibleCols[0]) * (pFieldInfo->numOfOutputCols - index));
|
||||
|
||||
memmove(&pFieldInfo->pSqlExpr[index + 1], &pFieldInfo->pSqlExpr[index],
|
||||
sizeof(pFieldInfo->pSqlExpr[0]) * (pFieldInfo->numOfOutputCols - index));
|
||||
|
||||
memmove(&pFieldInfo->pExpr[index + 1], &pFieldInfo->pExpr[index],
|
||||
sizeof(pFieldInfo->pExpr[0]) * (pFieldInfo->numOfOutputCols - index));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -868,7 +868,6 @@ void tscFieldInfoSetValFromField(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIE
|
|||
|
||||
memcpy(&pFieldInfo->pFields[index], pField, sizeof(TAOS_FIELD));
|
||||
pFieldInfo->pVisibleCols[index] = true;
|
||||
|
||||
pFieldInfo->numOfOutputCols++;
|
||||
}
|
||||
|
||||
|
@ -902,29 +901,49 @@ void tscFieldInfoSetValue(SFieldInfo* pFieldInfo, int32_t index, int8_t type, co
|
|||
pFieldInfo->numOfOutputCols++;
|
||||
}
|
||||
|
||||
void tscFieldInfoCalOffset(SQueryInfo* pQueryInfo) {
|
||||
SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo;
|
||||
pFieldInfo->pOffset[0] = 0;
|
||||
void tscFieldInfoSetExpr(SFieldInfo* pFieldInfo, int32_t index, SSqlExpr* pExpr) {
|
||||
assert(index >= 0 && index < pFieldInfo->numOfOutputCols);
|
||||
pFieldInfo->pSqlExpr[index] = pExpr;
|
||||
}
|
||||
|
||||
for (int32_t i = 1; i < pFieldInfo->numOfOutputCols; ++i) {
|
||||
pFieldInfo->pOffset[i] = pFieldInfo->pOffset[i - 1] + pFieldInfo->pFields[i - 1].bytes;
|
||||
void tscFieldInfoSetBinExpr(SFieldInfo* pFieldInfo, int32_t index, SSqlFunctionExpr* pExpr) {
|
||||
assert(index >= 0 && index < pFieldInfo->numOfOutputCols);
|
||||
pFieldInfo->pExpr[index] = pExpr;
|
||||
}
|
||||
|
||||
void tscFieldInfoCalOffset(SQueryInfo* pQueryInfo) {
|
||||
SSqlExprInfo* pExprInfo = &pQueryInfo->exprsInfo;
|
||||
pExprInfo->pExprs[0]->offset = 0;
|
||||
|
||||
for (int32_t i = 1; i < pExprInfo->numOfExprs; ++i) {
|
||||
pExprInfo->pExprs[i]->offset = pExprInfo->pExprs[i - 1]->offset + pExprInfo->pExprs[i - 1]->resBytes;
|
||||
}
|
||||
}
|
||||
|
||||
void tscFieldInfoUpdateOffsetForInterResult(SQueryInfo* pQueryInfo) {
|
||||
SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo;
|
||||
if (pFieldInfo->numOfOutputCols == 0) {
|
||||
// SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo;
|
||||
// if (pFieldInfo->numOfOutputCols == 0) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// pFieldInfo->pOffset[0] = 0;
|
||||
//
|
||||
// /*
|
||||
// * the retTypeLen is used to store the intermediate result length
|
||||
// * for potential secondary merge exists
|
||||
// */
|
||||
// for (int32_t i = 1; i < pFieldInfo->numOfOutputCols; ++i) {
|
||||
// pFieldInfo->pOffset[i] = pFieldInfo->pOffset[i - 1] + tscSqlExprGet(pQueryInfo, i - 1)->resBytes;
|
||||
// }
|
||||
SSqlExprInfo* pExprInfo = &pQueryInfo->exprsInfo;
|
||||
if (pExprInfo->numOfExprs == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
pFieldInfo->pOffset[0] = 0;
|
||||
|
||||
/*
|
||||
* the retTypeLen is used to store the intermediate result length
|
||||
* for potential secondary merge exists
|
||||
*/
|
||||
for (int32_t i = 1; i < pFieldInfo->numOfOutputCols; ++i) {
|
||||
pFieldInfo->pOffset[i] = pFieldInfo->pOffset[i - 1] + tscSqlExprGet(pQueryInfo, i - 1)->resBytes;
|
||||
|
||||
pExprInfo->pExprs[0]->offset = 0;
|
||||
|
||||
for (int32_t i = 1; i < pExprInfo->numOfExprs; ++i) {
|
||||
pExprInfo->pExprs[i]->offset = pExprInfo->pExprs[i - 1]->offset + pExprInfo->pExprs[i - 1]->resBytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -940,6 +959,8 @@ void tscFieldInfoCopy(SFieldInfo* src, SFieldInfo* dst, const int32_t* indexList
|
|||
for (int32_t i = 0; i < size; ++i) {
|
||||
assert(indexList[i] >= 0 && indexList[i] <= src->numOfOutputCols);
|
||||
tscFieldInfoSetValFromField(dst, i, &src->pFields[indexList[i]]);
|
||||
dst->pVisibleCols[i] = src->pVisibleCols[indexList[i]];
|
||||
dst->pSqlExpr[i] = src->pSqlExpr[indexList[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -948,12 +969,14 @@ void tscFieldInfoCopyAll(SFieldInfo* dst, SFieldInfo* src) {
|
|||
*dst = *src;
|
||||
|
||||
dst->pFields = malloc(sizeof(TAOS_FIELD) * dst->numOfAlloc);
|
||||
dst->pOffset = malloc(sizeof(short) * dst->numOfAlloc);
|
||||
dst->pVisibleCols = malloc(sizeof(bool) * dst->numOfAlloc);
|
||||
dst->pSqlExpr = malloc(POINTER_BYTES * dst->numOfAlloc);
|
||||
dst->pExpr = malloc(POINTER_BYTES * dst->numOfAlloc);
|
||||
|
||||
memcpy(dst->pFields, src->pFields, sizeof(TAOS_FIELD) * dst->numOfOutputCols);
|
||||
memcpy(dst->pOffset, src->pOffset, sizeof(short) * dst->numOfOutputCols);
|
||||
memcpy(dst->pVisibleCols, src->pVisibleCols, sizeof(bool) * dst->numOfOutputCols);
|
||||
memcpy(dst->pSqlExpr, src->pSqlExpr, POINTER_BYTES * dst->numOfOutputCols);
|
||||
memcpy(dst->pExpr, src->pExpr, POINTER_BYTES * dst->numOfOutputCols);
|
||||
}
|
||||
|
||||
TAOS_FIELD* tscFieldInfoGetField(SQueryInfo* pQueryInfo, int32_t index) {
|
||||
|
@ -967,11 +990,11 @@ TAOS_FIELD* tscFieldInfoGetField(SQueryInfo* pQueryInfo, int32_t index) {
|
|||
int32_t tscNumOfFields(SQueryInfo* pQueryInfo) { return pQueryInfo->fieldsInfo.numOfOutputCols; }
|
||||
|
||||
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
|
||||
if (index >= pQueryInfo->fieldsInfo.numOfOutputCols) {
|
||||
if (index >= pQueryInfo->exprsInfo.numOfExprs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pQueryInfo->fieldsInfo.pOffset[index];
|
||||
return pQueryInfo->exprsInfo.pExprs[index]->offset;
|
||||
}
|
||||
|
||||
int32_t tscFieldInfoCompare(SFieldInfo* pFieldInfo1, SFieldInfo* pFieldInfo2) {
|
||||
|
@ -995,13 +1018,16 @@ int32_t tscFieldInfoCompare(SFieldInfo* pFieldInfo1, SFieldInfo* pFieldInfo2) {
|
|||
}
|
||||
|
||||
int32_t tscGetResRowLength(SQueryInfo* pQueryInfo) {
|
||||
SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo;
|
||||
if (pFieldInfo->numOfOutputCols <= 0) {
|
||||
if (pQueryInfo->exprsInfo.numOfExprs <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pFieldInfo->pOffset[pFieldInfo->numOfOutputCols - 1] +
|
||||
pFieldInfo->pFields[pFieldInfo->numOfOutputCols - 1].bytes;
|
||||
|
||||
int32_t size = 0;
|
||||
for(int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
size += pQueryInfo->exprsInfo.pExprs[i]->resBytes;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void tscClearFieldInfo(SFieldInfo* pFieldInfo) {
|
||||
|
@ -1009,10 +1035,19 @@ void tscClearFieldInfo(SFieldInfo* pFieldInfo) {
|
|||
return;
|
||||
}
|
||||
|
||||
tfree(pFieldInfo->pOffset);
|
||||
tfree(pFieldInfo->pFields);
|
||||
tfree(pFieldInfo->pVisibleCols);
|
||||
|
||||
tfree(pFieldInfo->pSqlExpr);
|
||||
|
||||
for(int32_t i = 0; i < pFieldInfo->numOfOutputCols; ++i) {
|
||||
if (pFieldInfo->pExpr[i] != NULL) {
|
||||
tSQLBinaryExprDestroy(&pFieldInfo->pExpr[i]->pBinExprInfo.pBinExpr, NULL);
|
||||
tfree(pFieldInfo->pExpr[i]->pBinExprInfo.pReqColumns);
|
||||
tfree(pFieldInfo->pExpr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
tfree(pFieldInfo->pExpr);
|
||||
memset(pFieldInfo, 0, sizeof(SFieldInfo));
|
||||
}
|
||||
|
||||
|
@ -1050,11 +1085,12 @@ SSqlExpr* tscSqlExprInsertEmpty(SQueryInfo* pQueryInfo, int32_t index, int16_t f
|
|||
|
||||
_exprCheckSpace(pExprInfo, pExprInfo->numOfExprs + 1);
|
||||
_exprEvic(pExprInfo, index);
|
||||
|
||||
SSqlExpr* pExpr = &pExprInfo->pExprs[index];
|
||||
|
||||
SSqlExpr* pExpr = calloc(1, sizeof(SSqlExpr));
|
||||
pExpr->functionId = functionId;
|
||||
|
||||
|
||||
pExprInfo->numOfExprs++;
|
||||
pExprInfo->pExprs[index] = pExpr;
|
||||
return pExpr;
|
||||
}
|
||||
|
||||
|
@ -1067,8 +1103,9 @@ SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functi
|
|||
_exprCheckSpace(pExprInfo, pExprInfo->numOfExprs + 1);
|
||||
_exprEvic(pExprInfo, index);
|
||||
|
||||
SSqlExpr* pExpr = &pExprInfo->pExprs[index];
|
||||
|
||||
SSqlExpr* pExpr = calloc(1, sizeof(SSqlExpr));
|
||||
pExprInfo->pExprs[index] = pExpr;
|
||||
|
||||
pExpr->functionId = functionId;
|
||||
int16_t numOfCols = pMeterMetaInfo->pMeterMeta->numOfColumns;
|
||||
|
||||
|
@ -1110,7 +1147,7 @@ SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functi
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SSqlExpr* pExpr = &pExprInfo->pExprs[index];
|
||||
SSqlExpr* pExpr = pExprInfo->pExprs[index];
|
||||
|
||||
pExpr->functionId = functionId;
|
||||
|
||||
|
@ -1123,6 +1160,10 @@ SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functi
|
|||
return pExpr;
|
||||
}
|
||||
|
||||
int32_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo) {
|
||||
return pQueryInfo->exprsInfo.numOfExprs;
|
||||
}
|
||||
|
||||
void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes, int16_t tableIndex) {
|
||||
if (pExpr == NULL || argument == NULL || bytes == 0) {
|
||||
return;
|
||||
|
@ -1141,7 +1182,7 @@ SSqlExpr* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return &pQueryInfo->exprsInfo.pExprs[index];
|
||||
return pQueryInfo->exprsInfo.pExprs[index];
|
||||
}
|
||||
|
||||
void* tscSqlExprDestroy(SSqlExpr* pExpr) {
|
||||
|
@ -1153,6 +1194,8 @@ void* tscSqlExprDestroy(SSqlExpr* pExpr) {
|
|||
tVariantDestroy(&pExpr->param[i]);
|
||||
}
|
||||
|
||||
tfree(pExpr);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1164,8 +1207,8 @@ void tscSqlExprInfoDestroy(SSqlExprInfo* pExprInfo) {
|
|||
return;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < pExprInfo->numOfAlloc; ++i) {
|
||||
tscSqlExprDestroy(&pExprInfo->pExprs[i]);
|
||||
for(int32_t i = 0; i < pExprInfo->numOfExprs; ++i) {
|
||||
tscSqlExprDestroy(pExprInfo->pExprs[i]);
|
||||
}
|
||||
|
||||
tfree(pExprInfo->pExprs);
|
||||
|
@ -1175,27 +1218,40 @@ void tscSqlExprInfoDestroy(SSqlExprInfo* pExprInfo) {
|
|||
}
|
||||
|
||||
|
||||
void tscSqlExprCopy(SSqlExprInfo* dst, const SSqlExprInfo* src, uint64_t tableuid) {
|
||||
void tscSqlExprCopy(SSqlExprInfo* dst, const SSqlExprInfo* src, uint64_t tableuid, bool deepcopy) {
|
||||
if (src == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
*dst = *src;
|
||||
|
||||
dst->pExprs = calloc(dst->numOfAlloc, sizeof(SSqlExpr));
|
||||
dst->pExprs = calloc(dst->numOfAlloc, POINTER_BYTES);
|
||||
|
||||
int16_t num = 0;
|
||||
for (int32_t i = 0; i < src->numOfExprs; ++i) {
|
||||
if (src->pExprs[i].uid == tableuid) {
|
||||
dst->pExprs[num++] = src->pExprs[i];
|
||||
if (src->pExprs[i]->uid == tableuid) {
|
||||
|
||||
if (deepcopy) {
|
||||
dst->pExprs[num] = calloc(1, sizeof(SSqlExpr));
|
||||
*dst->pExprs[num] = *src->pExprs[i];
|
||||
} else {
|
||||
dst->pExprs[num] = src->pExprs[i];
|
||||
}
|
||||
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
dst->numOfExprs = num;
|
||||
for (int32_t i = 0; i < dst->numOfExprs; ++i) {
|
||||
for (int32_t j = 0; j < src->pExprs[i].numOfParams; ++j) {
|
||||
tVariantAssign(&dst->pExprs[i].param[j], &src->pExprs[i].param[j]);
|
||||
|
||||
if (deepcopy) {
|
||||
for (int32_t i = 0; i < dst->numOfExprs; ++i) {
|
||||
for (int32_t j = 0; j < src->pExprs[i]->numOfParams; ++j) {
|
||||
tVariantAssign(&dst->pExprs[i]->param[j], &src->pExprs[i]->param[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void clearVal(SColumnBase* pBase) {
|
||||
|
@ -1950,7 +2006,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
}
|
||||
|
||||
uint64_t uid = pMeterMetaInfo->pMeterMeta->uid;
|
||||
tscSqlExprCopy(&pNewQueryInfo->exprsInfo, &pQueryInfo->exprsInfo, uid);
|
||||
tscSqlExprCopy(&pNewQueryInfo->exprsInfo, &pQueryInfo->exprsInfo, uid, true);
|
||||
|
||||
int32_t numOfOutputCols = pNewQueryInfo->exprsInfo.numOfExprs;
|
||||
|
||||
|
@ -1965,7 +2021,19 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
|
||||
tscFieldInfoCopy(&pQueryInfo->fieldsInfo, &pNewQueryInfo->fieldsInfo, indexList, numOfOutputCols);
|
||||
free(indexList);
|
||||
|
||||
|
||||
// make sure the the sqlExpr for each fields is correct
|
||||
// todo handle the agg arithmetic expression
|
||||
for(int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutputCols; ++f) {
|
||||
char* name = pNewQueryInfo->fieldsInfo.pFields[f].name;
|
||||
for(int32_t k1 = 0; k1 < pNewQueryInfo->exprsInfo.numOfExprs; ++k1) {
|
||||
SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1);
|
||||
if (strcmp(name, pExpr1->aliasName) == 0) {
|
||||
pNewQueryInfo->fieldsInfo.pSqlExpr[f] = pExpr1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tscFieldInfoUpdateOffsetForInterResult(pNewQueryInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
#ifndef TDENGINE_HASH_H
|
||||
#define TDENGINE_HASH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hashutil.h"
|
||||
|
||||
#define HASH_MAX_CAPACITY (1024 * 1024 * 16)
|
||||
|
@ -64,11 +68,12 @@ int32_t taosNumElemsInHashTable(HashObj *pObj);
|
|||
|
||||
char *taosGetDataFromHashTable(HashObj *pObj, const char *key, uint32_t keyLen);
|
||||
|
||||
|
||||
void taosCleanUpHashTable(void *handle);
|
||||
|
||||
int32_t taosGetHashMaxOverflowLength(HashObj *pObj);
|
||||
|
||||
int32_t taosCheckHashTable(HashObj *pObj);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_HASH_H
|
||||
|
|
|
@ -417,6 +417,7 @@ typedef struct SColIndexEx {
|
|||
int16_t colIdx;
|
||||
int16_t colIdxInBuf;
|
||||
uint16_t flag; // denote if it is a tag or not
|
||||
char name[TSDB_COL_NAME_LEN];
|
||||
} SColIndexEx;
|
||||
|
||||
/* sql function msg, to describe the message to vnode about sql function
|
||||
|
@ -514,7 +515,7 @@ typedef struct {
|
|||
int16_t numOfCols; // the number of columns will be load from vnode
|
||||
char intervalTimeUnit; // time interval type, for revisement of interval(1d)
|
||||
|
||||
int64_t nAggTimeInterval; // time interval for aggregation, in million second
|
||||
int64_t intervalTime; // time interval for aggregation, in million second
|
||||
int64_t slidingTime; // value for sliding window
|
||||
|
||||
// tag schema, used to parse tag information in pSidExtInfo
|
||||
|
|
|
@ -103,6 +103,8 @@ void tSQLBinaryExprCalcTraverse(tSQLBinaryExpr *pExprs, int32_t numOfRows, char
|
|||
void tSQLBinaryExprTrv(tSQLBinaryExpr *pExprs, int32_t *val, int16_t *ids);
|
||||
void tQueryResultClean(tQueryResultset *pRes);
|
||||
|
||||
uint8_t getBinaryExprOptr(SSQLToken *pToken);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -14,7 +14,7 @@ typedef struct SIDList {
|
|||
int32_t* pData;
|
||||
} SIDList;
|
||||
|
||||
typedef struct SQueryResultBuf {
|
||||
typedef struct SQueryDiskbasedResultBuf {
|
||||
int32_t numOfRowsPerPage;
|
||||
int32_t numOfPages;
|
||||
int64_t totalBufSize;
|
||||
|
@ -27,7 +27,7 @@ typedef struct SQueryResultBuf {
|
|||
uint32_t numOfAllocGroupIds; // number of allocated id list
|
||||
void* idsTable; // id hash table
|
||||
SIDList* list; // for each id, there is a page id list
|
||||
} SQueryResultBuf;
|
||||
} SQueryDiskbasedResultBuf;
|
||||
|
||||
/**
|
||||
* create disk-based result buffer
|
||||
|
@ -36,7 +36,7 @@ typedef struct SQueryResultBuf {
|
|||
* @param rowSize
|
||||
* @return
|
||||
*/
|
||||
int32_t createResultBuf(SQueryResultBuf** pResultBuf, int32_t size, int32_t rowSize);
|
||||
int32_t createDiskbasedResultBuffer(SQueryDiskbasedResultBuf** pResultBuf, int32_t size, int32_t rowSize);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -45,14 +45,14 @@ int32_t createResultBuf(SQueryResultBuf** pResultBuf, int32_t size, int32_t rowS
|
|||
* @param pageId
|
||||
* @return
|
||||
*/
|
||||
tFilePage* getNewDataBuf(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t* pageId);
|
||||
tFilePage* getNewDataBuf(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t* pageId);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pResultBuf
|
||||
* @return
|
||||
*/
|
||||
int32_t getNumOfRowsPerPage(SQueryResultBuf* pResultBuf);
|
||||
int32_t getNumOfRowsPerPage(SQueryDiskbasedResultBuf* pResultBuf);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -60,7 +60,7 @@ int32_t getNumOfRowsPerPage(SQueryResultBuf* pResultBuf);
|
|||
* @param groupId
|
||||
* @return
|
||||
*/
|
||||
SIDList getDataBufPagesIdList(SQueryResultBuf* pResultBuf, int32_t groupId);
|
||||
SIDList getDataBufPagesIdList(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId);
|
||||
|
||||
/**
|
||||
* get the specified buffer page by id
|
||||
|
@ -68,27 +68,27 @@ SIDList getDataBufPagesIdList(SQueryResultBuf* pResultBuf, int32_t groupId);
|
|||
* @param id
|
||||
* @return
|
||||
*/
|
||||
tFilePage* getResultBufferPageById(SQueryResultBuf* pResultBuf, int32_t id);
|
||||
tFilePage* getResultBufferPageById(SQueryDiskbasedResultBuf* pResultBuf, int32_t id);
|
||||
|
||||
/**
|
||||
* get the total buffer size in the format of disk file
|
||||
* @param pResultBuf
|
||||
* @return
|
||||
*/
|
||||
int32_t getResBufSize(SQueryResultBuf* pResultBuf);
|
||||
int32_t getResBufSize(SQueryDiskbasedResultBuf* pResultBuf);
|
||||
|
||||
/**
|
||||
* get the number of groups in the result buffer
|
||||
* @param pResultBuf
|
||||
* @return
|
||||
*/
|
||||
int32_t getNumOfResultBufGroupId(SQueryResultBuf* pResultBuf);
|
||||
int32_t getNumOfResultBufGroupId(SQueryDiskbasedResultBuf* pResultBuf);
|
||||
|
||||
/**
|
||||
* destroy result buffer
|
||||
* @param pResultBuf
|
||||
*/
|
||||
void destroyResultBuf(SQueryResultBuf* pResultBuf);
|
||||
void destroyResultBuf(SQueryDiskbasedResultBuf* pResultBuf);
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -107,10 +107,11 @@ extern "C" {
|
|||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||
|
||||
enum {
|
||||
MASTER_SCAN = 0x0,
|
||||
SUPPLEMENTARY_SCAN = 0x1,
|
||||
FIRST_STAGE_MERGE = 0x10,
|
||||
SECONDARY_STAGE_MERGE = 0x20,
|
||||
MASTER_SCAN = 0x0u,
|
||||
SUPPLEMENTARY_SCAN = 0x1u,
|
||||
REPEAT_SCAN = 0x2u, //repeat scan belongs to the master scan
|
||||
FIRST_STAGE_MERGE = 0x10u,
|
||||
SECONDARY_STAGE_MERGE = 0x20u,
|
||||
};
|
||||
|
||||
#define QUERY_IS_STABLE_QUERY(type) (((type)&TSDB_QUERY_TYPE_STABLE_QUERY) != 0)
|
||||
|
@ -171,7 +172,7 @@ typedef struct SQLFunctionCtx {
|
|||
int32_t startOffset;
|
||||
int32_t size; // number of rows
|
||||
int32_t order; // asc|desc
|
||||
int32_t scanFlag; // TODO merge with currentStage
|
||||
uint32_t scanFlag; // TODO merge with currentStage
|
||||
|
||||
int16_t inputType;
|
||||
int16_t inputBytes;
|
||||
|
@ -304,6 +305,9 @@ void getStatistics(char *priData, char *data, int32_t size, int32_t numOfRow, in
|
|||
|
||||
bool top_bot_datablock_filter(SQLFunctionCtx *pCtx, int32_t functionId, char *minval, char *maxval);
|
||||
|
||||
bool stableQueryFunctChanged(int32_t funcId);
|
||||
|
||||
|
||||
void resetResultInfo(SResultInfo *pResInfo);
|
||||
void initResultInfo(SResultInfo *pResInfo);
|
||||
void setResultInfoBuf(SResultInfo *pResInfo, int32_t size, bool superTable);
|
||||
|
|
|
@ -259,7 +259,7 @@ typedef struct SQuery {
|
|||
int64_t blockId;
|
||||
TSKEY skey;
|
||||
TSKEY ekey;
|
||||
int64_t nAggTimeInterval;
|
||||
int64_t intervalTime;
|
||||
int64_t slidingTime; // sliding time for sliding window query
|
||||
char intervalTimeUnit; // interval data type, used for daytime revise
|
||||
int8_t precision;
|
||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
#include "hash.h"
|
||||
#include "hashutil.h"
|
||||
|
||||
#define GET_QINFO_ADDR(x) ((char*)(x)-offsetof(SQInfo, query))
|
||||
#define GET_QINFO_ADDR(x) ((char*)(x)-offsetof(SQInfo, query))
|
||||
#define Q_STATUS_EQUAL(p, s) (((p) & (s)) != 0)
|
||||
|
||||
/*
|
||||
|
@ -33,10 +33,10 @@ extern "C" {
|
|||
* The page size should be sufficient for at least one output result or intermediate result.
|
||||
* Some intermediate results may be extremely large, such as top/bottom(100) query.
|
||||
*/
|
||||
#define DEFAULT_INTERN_BUF_SIZE 16384L
|
||||
#define DEFAULT_INTERN_BUF_SIZE 16384L
|
||||
|
||||
#define INIT_ALLOCATE_DISK_PAGES 60L
|
||||
#define DEFAULT_DATA_FILE_MAPPING_PAGES 2L
|
||||
#define INIT_ALLOCATE_DISK_PAGES 60L
|
||||
#define DEFAULT_DATA_FILE_MAPPING_PAGES 2L
|
||||
#define DEFAULT_DATA_FILE_MMAP_WINDOW_SIZE (DEFAULT_DATA_FILE_MAPPING_PAGES * DEFAULT_INTERN_BUF_SIZE)
|
||||
|
||||
#define IO_ENGINE_MMAP 0
|
||||
|
@ -56,7 +56,7 @@ typedef enum {
|
|||
* the program will call this function again, if this status is set.
|
||||
* used to transfer from QUERY_RESBUF_FULL
|
||||
*/
|
||||
QUERY_NOT_COMPLETED = 0x1,
|
||||
QUERY_NOT_COMPLETED = 0x1u,
|
||||
|
||||
/*
|
||||
* output buffer is full, so, the next query will be employed,
|
||||
|
@ -66,7 +66,7 @@ typedef enum {
|
|||
* this status is only exist in group-by clause and
|
||||
* diff/add/division/multiply/ query.
|
||||
*/
|
||||
QUERY_RESBUF_FULL = 0x2,
|
||||
QUERY_RESBUF_FULL = 0x2u,
|
||||
|
||||
/*
|
||||
* query is over
|
||||
|
@ -76,14 +76,13 @@ typedef enum {
|
|||
* 2. when the query range on timestamp is satisfied, it is also denoted as
|
||||
* query_compeleted
|
||||
*/
|
||||
QUERY_COMPLETED = 0x4,
|
||||
QUERY_COMPLETED = 0x4u,
|
||||
|
||||
/*
|
||||
* all data has been scanned, so current search is stopped,
|
||||
* At last, the function will transfer this status to QUERY_COMPLETED
|
||||
*/
|
||||
QUERY_NO_DATA_TO_CHECK = 0x8,
|
||||
|
||||
QUERY_NO_DATA_TO_CHECK = 0x8u,
|
||||
} vnodeQueryStatus;
|
||||
|
||||
typedef struct SPointInterpoSupporter {
|
||||
|
@ -112,15 +111,15 @@ typedef enum {
|
|||
DISK_DATA_DISCARDED = 0x01,
|
||||
} vnodeDiskLoadStatus;
|
||||
|
||||
#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN)
|
||||
#define IS_SUPPLEMENT_SCAN(runtime) (!IS_MASTER_SCAN(runtime))
|
||||
#define IS_MASTER_SCAN(runtime) (((runtime)->scanFlag & 1u) == MASTER_SCAN)
|
||||
#define IS_SUPPLEMENT_SCAN(runtime) ((runtime)->scanFlag == SUPPLEMENTARY_SCAN)
|
||||
#define SET_SUPPLEMENT_SCAN_FLAG(runtime) ((runtime)->scanFlag = SUPPLEMENTARY_SCAN)
|
||||
#define SET_MASTER_SCAN_FLAG(runtime) ((runtime)->scanFlag = MASTER_SCAN)
|
||||
|
||||
typedef int (*__block_search_fn_t)(char* data, int num, int64_t key, int order);
|
||||
|
||||
static FORCE_INLINE SMeterObj* getMeterObj(void* hashHandle, int32_t sid) {
|
||||
return *(SMeterObj**)taosGetDataFromHashTable(hashHandle, (const char*) &sid, sizeof(sid));
|
||||
return *(SMeterObj**)taosGetDataFromHashTable(hashHandle, (const char*)&sid, sizeof(sid));
|
||||
}
|
||||
|
||||
bool isQueryKilled(SQuery* pQuery);
|
||||
|
@ -130,7 +129,7 @@ bool isSumAvgRateQuery(SQuery *pQuery);
|
|||
bool isTopBottomQuery(SQuery* pQuery);
|
||||
bool isFirstLastRowQuery(SQuery* pQuery);
|
||||
bool isTSCompQuery(SQuery* pQuery);
|
||||
bool notHasQueryTimeRange(SQuery *pQuery);
|
||||
bool notHasQueryTimeRange(SQuery* pQuery);
|
||||
|
||||
bool needSupplementaryScan(SQuery* pQuery);
|
||||
bool onDemandLoadDatablock(SQuery* pQuery, int16_t queryRangeSet);
|
||||
|
@ -149,16 +148,15 @@ void vnodeScanAllData(SQueryRuntimeEnv* pRuntimeEnv);
|
|||
|
||||
int32_t vnodeQueryResultInterpolate(SQInfo* pQInfo, tFilePage** pDst, tFilePage** pDataSrc, int32_t numOfRows,
|
||||
int32_t* numOfInterpo);
|
||||
void copyResToQueryResultBuf(SMeterQuerySupportObj* pSupporter, SQuery* pQuery);
|
||||
void copyResToQueryResultBuf(STableQuerySupportObj* pSupporter, SQuery* pQuery);
|
||||
|
||||
void doSkipResults(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
void doFinalizeResult(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
void doSkipResults(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
void doFinalizeResult(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
int64_t getNumOfResult(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
|
||||
void forwardIntervalQueryRange(SMeterQuerySupportObj* pSupporter, SQueryRuntimeEnv* pRuntimeEnv);
|
||||
void forwardQueryStartPosition(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
|
||||
bool normalizedFirstQueryRange(bool dataInDisk, bool dataInCache, SMeterQuerySupportObj* pSupporter,
|
||||
bool normalizedFirstQueryRange(bool dataInDisk, bool dataInCache, STableQuerySupportObj* pSupporter,
|
||||
SPointInterpoSupporter* pPointInterpSupporter, int64_t* key);
|
||||
|
||||
void pointInterpSupporterInit(SQuery* pQuery, SPointInterpoSupporter* pInterpoSupport);
|
||||
|
@ -166,41 +164,42 @@ void pointInterpSupporterDestroy(SPointInterpoSupporter* pPointInterpSupport);
|
|||
void pointInterpSupporterSetData(SQInfo* pQInfo, SPointInterpoSupporter* pPointInterpSupport);
|
||||
|
||||
int64_t loadRequiredBlockIntoMem(SQueryRuntimeEnv* pRuntimeEnv, SPositionInfo* position);
|
||||
int32_t doCloseAllOpenedResults(SMeterQuerySupportObj* pSupporter);
|
||||
void disableFunctForSuppleScan(SQueryRuntimeEnv* pRuntimeEnv, int32_t order);
|
||||
void enableFunctForMasterScan(SQueryRuntimeEnv* pRuntimeEnv, int32_t order);
|
||||
void disableFunctForSuppleScan(STableQuerySupportObj* pSupporter, int32_t order);
|
||||
void enableFunctForMasterScan(SQueryRuntimeEnv* pRuntimeEnv, int32_t order);
|
||||
|
||||
int32_t mergeMetersResultToOneGroups(SMeterQuerySupportObj* pSupporter);
|
||||
void copyFromGroupBuf(SQInfo* pQInfo, SOutputRes* result);
|
||||
int32_t mergeMetersResultToOneGroups(STableQuerySupportObj* pSupporter);
|
||||
void copyFromWindowResToSData(SQInfo* pQInfo, SWindowResult* result);
|
||||
|
||||
SBlockInfo getBlockInfo(SQueryRuntimeEnv *pRuntimeEnv);
|
||||
SBlockInfo getBlockBasicInfo(SQueryRuntimeEnv *pRuntimeEnv, void* pBlock, int32_t type);
|
||||
|
||||
SBlockInfo getBlockBasicInfo(SQueryRuntimeEnv* pRuntimeEnv, void* pBlock, int32_t blockType);
|
||||
SCacheBlock* getCacheDataBlock(SMeterObj* pMeterObj, SQueryRuntimeEnv* pRuntimeEnv, int32_t slot);
|
||||
|
||||
void queryOnBlock(SMeterQuerySupportObj* pSupporter, int64_t* primaryKeys, int32_t blockStatus,
|
||||
SBlockInfo* pBlockBasicInfo, SMeterDataInfo* pDataHeadInfoEx, SField* pFields,
|
||||
__block_search_fn_t searchFn);
|
||||
void stableApplyFunctionsOnBlock(STableQuerySupportObj* pSupporter, SMeterDataInfo* pMeterDataInfo,
|
||||
SBlockInfo* pBlockInfo, SField* pFields, __block_search_fn_t searchFn);
|
||||
|
||||
int32_t vnodeFilterQualifiedMeters(SQInfo *pQInfo, int32_t vid, tSidSet *pSidSet, SMeterDataInfo *pMeterDataInfo,
|
||||
int32_t *numOfMeters, SMeterDataInfo ***pReqMeterDataInfo);
|
||||
int32_t vnodeGetVnodeHeaderFileIdx(int32_t* fid, SQueryRuntimeEnv* pRuntimeEnv, int32_t order);
|
||||
int32_t vnodeFilterQualifiedMeters(SQInfo* pQInfo, int32_t vid, tSidSet* pSidSet, SMeterDataInfo* pMeterDataInfo,
|
||||
int32_t* numOfMeters, SMeterDataInfo*** pReqMeterDataInfo);
|
||||
int32_t vnodeGetVnodeHeaderFileIndex(int32_t* fid, SQueryRuntimeEnv* pRuntimeEnv, int32_t order);
|
||||
|
||||
int32_t createDataBlocksInfoEx(SMeterDataInfo** pMeterDataInfo, int32_t numOfMeters,
|
||||
SMeterDataBlockInfoEx** pDataBlockInfoEx, int32_t numOfCompBlocks,
|
||||
int32_t* nAllocBlocksInfoSize, int64_t addr);
|
||||
void freeMeterBlockInfoEx(SMeterDataBlockInfoEx* pDataBlockInfoEx, int32_t len);
|
||||
void freeMeterBlockInfoEx(SMeterDataBlockInfoEx* pDataBlockInfoEx, int32_t len);
|
||||
|
||||
void setExecutionContext(SMeterQuerySupportObj* pSupporter, SOutputRes* outputRes, int32_t meterIdx, int32_t groupIdx,
|
||||
SMeterQueryInfo* sqinfo);
|
||||
int32_t setIntervalQueryExecutionContext(SMeterQuerySupportObj* pSupporter, int32_t meterIdx, SMeterQueryInfo* sqinfo);
|
||||
void setExecutionContext(STableQuerySupportObj* pSupporter, SMeterQueryInfo* pMeterQueryInfo, int32_t meterIdx,
|
||||
int32_t groupIdx, TSKEY nextKey);
|
||||
int32_t setAdditionalInfo(STableQuerySupportObj *pSupporter, int32_t meterIdx, SMeterQueryInfo *pMeterQueryInfo);
|
||||
void doGetAlignedIntervalQueryRangeImpl(SQuery* pQuery, int64_t pKey, int64_t keyFirst, int64_t keyLast,
|
||||
int64_t* actualSkey, int64_t* actualEkey, int64_t* skey, int64_t* ekey);
|
||||
|
||||
int64_t getQueryStartPositionInCache(SQueryRuntimeEnv* pRuntimeEnv, int32_t* slot, int32_t* pos, bool ignoreQueryRange);
|
||||
int64_t getNextAccessedKeyInData(SQuery* pQuery, int64_t* pPrimaryCol, SBlockInfo* pBlockInfo, int32_t blockStatus);
|
||||
|
||||
int32_t getDataBlocksForMeters(SMeterQuerySupportObj* pSupporter, SQuery* pQuery, int32_t numOfMeters,
|
||||
const char* filePath, SMeterDataInfo** pMeterDataInfo, uint32_t* numOfBlocks);
|
||||
int32_t getDataBlocksForMeters(STableQuerySupportObj* pSupporter, SQuery* pQuery, int32_t numOfMeters,
|
||||
const char* filePath, SMeterDataInfo** pMeterDataInfo, uint32_t* numOfBlocks);
|
||||
int32_t LoadDatablockOnDemand(SCompBlock* pBlock, SField** pFields, uint8_t* blkStatus, SQueryRuntimeEnv* pRuntimeEnv,
|
||||
int32_t fileIdx, int32_t slotIdx, __block_search_fn_t searchFn, bool onDemand);
|
||||
int32_t vnodeGetHeaderFile(SQueryRuntimeEnv *pRuntimeEnv, int32_t fileIndex);
|
||||
int32_t vnodeGetHeaderFile(SQueryRuntimeEnv* pRuntimeEnv, int32_t fileIndex);
|
||||
|
||||
/**
|
||||
* Create SMeterQueryInfo.
|
||||
|
@ -210,14 +209,14 @@ int32_t vnodeGetHeaderFile(SQueryRuntimeEnv *pRuntimeEnv, int32_t fileIndex);
|
|||
* @param ekey
|
||||
* @return
|
||||
*/
|
||||
SMeterQueryInfo* createMeterQueryInfo(SQuery* pQuery, int32_t sid, TSKEY skey, TSKEY ekey);
|
||||
SMeterQueryInfo* createMeterQueryInfo(STableQuerySupportObj* pSupporter, int32_t sid, TSKEY skey, TSKEY ekey);
|
||||
|
||||
/**
|
||||
* Destroy meter query info
|
||||
* @param pMeterQInfo
|
||||
* @param numOfCols
|
||||
*/
|
||||
void destroyMeterQueryInfo(SMeterQueryInfo *pMeterQueryInfo, int32_t numOfCols);
|
||||
void destroyMeterQueryInfo(SMeterQueryInfo* pMeterQueryInfo, int32_t numOfCols);
|
||||
|
||||
/**
|
||||
* change the meter query info for supplement scan
|
||||
|
@ -225,7 +224,8 @@ void destroyMeterQueryInfo(SMeterQueryInfo *pMeterQueryInfo, int32_t numOfCols);
|
|||
* @param skey
|
||||
* @param ekey
|
||||
*/
|
||||
void changeMeterQueryInfoForSuppleQuery(SQueryResultBuf* pResultBuf, SMeterQueryInfo *pMeterQueryInfo, TSKEY skey, TSKEY ekey);
|
||||
void changeMeterQueryInfoForSuppleQuery(SQuery* pQuery, SMeterQueryInfo* pMeterQueryInfo,
|
||||
TSKEY skey, TSKEY ekey);
|
||||
|
||||
/**
|
||||
* add the new allocated disk page to meter query info
|
||||
|
@ -234,14 +234,8 @@ void changeMeterQueryInfoForSuppleQuery(SQueryResultBuf* pResultBuf, SMeterQuery
|
|||
* @param pMeterQueryInfo
|
||||
* @param pSupporter
|
||||
*/
|
||||
tFilePage* addDataPageForMeterQueryInfo(SQuery* pQuery, SMeterQueryInfo *pMeterQueryInfo, SMeterQuerySupportObj *pSupporter);
|
||||
|
||||
/**
|
||||
* save the query range data into SMeterQueryInfo
|
||||
* @param pRuntimeEnv
|
||||
* @param pMeterQueryInfo
|
||||
*/
|
||||
void saveIntervalQueryRange(SQueryRuntimeEnv* pRuntimeEnv, SMeterQueryInfo* pMeterQueryInfo);
|
||||
tFilePage* addDataPageForMeterQueryInfo(SQuery* pQuery, SMeterQueryInfo* pMeterQueryInfo,
|
||||
STableQuerySupportObj* pSupporter);
|
||||
|
||||
/**
|
||||
* restore the query range data from SMeterQueryInfo to runtime environment
|
||||
|
@ -258,7 +252,7 @@ void restoreIntervalQueryRange(SQueryRuntimeEnv* pRuntimeEnv, SMeterQueryInfo* p
|
|||
* @param pSupporter
|
||||
* @param key
|
||||
*/
|
||||
void setIntervalQueryRange(SMeterQueryInfo *pMeterQueryInfo, SMeterQuerySupportObj* pSupporter, int64_t key);
|
||||
void setIntervalQueryRange(SMeterQueryInfo* pMeterQueryInfo, STableQuerySupportObj* pSupporter, int64_t key);
|
||||
|
||||
/**
|
||||
* set the meter data information
|
||||
|
@ -275,16 +269,22 @@ void vnodeCheckIfDataExists(SQueryRuntimeEnv* pRuntimeEnv, SMeterObj* pMeterObj,
|
|||
|
||||
void displayInterResult(SData** pdata, SQuery* pQuery, int32_t numOfRows);
|
||||
|
||||
void vnodePrintQueryStatistics(SMeterQuerySupportObj* pSupporter);
|
||||
void vnodePrintQueryStatistics(STableQuerySupportObj* pSupporter);
|
||||
|
||||
void clearGroupResultBuf(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes *pOneOutputRes);
|
||||
void copyGroupResultBuf(SQueryRuntimeEnv *pRuntimeEnv, SOutputRes* dst, const SOutputRes* src);
|
||||
void clearTimeWindowResBuf(SQueryRuntimeEnv* pRuntimeEnv, SWindowResult* pOneOutputRes);
|
||||
void copyTimeWindowResBuf(SQueryRuntimeEnv* pRuntimeEnv, SWindowResult* dst, const SWindowResult* src);
|
||||
|
||||
void resetSlidingWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SSlidingWindowInfo* pSlidingWindowInfo);
|
||||
void clearCompletedSlidingWindows(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
int32_t numOfClosedSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo);
|
||||
void closeSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo, int32_t slot);
|
||||
void closeAllSlidingWindow(SSlidingWindowInfo* pSlidingWindowInfo);
|
||||
int32_t initWindowResInfo(SWindowResInfo* pWindowResInfo, SQueryRuntimeEnv* pRuntimeEnv, int32_t size,
|
||||
int32_t threshold, int16_t type);
|
||||
|
||||
void cleanupTimeWindowInfo(SWindowResInfo* pWindowResInfo, SQueryRuntimeEnv* pRuntimeEnv);
|
||||
void resetTimeWindowInfo(SQueryRuntimeEnv* pRuntimeEnv, SWindowResInfo* pWindowResInfo);
|
||||
void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num);
|
||||
|
||||
void clearClosedTimeWindow(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
int32_t numOfClosedTimeWindow(SWindowResInfo* pWindowResInfo);
|
||||
void closeTimeWindow(SWindowResInfo* pWindowResInfo, int32_t slot);
|
||||
void closeAllTimeWindow(SWindowResInfo* pWindowResInfo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -86,16 +86,26 @@ typedef struct SQueryCostSummary {
|
|||
} SQueryCostSummary;
|
||||
|
||||
typedef struct SPosInfo {
|
||||
int64_t pageId;
|
||||
int32_t rowId;
|
||||
int16_t pageId;
|
||||
int16_t rowId;
|
||||
} SPosInfo;
|
||||
|
||||
typedef struct SOutputRes {
|
||||
typedef struct STimeWindow {
|
||||
TSKEY skey;
|
||||
TSKEY ekey;
|
||||
} STimeWindow;
|
||||
|
||||
typedef struct SWindowStatus {
|
||||
bool closed;
|
||||
} SWindowStatus;
|
||||
|
||||
typedef struct SWindowResult {
|
||||
uint16_t numOfRows;
|
||||
int32_t nAlloc;
|
||||
SPosInfo pos;
|
||||
SResultInfo* resultInfo;
|
||||
} SOutputRes;
|
||||
SPosInfo pos; // Position of current result in disk-based output buffer
|
||||
SResultInfo* resultInfo; // For each result column, there is a resultInfo
|
||||
STimeWindow window; // The time window that current result covers.
|
||||
SWindowStatus status;
|
||||
} SWindowResult;
|
||||
|
||||
/*
|
||||
* header files info, avoid to iterate the directory, the data is acquired
|
||||
|
@ -118,19 +128,8 @@ typedef struct SQueryFilesInfo {
|
|||
char dbFilePathPrefix[PATH_MAX];
|
||||
} SQueryFilesInfo;
|
||||
|
||||
typedef struct STimeWindow {
|
||||
TSKEY skey;
|
||||
TSKEY ekey;
|
||||
} STimeWindow;
|
||||
|
||||
typedef struct SWindowStatus {
|
||||
STimeWindow window;
|
||||
bool closed;
|
||||
} SWindowStatus;
|
||||
|
||||
typedef struct SSlidingWindowInfo {
|
||||
SOutputRes* pResult; // reference to SQuerySupporter->pResult
|
||||
SWindowStatus* pStatus; // current query window closed or not?
|
||||
typedef struct SWindowResInfo {
|
||||
SWindowResult* pResult; // reference to SQuerySupporter->pResult
|
||||
void* hashList; // hash list for quick access
|
||||
int16_t type; // data type for hash key
|
||||
int32_t capacity; // max capacity
|
||||
|
@ -140,7 +139,7 @@ typedef struct SSlidingWindowInfo {
|
|||
int64_t startTime; // start time of the first time window for sliding query
|
||||
int64_t prevSKey; // previous (not completed) sliding window start key
|
||||
int64_t threshold; // threshold for return completed results.
|
||||
} SSlidingWindowInfo;
|
||||
} SWindowResInfo;
|
||||
|
||||
typedef struct SQueryRuntimeEnv {
|
||||
SPositionInfo startPos; /* the start position, used for secondary/third iteration */
|
||||
|
@ -161,28 +160,25 @@ typedef struct SQueryRuntimeEnv {
|
|||
SQueryFilesInfo vnodeFileInfo;
|
||||
int16_t numOfRowsPerPage;
|
||||
int16_t offset[TSDB_MAX_COLUMNS];
|
||||
int16_t scanFlag; // denotes reversed scan of data or not
|
||||
uint16_t scanFlag; // denotes reversed scan of data or not
|
||||
SInterpolationInfo interpoInfo;
|
||||
SData** pInterpoBuf;
|
||||
|
||||
SSlidingWindowInfo swindowResInfo;
|
||||
SWindowResInfo windowResInfo;
|
||||
|
||||
STSBuf* pTSBuf;
|
||||
STSCursor cur;
|
||||
SQueryCostSummary summary;
|
||||
|
||||
STimeWindow intervalWindow; // the complete time window, not affected by the actual data distribution
|
||||
bool stableQuery; // is super table query or not
|
||||
SQueryDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file
|
||||
|
||||
/*
|
||||
* Temporarily hold the in-memory cache block info during scan cache blocks
|
||||
* Here we do not use the cacheblock info from pMeterObj, simple because it may change anytime
|
||||
* during the query by the subumit/insert handling threads.
|
||||
* Here we do not use the cache block info from pMeterObj, simple because it may change anytime
|
||||
* during the query by the submit/insert handling threads.
|
||||
* So we keep a copy of the support structure as well as the cache block data itself.
|
||||
*/
|
||||
SCacheBlock cacheBlock;
|
||||
|
||||
SQueryResultBuf* pResultBuf;
|
||||
bool stableQuery; // is super table query or not
|
||||
} SQueryRuntimeEnv;
|
||||
|
||||
/* intermediate pos during multimeter query involves interval */
|
||||
|
@ -191,14 +187,12 @@ typedef struct SMeterQueryInfo {
|
|||
int64_t skey;
|
||||
int64_t ekey;
|
||||
int32_t numOfRes;
|
||||
int32_t reverseIndex; // reversed output indicator, start from (numOfRes-1)
|
||||
int16_t reverseFillRes; // denote if reverse fill the results in supplementary scan required or not
|
||||
int16_t queryRangeSet; // denote if the query range is set, only available for interval query
|
||||
int16_t lastResRows;
|
||||
int64_t tag;
|
||||
STSCursor cur;
|
||||
SResultInfo* resultInfo;
|
||||
int32_t sid; // for retrieve the page id list
|
||||
|
||||
SWindowResInfo windowResInfo;
|
||||
} SMeterQueryInfo;
|
||||
|
||||
typedef struct SMeterDataInfo {
|
||||
|
@ -212,7 +206,7 @@ typedef struct SMeterDataInfo {
|
|||
SMeterQueryInfo* pMeterQInfo;
|
||||
} SMeterDataInfo;
|
||||
|
||||
typedef struct SMeterQuerySupportObj {
|
||||
typedef struct STableQuerySupportObj {
|
||||
void* pMetersHashTable; // meter table hash list
|
||||
|
||||
SMeterSidExtInfo** pMeterSidExtInfo;
|
||||
|
@ -225,13 +219,11 @@ typedef struct SMeterQuerySupportObj {
|
|||
* rows may be generated by a specific subgroup. When query on all subgroups is executed,
|
||||
* the result is copy to output buffer. This attribution is not used during single meter query processing.
|
||||
*/
|
||||
SOutputRes* pResult;
|
||||
SQueryRuntimeEnv runtimeEnv;
|
||||
int64_t rawSKey;
|
||||
int64_t rawEKey;
|
||||
int32_t subgroupIdx;
|
||||
int32_t offset; /* offset in group result set of subgroup */
|
||||
|
||||
tSidSet* pSidSet;
|
||||
|
||||
/*
|
||||
|
@ -247,7 +239,7 @@ typedef struct SMeterQuerySupportObj {
|
|||
SMeterDataInfo* pMeterDataInfo;
|
||||
|
||||
TSKEY* tsList;
|
||||
} SMeterQuerySupportObj;
|
||||
} STableQuerySupportObj;
|
||||
|
||||
typedef struct _qinfo {
|
||||
uint64_t signature;
|
||||
|
@ -273,18 +265,18 @@ typedef struct _qinfo {
|
|||
SMeterObj* pObj;
|
||||
sem_t dataReady;
|
||||
|
||||
SMeterQuerySupportObj* pMeterQuerySupporter;
|
||||
STableQuerySupportObj* pTableQuerySupporter;
|
||||
int (*fp)(SMeterObj*, SQuery*);
|
||||
} SQInfo;
|
||||
|
||||
int32_t vnodeQuerySingleMeterPrepare(SQInfo* pQInfo, SMeterObj* pMeterObj, SMeterQuerySupportObj* pSMultiMeterObj,
|
||||
int32_t vnodeQueryTablePrepare(SQInfo* pQInfo, SMeterObj* pMeterObj, STableQuerySupportObj* pSMultiMeterObj,
|
||||
void* param);
|
||||
|
||||
void vnodeQueryFreeQInfoEx(SQInfo* pQInfo);
|
||||
|
||||
bool vnodeParametersSafetyCheck(SQuery* pQuery);
|
||||
|
||||
int32_t vnodeMultiMeterQueryPrepare(SQInfo* pQInfo, SQuery* pQuery, void* param);
|
||||
int32_t vnodeSTableQueryPrepare(SQInfo* pQInfo, SQuery* pQuery, void* param);
|
||||
|
||||
/**
|
||||
* decrease the numofQuery of each table that is queried, enable the
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,8 +26,9 @@
|
|||
|
||||
#include "vnodeQueryImpl.h"
|
||||
|
||||
#define ALL_CACHE_BLOCKS_CHECKED(q) \
|
||||
(((q)->slot == (q)->currentSlot && QUERY_IS_ASC_QUERY(q)) || ((q)->slot == (q)->firstSlot && (!QUERY_IS_ASC_QUERY(q))))
|
||||
#define ALL_CACHE_BLOCKS_CHECKED(q) \
|
||||
(((q)->slot == (q)->currentSlot && QUERY_IS_ASC_QUERY(q)) || \
|
||||
((q)->slot == (q)->firstSlot && (!QUERY_IS_ASC_QUERY(q))))
|
||||
|
||||
#define FORWARD_CACHE_BLOCK_CHECK_SLOT(slot, step, maxblocks) (slot) = ((slot) + (step) + (maxblocks)) % (maxblocks);
|
||||
|
||||
|
@ -47,23 +48,10 @@ static bool isGroupbyEachTable(SSqlGroupbyExpr *pGroupbyExpr, tSidSet *pSidset)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool doCheckWithPrevQueryRange(SQInfo *pQInfo, TSKEY nextKey, SMeterDataInfo *pMeterInfo) {
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
SQuery * pQuery = &pQInfo->query;
|
||||
SMeterObj * pMeterObj = pMeterInfo->pMeterObj;
|
||||
|
||||
/* no data for current query */
|
||||
static bool doCheckWithPrevQueryRange(SQuery *pQuery, TSKEY nextKey) {
|
||||
if ((nextKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(nextKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||
if (((nextKey > pSupporter->rawEKey) && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
((nextKey < pSupporter->rawEKey) && (!QUERY_IS_ASC_QUERY(pQuery)))) {
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, no data qualified in block, ignore", pQInfo, pMeterObj->vnode,
|
||||
pMeterObj->sid, pMeterObj->meterId);
|
||||
|
||||
return false;
|
||||
} else { // in case of interval query, forward the query range
|
||||
setIntervalQueryRange(pMeterInfo->pMeterQInfo, pSupporter, nextKey);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -86,8 +74,8 @@ static void setStartPositionForCacheBlock(SQuery *pQuery, SCacheBlock *pBlock, b
|
|||
}
|
||||
|
||||
static void enableExecutionForNextTable(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||
|
||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||
|
||||
for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) {
|
||||
SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[i]);
|
||||
if (pResInfo != NULL) {
|
||||
|
@ -96,10 +84,10 @@ static void enableExecutionForNextTable(SQueryRuntimeEnv *pRuntimeEnv) {
|
|||
}
|
||||
}
|
||||
|
||||
static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) {
|
||||
static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo) {
|
||||
SQuery * pQuery = &pQInfo->query;
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
SQueryRuntimeEnv * pRuntimeEnv = &pQInfo->pMeterQuerySupporter->runtimeEnv;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
SQueryRuntimeEnv * pRuntimeEnv = &pQInfo->pTableQuerySupporter->runtimeEnv;
|
||||
|
||||
SMeterSidExtInfo **pMeterSidExtInfo = pSupporter->pMeterSidExtInfo;
|
||||
|
||||
|
@ -131,17 +119,18 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) {
|
|||
pQInfo->pObj = pMeterObj;
|
||||
pRuntimeEnv->pMeterObj = pMeterObj;
|
||||
|
||||
if (pMeterInfo[k].pMeterQInfo == NULL) {
|
||||
pMeterInfo[k].pMeterQInfo = createMeterQueryInfo(pQuery, pMeterObj->sid, pSupporter->rawSKey, pSupporter->rawEKey);
|
||||
if (pMeterDataInfo[k].pMeterQInfo == NULL) {
|
||||
pMeterDataInfo[k].pMeterQInfo =
|
||||
createMeterQueryInfo(pSupporter, pMeterObj->sid, pSupporter->rawSKey, pSupporter->rawEKey);
|
||||
}
|
||||
|
||||
if (pMeterInfo[k].pMeterObj == NULL) { // no data in disk for this meter, set its pointer
|
||||
setMeterDataInfo(&pMeterInfo[k], pMeterObj, k, groupIdx);
|
||||
if (pMeterDataInfo[k].pMeterObj == NULL) { // no data in disk for this meter, set its pointer
|
||||
setMeterDataInfo(&pMeterDataInfo[k], pMeterObj, k, groupIdx);
|
||||
}
|
||||
|
||||
assert(pMeterInfo[k].meterOrderIdx == k && pMeterObj == pMeterInfo[k].pMeterObj);
|
||||
assert(pMeterDataInfo[k].meterOrderIdx == k && pMeterObj == pMeterDataInfo[k].pMeterObj);
|
||||
|
||||
SMeterQueryInfo *pMeterQueryInfo = pMeterInfo[k].pMeterQInfo;
|
||||
SMeterQueryInfo *pMeterQueryInfo = pMeterDataInfo[k].pMeterQInfo;
|
||||
restoreIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo);
|
||||
|
||||
/*
|
||||
|
@ -154,29 +143,18 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) {
|
|||
vnodeUpdateQueryColumnIndex(pQuery, pMeterObj);
|
||||
vnodeUpdateFilterColumnIndex(pQuery);
|
||||
|
||||
if (pQuery->nAggTimeInterval == 0) {
|
||||
if ((pQuery->lastKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(pQuery->lastKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||
dTrace(
|
||||
"QInfo:%p vid:%d sid:%d id:%s, query completed, ignore data in cache. qrange:%" PRId64 "-%" PRId64 ", "
|
||||
"lastKey:%" PRId64,
|
||||
pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey,
|
||||
pQuery->lastKey);
|
||||
if ((pQuery->lastKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(pQuery->lastKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, query completed, ignore data in cache. qrange:%" PRId64 "-%" PRId64
|
||||
", lastKey:%" PRId64,
|
||||
pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey,
|
||||
pQuery->lastKey);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
setExecutionContext(pSupporter, pSupporter->pResult, k, pMeterInfo[k].groupIdx, pMeterQueryInfo);
|
||||
} else {
|
||||
int32_t ret = setIntervalQueryExecutionContext(pSupporter, k, pMeterQueryInfo);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
pQInfo->killed = 1;
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
qTrace("QInfo:%p vid:%d sid:%d id:%s, query in cache, qrange:%" PRId64 "-%" PRId64 ", lastKey:%" PRId64, pQInfo, pMeterObj->vnode,
|
||||
pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, pQuery->lastKey);
|
||||
qTrace("QInfo:%p vid:%d sid:%d id:%s, query in cache, qrange:%" PRId64 "-%" PRId64 ", lastKey:%" PRId64, pQInfo,
|
||||
pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, pQuery->lastKey);
|
||||
|
||||
/*
|
||||
* find the appropriated start position in cache
|
||||
|
@ -186,7 +164,7 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) {
|
|||
* should be ignored (the fourth parameter).
|
||||
*/
|
||||
TSKEY nextKey = getQueryStartPositionInCache(pRuntimeEnv, &pQuery->slot, &pQuery->pos, true);
|
||||
if (nextKey < 0) {
|
||||
if (nextKey < 0 || !doCheckWithPrevQueryRange(pQuery, nextKey)) {
|
||||
qTrace("QInfo:%p vid:%d sid:%d id:%s, no data qualified in cache, cache blocks:%d, lastKey:%" PRId64, pQInfo,
|
||||
pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->numOfBlocks, pQuery->lastKey);
|
||||
continue;
|
||||
|
@ -199,10 +177,6 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!doCheckWithPrevQueryRange(pQInfo, nextKey, &pMeterInfo[k])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool firstCheckSlot = true;
|
||||
SCacheInfo *pCacheInfo = (SCacheInfo *)pMeterObj->pCache;
|
||||
|
||||
|
@ -224,24 +198,39 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) {
|
|||
|
||||
setStartPositionForCacheBlock(pQuery, pBlock, &firstCheckSlot);
|
||||
|
||||
TSKEY* primaryKeys = (TSKEY*) pRuntimeEnv->primaryColBuffer->data;
|
||||
|
||||
TSKEY *primaryKeys = (TSKEY *)pRuntimeEnv->primaryColBuffer->data;
|
||||
TSKEY key = primaryKeys[pQuery->pos];
|
||||
|
||||
// in handling file data block, the timestamp range validation is done during fetching candidate file blocks
|
||||
if ((primaryKeys[pQuery->pos] > pSupporter->rawEKey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(primaryKeys[pQuery->pos] < pSupporter->rawEKey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||
if ((key > pSupporter->rawEKey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(key < pSupporter->rawEKey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pQuery->intervalTime == 0) {
|
||||
setExecutionContext(pSupporter, pMeterQueryInfo, k, pMeterDataInfo[k].groupIdx, key);
|
||||
} else {
|
||||
setIntervalQueryRange(pMeterQueryInfo, pSupporter, key);
|
||||
int32_t ret = setAdditionalInfo(pSupporter, k, pMeterQueryInfo);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
pQInfo->killed = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
qTrace("QInfo:%p vid:%d sid:%d id:%s, query in cache, qrange:%" PRId64 "-%" PRId64 ", lastKey:%" PRId64, pQInfo,
|
||||
pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, pQuery->lastKey);
|
||||
|
||||
// only record the key on last block
|
||||
SET_CACHE_BLOCK_FLAG(pRuntimeEnv->blockStatus);
|
||||
SBlockInfo binfo = getBlockBasicInfo(pRuntimeEnv, pBlock, BLK_CACHE_BLOCK);
|
||||
SBlockInfo binfo = getBlockInfo(pRuntimeEnv);
|
||||
|
||||
dTrace("QInfo:%p check data block, brange:%" PRId64 "-%" PRId64 ", fileId:%d, slot:%d, pos:%d, bstatus:%d",
|
||||
GET_QINFO_ADDR(pQuery), binfo.keyFirst, binfo.keyLast, pQuery->fileId, pQuery->slot, pQuery->pos,
|
||||
pRuntimeEnv->blockStatus);
|
||||
|
||||
totalBlocks++;
|
||||
queryOnBlock(pSupporter, primaryKeys, pRuntimeEnv->blockStatus, &binfo, &pMeterInfo[k], NULL, searchFn);
|
||||
stableApplyFunctionsOnBlock(pSupporter, &pMeterDataInfo[k], &binfo, NULL, searchFn);
|
||||
|
||||
if (ALL_CACHE_BLOCKS_CHECKED(pQuery)) {
|
||||
break;
|
||||
|
@ -266,7 +255,7 @@ static void queryOnMultiDataCache(SQInfo *pQInfo, SMeterDataInfo *pMeterInfo) {
|
|||
|
||||
static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo) {
|
||||
SQuery * pQuery = &pQInfo->query;
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv;
|
||||
SMeterDataBlockInfoEx *pDataBlockInfoEx = NULL;
|
||||
int32_t nAllocBlocksInfoSize = 0;
|
||||
|
@ -274,9 +263,9 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo
|
|||
SMeterObj * pTempMeter = getMeterObj(pSupporter->pMetersHashTable, pSupporter->pMeterSidExtInfo[0]->sid);
|
||||
__block_search_fn_t searchFn = vnodeSearchKeyFunc[pTempMeter->searchAlgorithm];
|
||||
|
||||
int32_t vnodeId = pTempMeter->vnode;
|
||||
SQueryFilesInfo* pVnodeFileInfo = &pRuntimeEnv->vnodeFileInfo;
|
||||
|
||||
int32_t vnodeId = pTempMeter->vnode;
|
||||
SQueryFilesInfo *pVnodeFileInfo = &pRuntimeEnv->vnodeFileInfo;
|
||||
|
||||
dTrace("QInfo:%p start to check data blocks in %d files", pQInfo, pVnodeFileInfo->numOfFiles);
|
||||
|
||||
int32_t fid = QUERY_IS_ASC_QUERY(pQuery) ? -1 : INT32_MAX;
|
||||
|
@ -291,7 +280,7 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo
|
|||
break;
|
||||
}
|
||||
|
||||
int32_t fileIdx = vnodeGetVnodeHeaderFileIdx(&fid, pRuntimeEnv, pQuery->order.order);
|
||||
int32_t fileIdx = vnodeGetVnodeHeaderFileIndex(&fid, pRuntimeEnv, pQuery->order.order);
|
||||
if (fileIdx < 0) { // no valid file, abort current search
|
||||
break;
|
||||
}
|
||||
|
@ -304,25 +293,25 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo
|
|||
fid += step;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
int32_t numOfQualifiedMeters = 0;
|
||||
assert(fileIdx == pRuntimeEnv->vnodeFileInfo.current);
|
||||
|
||||
|
||||
SMeterDataInfo **pReqMeterDataInfo = NULL;
|
||||
int32_t ret = vnodeFilterQualifiedMeters(pQInfo, vnodeId, pSupporter->pSidSet, pMeterDataInfo,
|
||||
int32_t ret = vnodeFilterQualifiedMeters(pQInfo, vnodeId, pSupporter->pSidSet, pMeterDataInfo,
|
||||
&numOfQualifiedMeters, &pReqMeterDataInfo);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
dError("QInfo:%p failed to create meterdata struct to perform query processing, abort", pQInfo);
|
||||
|
||||
|
||||
tfree(pReqMeterDataInfo);
|
||||
pQInfo->code = -ret;
|
||||
pQInfo->killed = 1;
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dTrace("QInfo:%p file:%s, %d meters qualified", pQInfo, pVnodeFileInfo->dataFilePath, numOfQualifiedMeters);
|
||||
|
||||
|
||||
// none of meters in query set have pHeaderFileData in this file, try next file
|
||||
if (numOfQualifiedMeters == 0) {
|
||||
fid += step;
|
||||
|
@ -335,17 +324,17 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo
|
|||
pReqMeterDataInfo, &numOfBlocks);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
dError("QInfo:%p failed to get data block before scan data blocks, abort", pQInfo);
|
||||
|
||||
|
||||
tfree(pReqMeterDataInfo);
|
||||
pQInfo->code = -ret;
|
||||
pQInfo->killed = 1;
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dTrace("QInfo:%p file:%s, %d meters contains %d blocks to be checked", pQInfo, pVnodeFileInfo->dataFilePath,
|
||||
numOfQualifiedMeters, numOfBlocks);
|
||||
|
||||
|
||||
if (numOfBlocks == 0) {
|
||||
fid += step;
|
||||
tfree(pReqMeterDataInfo);
|
||||
|
@ -353,7 +342,7 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo
|
|||
}
|
||||
|
||||
ret = createDataBlocksInfoEx(pReqMeterDataInfo, numOfQualifiedMeters, &pDataBlockInfoEx, numOfBlocks,
|
||||
&nAllocBlocksInfoSize, (int64_t)pQInfo);
|
||||
&nAllocBlocksInfoSize, (int64_t)pQInfo);
|
||||
if (ret != TSDB_CODE_SUCCESS) { // failed to create data blocks
|
||||
dError("QInfo:%p build blockInfoEx failed, abort", pQInfo);
|
||||
tfree(pReqMeterDataInfo);
|
||||
|
@ -383,8 +372,8 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo
|
|||
stimeUnit = taosGetTimestampMs();
|
||||
} else if ((j % TRACE_OUTPUT_BLOCK_CNT) == 0) {
|
||||
etimeUnit = taosGetTimestampMs();
|
||||
dTrace("QInfo:%p load and check %" PRId64 " blocks, and continue. elapsed:%" PRId64 " ms", pQInfo, TRACE_OUTPUT_BLOCK_CNT,
|
||||
etimeUnit - stimeUnit);
|
||||
dTrace("QInfo:%p load and check %" PRId64 " blocks, and continue. elapsed:%" PRId64 " ms", pQInfo,
|
||||
TRACE_OUTPUT_BLOCK_CNT, etimeUnit - stimeUnit);
|
||||
stimeUnit = taosGetTimestampMs();
|
||||
}
|
||||
|
||||
|
@ -398,22 +387,52 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo
|
|||
|
||||
restoreIntervalQueryRange(pRuntimeEnv, pMeterQueryInfo);
|
||||
|
||||
if (pQuery->nAggTimeInterval == 0 && !isSumAvgRateQuery(pQuery)) { // normal query
|
||||
if ((pQuery->lastKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(pQuery->lastKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||
qTrace(
|
||||
"QInfo:%p vid:%d sid:%d id:%s, query completed, no need to scan this data block. qrange:%" PRId64 "-%" PRId64 ", "
|
||||
"lastKey:%" PRId64,
|
||||
pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey,
|
||||
pQuery->lastKey);
|
||||
if ((pQuery->lastKey > pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(pQuery->lastKey < pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||
qTrace("QInfo:%p vid:%d sid:%d id:%s, query completed, no need to scan this data block. qrange:%" PRId64
|
||||
"-%" PRId64 ", lastKey:%" PRId64,
|
||||
pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey,
|
||||
pQuery->lastKey);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
SCompBlock *pBlock = pInfoEx->pBlock.compBlock;
|
||||
bool ondemandLoad = onDemandLoadDatablock(pQuery, pMeterQueryInfo->queryRangeSet);
|
||||
ret = LoadDatablockOnDemand(pBlock, &pInfoEx->pBlock.fields, &pRuntimeEnv->blockStatus, pRuntimeEnv, fileIdx,
|
||||
pInfoEx->blockIndex, searchFn, ondemandLoad);
|
||||
if (ret != DISK_DATA_LOADED) {
|
||||
pSummary->skippedFileBlocks++;
|
||||
continue;
|
||||
}
|
||||
|
||||
SBlockInfo binfo = getBlockBasicInfo(pRuntimeEnv, pBlock, BLK_FILE_BLOCK);
|
||||
int64_t nextKey = -1;
|
||||
|
||||
assert(pQuery->pos >= 0 && pQuery->pos < pBlock->numOfPoints);
|
||||
TSKEY *primaryKeys = (TSKEY *)pRuntimeEnv->primaryColBuffer->data;
|
||||
|
||||
if (IS_DATA_BLOCK_LOADED(pRuntimeEnv->blockStatus) && needPrimaryTimestampCol(pQuery, &binfo)) {
|
||||
nextKey = primaryKeys[pQuery->pos];
|
||||
|
||||
if (!doCheckWithPrevQueryRange(pQuery, nextKey)) {
|
||||
qTrace("QInfo:%p vid:%d sid:%d id:%s, no data qualified in data file, lastKey:%" PRId64, pQInfo,
|
||||
pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->numOfBlocks, pQuery->lastKey);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// if data block is not loaded, it must be the intermediate blocks
|
||||
assert((pBlock->keyFirst >= pQuery->lastKey && pBlock->keyLast <= pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(pBlock->keyFirst >= pQuery->ekey && pBlock->keyLast <= pQuery->lastKey && !QUERY_IS_ASC_QUERY(pQuery)));
|
||||
nextKey = QUERY_IS_ASC_QUERY(pQuery) ? pBlock->keyFirst : pBlock->keyLast;
|
||||
}
|
||||
|
||||
setExecutionContext(pSupporter, pSupporter->pResult, pOneMeterDataInfo->meterOrderIdx,
|
||||
pOneMeterDataInfo->groupIdx, pMeterQueryInfo);
|
||||
if (pQuery->intervalTime == 0) {
|
||||
setExecutionContext(pSupporter, pMeterQueryInfo, pOneMeterDataInfo->meterOrderIdx, pOneMeterDataInfo->groupIdx,
|
||||
nextKey);
|
||||
} else { // interval query
|
||||
ret = setIntervalQueryExecutionContext(pSupporter, pOneMeterDataInfo->meterOrderIdx, pMeterQueryInfo);
|
||||
setIntervalQueryRange(pMeterQueryInfo, pSupporter, nextKey);
|
||||
ret = setAdditionalInfo(pSupporter, pOneMeterDataInfo->meterOrderIdx, pMeterQueryInfo);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
tfree(pReqMeterDataInfo); // error code has been set
|
||||
pQInfo->killed = 1;
|
||||
|
@ -421,33 +440,7 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo
|
|||
}
|
||||
}
|
||||
|
||||
SCompBlock *pBlock = pInfoEx->pBlock.compBlock;
|
||||
bool ondemandLoad = onDemandLoadDatablock(pQuery, pMeterQueryInfo->queryRangeSet);
|
||||
int32_t ret = LoadDatablockOnDemand(pBlock, &pInfoEx->pBlock.fields, &pRuntimeEnv->blockStatus, pRuntimeEnv,
|
||||
fileIdx, pInfoEx->blockIndex, searchFn, ondemandLoad);
|
||||
if (ret != DISK_DATA_LOADED) {
|
||||
pSummary->skippedFileBlocks++;
|
||||
continue;
|
||||
}
|
||||
|
||||
SBlockInfo binfo = getBlockBasicInfo(pRuntimeEnv, pBlock, BLK_FILE_BLOCK);
|
||||
|
||||
assert(pQuery->pos >= 0 && pQuery->pos < pBlock->numOfPoints);
|
||||
TSKEY *primaryKeys = (TSKEY *)pRuntimeEnv->primaryColBuffer->data;
|
||||
|
||||
if (IS_DATA_BLOCK_LOADED(pRuntimeEnv->blockStatus) && needPrimaryTimestampCol(pQuery, &binfo)) {
|
||||
TSKEY nextKey = primaryKeys[pQuery->pos];
|
||||
if (!doCheckWithPrevQueryRange(pQInfo, nextKey, pOneMeterDataInfo)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// if data block is not loaded, it must be the intermediate blocks
|
||||
assert((pBlock->keyFirst >= pQuery->lastKey && pBlock->keyLast <= pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(pBlock->keyFirst >= pQuery->ekey && pBlock->keyLast <= pQuery->lastKey && !QUERY_IS_ASC_QUERY(pQuery)));
|
||||
}
|
||||
|
||||
queryOnBlock(pSupporter, primaryKeys, pRuntimeEnv->blockStatus, &binfo, pOneMeterDataInfo, pInfoEx->pBlock.fields,
|
||||
searchFn);
|
||||
stableApplyFunctionsOnBlock(pSupporter, pOneMeterDataInfo, &binfo, pInfoEx->pBlock.fields, searchFn);
|
||||
}
|
||||
|
||||
tfree(pReqMeterDataInfo);
|
||||
|
@ -470,7 +463,7 @@ static void queryOnMultiDataFiles(SQInfo *pQInfo, SMeterDataInfo *pMeterDataInfo
|
|||
|
||||
static bool multimeterMultioutputHelper(SQInfo *pQInfo, bool *dataInDisk, bool *dataInCache, int32_t index,
|
||||
int32_t start) {
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
|
||||
SMeterSidExtInfo **pMeterSidExtInfo = pSupporter->pMeterSidExtInfo;
|
||||
SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv;
|
||||
|
@ -486,13 +479,13 @@ static bool multimeterMultioutputHelper(SQInfo *pQInfo, bool *dataInDisk, bool *
|
|||
|
||||
vnodeSetTagValueInParam(pSupporter->pSidSet, pRuntimeEnv, pMeterSidExtInfo[index]);
|
||||
|
||||
dTrace("QInfo:%p query on (%d): vid:%d sid:%d meterId:%s, qrange:%" PRId64 "-%" PRId64, pQInfo, index - start, pMeterObj->vnode,
|
||||
pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey);
|
||||
dTrace("QInfo:%p query on (%d): vid:%d sid:%d meterId:%s, qrange:%" PRId64 "-%" PRId64, pQInfo, index - start,
|
||||
pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey);
|
||||
|
||||
pQInfo->pObj = pMeterObj;
|
||||
pQuery->lastKey = pQuery->skey;
|
||||
pRuntimeEnv->pMeterObj = pMeterObj;
|
||||
|
||||
|
||||
vnodeUpdateQueryColumnIndex(pQuery, pRuntimeEnv->pMeterObj);
|
||||
vnodeUpdateFilterColumnIndex(pQuery);
|
||||
|
||||
|
@ -500,8 +493,8 @@ static bool multimeterMultioutputHelper(SQInfo *pQInfo, bool *dataInDisk, bool *
|
|||
|
||||
// data in file or cache is not qualified for the query. abort
|
||||
if (!(dataInCache || dataInDisk)) {
|
||||
dTrace("QInfo:%p vid:%d sid:%d meterId:%s, qrange:%" PRId64 "-%" PRId64 ", nores, %p", pQInfo, pMeterObj->vnode, pMeterObj->sid,
|
||||
pMeterObj->meterId, pQuery->skey, pQuery->ekey, pQuery);
|
||||
dTrace("QInfo:%p vid:%d sid:%d meterId:%s, qrange:%" PRId64 "-%" PRId64 ", nores, %p", pQInfo, pMeterObj->vnode,
|
||||
pMeterObj->sid, pMeterObj->meterId, pQuery->skey, pQuery->ekey, pQuery);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -525,7 +518,7 @@ static bool multimeterMultioutputHelper(SQInfo *pQInfo, bool *dataInDisk, bool *
|
|||
|
||||
static int64_t doCheckMetersInGroup(SQInfo *pQInfo, int32_t index, int32_t start) {
|
||||
SQuery * pQuery = &pQInfo->query;
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv;
|
||||
|
||||
bool dataInDisk = true;
|
||||
|
@ -556,7 +549,7 @@ static int64_t doCheckMetersInGroup(SQInfo *pQInfo, int32_t index, int32_t start
|
|||
pointInterpSupporterDestroy(&pointInterpSupporter);
|
||||
|
||||
vnodeScanAllData(pRuntimeEnv);
|
||||
|
||||
|
||||
// first/last_row query, do not invoke the finalize for super table query
|
||||
doFinalizeResult(pRuntimeEnv);
|
||||
|
||||
|
@ -580,7 +573,7 @@ static int64_t doCheckMetersInGroup(SQInfo *pQInfo, int32_t index, int32_t start
|
|||
* @param pQInfo
|
||||
*/
|
||||
static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
|
||||
SMeterSidExtInfo **pMeterSidExtInfo = pSupporter->pMeterSidExtInfo;
|
||||
SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv;
|
||||
|
@ -589,10 +582,10 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
tSidSet *pSids = pSupporter->pSidSet;
|
||||
|
||||
int32_t vid = getMeterObj(pSupporter->pMetersHashTable, pMeterSidExtInfo[0]->sid)->vnode;
|
||||
|
||||
|
||||
if (isPointInterpoQuery(pQuery)) {
|
||||
resetCtxOutputBuf(pRuntimeEnv);
|
||||
|
||||
|
||||
assert(pQuery->limit.offset == 0 && pQuery->limit.limit != 0);
|
||||
|
||||
while (pSupporter->subgroupIdx < pSids->numOfSubSet) {
|
||||
|
@ -600,8 +593,8 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
int32_t end = pSids->starterPos[pSupporter->subgroupIdx + 1] - 1;
|
||||
|
||||
if (isFirstLastRowQuery(pQuery)) {
|
||||
dTrace("QInfo:%p last_row query on vid:%d, numOfGroups:%d, current group:%d", pQInfo, vid,
|
||||
pSids->numOfSubSet, pSupporter->subgroupIdx);
|
||||
dTrace("QInfo:%p last_row query on vid:%d, numOfGroups:%d, current group:%d", pQInfo, vid, pSids->numOfSubSet,
|
||||
pSupporter->subgroupIdx);
|
||||
|
||||
TSKEY key = -1;
|
||||
int32_t index = -1;
|
||||
|
@ -633,8 +626,8 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
int64_t num = doCheckMetersInGroup(pQInfo, index, start);
|
||||
assert(num >= 0);
|
||||
} else {
|
||||
dTrace("QInfo:%p interp query on vid:%d, numOfGroups:%d, current group:%d", pQInfo, vid,
|
||||
pSids->numOfSubSet, pSupporter->subgroupIdx);
|
||||
dTrace("QInfo:%p interp query on vid:%d, numOfGroups:%d, current group:%d", pQInfo, vid, pSids->numOfSubSet,
|
||||
pSupporter->subgroupIdx);
|
||||
|
||||
for (int32_t k = start; k <= end; ++k) {
|
||||
if (isQueryKilled(pQuery)) {
|
||||
|
@ -670,7 +663,7 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
* we need to return it to client in the first place.
|
||||
*/
|
||||
if (pSupporter->subgroupIdx > 0) {
|
||||
copyFromGroupBuf(pQInfo, pSupporter->pResult);
|
||||
copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult);
|
||||
pQInfo->pointsRead += pQuery->pointsRead;
|
||||
|
||||
if (pQuery->pointsRead > 0) {
|
||||
|
@ -681,10 +674,10 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
if (pSupporter->meterIdx >= pSids->numOfSids) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
resetCtxOutputBuf(pRuntimeEnv);
|
||||
resetSlidingWindowInfo(pRuntimeEnv, &pRuntimeEnv->swindowResInfo);
|
||||
|
||||
resetTimeWindowInfo(pRuntimeEnv, &pRuntimeEnv->windowResInfo);
|
||||
|
||||
while (pSupporter->meterIdx < pSupporter->numOfMeters) {
|
||||
int32_t k = pSupporter->meterIdx;
|
||||
|
||||
|
@ -692,9 +685,8 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
setQueryStatus(pQuery, QUERY_NO_DATA_TO_CHECK);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
TSKEY skey = pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[k]->key;
|
||||
TSKEY skey = pQInfo->pTableQuerySupporter->pMeterSidExtInfo[k]->key;
|
||||
if (skey > 0) {
|
||||
pQuery->skey = skey;
|
||||
}
|
||||
|
@ -747,10 +739,10 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
pSupporter->meterIdx = pSupporter->pSidSet->numOfSids;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// enable execution for next table, when handling the projection query
|
||||
enableExecutionForNextTable(pRuntimeEnv);
|
||||
|
||||
|
||||
if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK | QUERY_COMPLETED)) {
|
||||
/*
|
||||
* query range is identical in terms of all meters involved in query,
|
||||
|
@ -762,7 +754,7 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
pQuery->ekey = pSupporter->rawEKey;
|
||||
pSupporter->meterIdx++;
|
||||
|
||||
pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[k]->key = pQuery->lastKey;
|
||||
pQInfo->pTableQuerySupporter->pMeterSidExtInfo[k]->key = pQuery->lastKey;
|
||||
|
||||
// if the buffer is full or group by each table, we need to jump out of the loop
|
||||
if (Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL) ||
|
||||
|
@ -770,7 +762,7 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
break;
|
||||
}
|
||||
|
||||
} else { // forward query range
|
||||
} else { // forward query range
|
||||
pQuery->skey = pQuery->lastKey;
|
||||
|
||||
// all data in the result buffer are skipped due to the offset, continue to retrieve data from current meter
|
||||
|
@ -778,7 +770,7 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
assert(!Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL));
|
||||
continue;
|
||||
} else {
|
||||
pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[k]->key = pQuery->lastKey;
|
||||
pQInfo->pTableQuerySupporter->pMeterSidExtInfo[k]->key = pQuery->lastKey;
|
||||
// buffer is full, wait for the next round to retrieve data from current meter
|
||||
assert(Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL));
|
||||
break;
|
||||
|
@ -808,20 +800,21 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
|
||||
// todo refactor
|
||||
if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) {
|
||||
SSlidingWindowInfo* pSlidingWindowInfo = &pRuntimeEnv->swindowResInfo;
|
||||
|
||||
for (int32_t i = 0; i < pSlidingWindowInfo->size; ++i) {
|
||||
SOutputRes *buf = &pSlidingWindowInfo->pResult[i];
|
||||
pSlidingWindowInfo->pStatus[i].closed = true; // enable return all results for group by normal columns
|
||||
|
||||
SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo;
|
||||
|
||||
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
|
||||
SWindowStatus *pStatus = &pWindowResInfo->pResult[i].status;
|
||||
pStatus->closed = true; // enable return all results for group by normal columns
|
||||
|
||||
SWindowResult *pResult = &pWindowResInfo->pResult[i];
|
||||
for (int32_t j = 0; j < pQuery->numOfOutputCols; ++j) {
|
||||
buf->numOfRows = MAX(buf->numOfRows, buf->resultInfo[j].numOfRes);
|
||||
pResult->numOfRows = MAX(pResult->numOfRows, pResult->resultInfo[j].numOfRes);
|
||||
}
|
||||
}
|
||||
|
||||
pQInfo->pMeterQuerySupporter->subgroupIdx = 0;
|
||||
pQInfo->pTableQuerySupporter->subgroupIdx = 0;
|
||||
pQuery->pointsRead = 0;
|
||||
copyFromGroupBuf(pQInfo, pSlidingWindowInfo->pResult);
|
||||
copyFromWindowResToSData(pQInfo, pWindowResInfo->pResult);
|
||||
}
|
||||
|
||||
pQInfo->pointsRead += pQuery->pointsRead;
|
||||
|
@ -830,12 +823,12 @@ static void vnodeSTableSeqProcessor(SQInfo *pQInfo) {
|
|||
dTrace(
|
||||
"QInfo %p vid:%d, numOfMeters:%d, index:%d, numOfGroups:%d, %d points returned, totalRead:%d totalReturn:%d,"
|
||||
"next skey:%" PRId64 ", offset:%" PRId64,
|
||||
pQInfo, vid, pSids->numOfSids, pSupporter->meterIdx, pSids->numOfSubSet, pQuery->pointsRead,
|
||||
pQInfo->pointsRead, pQInfo->pointsReturned, pQuery->skey, pQuery->limit.offset);
|
||||
pQInfo, vid, pSids->numOfSids, pSupporter->meterIdx, pSids->numOfSubSet, pQuery->pointsRead, pQInfo->pointsRead,
|
||||
pQInfo->pointsReturned, pQuery->skey, pQuery->limit.offset);
|
||||
}
|
||||
|
||||
static void doOrderedScan(SQInfo *pQInfo) {
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
SQuery * pQuery = &pQInfo->query;
|
||||
|
||||
if (QUERY_IS_ASC_QUERY(pQuery)) {
|
||||
|
@ -855,17 +848,17 @@ static void doOrderedScan(SQInfo *pQInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
static void setupMeterQueryInfoForSupplementQuery(SMeterQuerySupportObj *pSupporter) {
|
||||
static void setupMeterQueryInfoForSupplementQuery(STableQuerySupportObj *pSupporter) {
|
||||
SQuery *pQuery = pSupporter->runtimeEnv.pQuery;
|
||||
|
||||
for (int32_t i = 0; i < pSupporter->numOfMeters; ++i) {
|
||||
SMeterQueryInfo *pMeterQueryInfo = pSupporter->pMeterDataInfo[i].pMeterQInfo;
|
||||
SQueryResultBuf* pResultBuf = pSupporter->runtimeEnv.pResultBuf;
|
||||
|
||||
changeMeterQueryInfoForSuppleQuery(pResultBuf, pMeterQueryInfo, pSupporter->rawSKey, pSupporter->rawEKey);
|
||||
changeMeterQueryInfoForSuppleQuery(pQuery, pMeterQueryInfo, pSupporter->rawSKey, pSupporter->rawEKey);
|
||||
}
|
||||
}
|
||||
|
||||
static void doMultiMeterSupplementaryScan(SQInfo *pQInfo) {
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
|
||||
SQueryRuntimeEnv *pRuntimeEnv = &pSupporter->runtimeEnv;
|
||||
SQuery * pQuery = &pQInfo->query;
|
||||
|
@ -876,7 +869,7 @@ static void doMultiMeterSupplementaryScan(SQInfo *pQInfo) {
|
|||
}
|
||||
|
||||
SET_SUPPLEMENT_SCAN_FLAG(pRuntimeEnv);
|
||||
disableFunctForSuppleScan(pRuntimeEnv, pQuery->order.order);
|
||||
disableFunctForSuppleScan(pSupporter, pQuery->order.order);
|
||||
|
||||
if (pRuntimeEnv->pTSBuf != NULL) {
|
||||
pRuntimeEnv->pTSBuf->cur.order = pRuntimeEnv->pTSBuf->cur.order ^ 1;
|
||||
|
@ -886,7 +879,9 @@ static void doMultiMeterSupplementaryScan(SQInfo *pQInfo) {
|
|||
setupMeterQueryInfoForSupplementQuery(pSupporter);
|
||||
|
||||
int64_t st = taosGetTimestampMs();
|
||||
|
||||
doOrderedScan(pQInfo);
|
||||
|
||||
int64_t et = taosGetTimestampMs();
|
||||
dTrace("QInfo:%p supplementary scan completed, elapsed time: %lldms", pQInfo, et - st);
|
||||
|
||||
|
@ -905,7 +900,8 @@ static void doMultiMeterSupplementaryScan(SQInfo *pQInfo) {
|
|||
}
|
||||
|
||||
static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) {
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv;
|
||||
SQuery * pQuery = &pQInfo->query;
|
||||
|
||||
if (pSupporter->subgroupIdx > 0) {
|
||||
|
@ -913,14 +909,14 @@ static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) {
|
|||
* if the subgroupIdx > 0, the query process must be completed yet, we only need to
|
||||
* copy the data into output buffer
|
||||
*/
|
||||
if (pQuery->nAggTimeInterval > 0) {
|
||||
if (pQuery->intervalTime > 0) {
|
||||
copyResToQueryResultBuf(pSupporter, pQuery);
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
displayInterResult(pQuery->sdata, pQuery, pQuery->sdata[0]->len);
|
||||
#endif
|
||||
} else {
|
||||
copyFromGroupBuf(pQInfo, pSupporter->pResult);
|
||||
copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult);
|
||||
}
|
||||
|
||||
pQInfo->pointsRead += pQuery->pointsRead;
|
||||
|
@ -941,8 +937,8 @@ static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) {
|
|||
return;
|
||||
}
|
||||
|
||||
dTrace("QInfo:%p query start, qrange:%" PRId64 "-%" PRId64 ", order:%d, group:%d", pQInfo, pSupporter->rawSKey, pSupporter->rawEKey,
|
||||
pQuery->order.order, pSupporter->pSidSet->numOfSubSet);
|
||||
dTrace("QInfo:%p query start, qrange:%" PRId64 "-%" PRId64 ", order:%d, group:%d", pQInfo, pSupporter->rawSKey,
|
||||
pSupporter->rawEKey, pQuery->order.order, pSupporter->pSidSet->numOfSubSet);
|
||||
|
||||
dTrace("QInfo:%p main query scan start", pQInfo);
|
||||
int64_t st = taosGetTimestampMs();
|
||||
|
@ -951,12 +947,15 @@ static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) {
|
|||
dTrace("QInfo:%p main scan completed, elapsed time: %lldms, supplementary scan start, order:%d", pQInfo, et - st,
|
||||
pQuery->order.order ^ 1);
|
||||
|
||||
// failed to save all intermediate results into disk, abort further query processing
|
||||
if (doCloseAllOpenedResults(pSupporter) != TSDB_CODE_SUCCESS) {
|
||||
dError("QInfo:%p failed to save intermediate results, abort further query processing", pQInfo);
|
||||
return;
|
||||
if (pQuery->intervalTime > 0) {
|
||||
for (int32_t i = 0; i < pSupporter->numOfMeters; ++i) {
|
||||
SMeterQueryInfo *pMeterQueryInfo = pSupporter->pMeterDataInfo[i].pMeterQInfo;
|
||||
closeAllTimeWindow(&pMeterQueryInfo->windowResInfo);
|
||||
}
|
||||
} else { // close results for group result
|
||||
closeAllTimeWindow(&pRuntimeEnv->windowResInfo);
|
||||
}
|
||||
|
||||
|
||||
doMultiMeterSupplementaryScan(pQInfo);
|
||||
|
||||
if (isQueryKilled(pQuery)) {
|
||||
|
@ -964,18 +963,18 @@ static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pQuery->nAggTimeInterval > 0 || isSumAvgRateQuery(pQuery)) {
|
||||
if (pQuery->intervalTime > 0 || isSumAvgRateQuery(pQuery)) {
|
||||
assert(pSupporter->subgroupIdx == 0 && pSupporter->numOfGroupResultPages == 0);
|
||||
|
||||
if (mergeMetersResultToOneGroups(pSupporter) == TSDB_CODE_SUCCESS) {
|
||||
copyResToQueryResultBuf(pSupporter, pQuery);
|
||||
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
displayInterResult(pQuery->sdata, pQuery, pQuery->sdata[0]->len);
|
||||
#endif
|
||||
}
|
||||
} else { // not a interval query
|
||||
copyFromGroupBuf(pQInfo, pSupporter->pResult);
|
||||
copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult);
|
||||
}
|
||||
|
||||
// handle the limitation of output buffer
|
||||
|
@ -992,7 +991,7 @@ static void vnodeMultiMeterQueryProcessor(SQInfo *pQInfo) {
|
|||
*/
|
||||
static void vnodeSingleTableFixedOutputProcessor(SQInfo *pQInfo) {
|
||||
SQuery * pQuery = &pQInfo->query;
|
||||
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pMeterQuerySupporter->runtimeEnv;
|
||||
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pTableQuerySupporter->runtimeEnv;
|
||||
|
||||
assert(pQuery->slot >= 0 && pQuery->pos >= 0);
|
||||
|
||||
|
@ -1023,7 +1022,7 @@ static void vnodeSingleTableMultiOutputProcessor(SQInfo *pQInfo) {
|
|||
SQuery * pQuery = &pQInfo->query;
|
||||
SMeterObj *pMeterObj = pQInfo->pObj;
|
||||
|
||||
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pMeterQuerySupporter->runtimeEnv;
|
||||
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pTableQuerySupporter->runtimeEnv;
|
||||
|
||||
// for ts_comp query, re-initialized is not allowed
|
||||
if (!isTSCompQuery(pQuery)) {
|
||||
|
@ -1054,8 +1053,9 @@ static void vnodeSingleTableMultiOutputProcessor(SQInfo *pQInfo) {
|
|||
TSKEY nextTimestamp = loadRequiredBlockIntoMem(pRuntimeEnv, &pRuntimeEnv->nextPos);
|
||||
assert(nextTimestamp > 0 || ((nextTimestamp < 0) && Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK)));
|
||||
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, skip current result, offset:%" PRId64 ", next qrange:%" PRId64 "-%" PRId64, pQInfo,
|
||||
pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->limit.offset, pQuery->lastKey, pQuery->ekey);
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, skip current result, offset:%" PRId64 ", next qrange:%" PRId64 "-%" PRId64,
|
||||
pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->limit.offset, pQuery->lastKey,
|
||||
pQuery->ekey);
|
||||
|
||||
resetCtxOutputBuf(pRuntimeEnv);
|
||||
}
|
||||
|
@ -1067,8 +1067,8 @@ static void vnodeSingleTableMultiOutputProcessor(SQInfo *pQInfo) {
|
|||
TSKEY nextTimestamp = loadRequiredBlockIntoMem(pRuntimeEnv, &pRuntimeEnv->nextPos);
|
||||
assert(nextTimestamp > 0 || ((nextTimestamp < 0) && Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK)));
|
||||
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, query abort due to buffer limitation, next qrange:%" PRId64 "-%" PRId64, pQInfo,
|
||||
pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->lastKey, pQuery->ekey);
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, query abort due to buffer limitation, next qrange:%" PRId64 "-%" PRId64,
|
||||
pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->lastKey, pQuery->ekey);
|
||||
}
|
||||
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, %d points returned, totalRead:%d totalReturn:%d", pQInfo, pMeterObj->vnode,
|
||||
|
@ -1080,58 +1080,39 @@ static void vnodeSingleTableMultiOutputProcessor(SQInfo *pQInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
static void vnodeSingleMeterIntervalMainLooper(SMeterQuerySupportObj *pSupporter, SQueryRuntimeEnv *pRuntimeEnv) {
|
||||
static void vnodeSingleMeterIntervalMainLooper(STableQuerySupportObj *pSupporter, SQueryRuntimeEnv *pRuntimeEnv) {
|
||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||
|
||||
while (1) {
|
||||
assert((pQuery->skey <= pQuery->ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(pQuery->skey >= pQuery->ekey && !QUERY_IS_ASC_QUERY(pQuery)));
|
||||
|
||||
initCtxOutputBuf(pRuntimeEnv);
|
||||
clearCompletedSlidingWindows(pRuntimeEnv);
|
||||
|
||||
vnodeScanAllData(pRuntimeEnv);
|
||||
|
||||
if (isQueryKilled(pQuery)) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!Q_STATUS_EQUAL(pQuery->over, QUERY_NOT_COMPLETED));
|
||||
|
||||
// clear tag, used to decide if the whole interval query is completed or not
|
||||
pQuery->over &= (~QUERY_COMPLETED);
|
||||
doFinalizeResult(pRuntimeEnv);
|
||||
|
||||
int64_t maxOutput = getNumOfResult(pRuntimeEnv);
|
||||
|
||||
// here we can ignore the records in case of no interpolation
|
||||
// todo handle offset, in case of top/bottom interval query
|
||||
if ((pQuery->numOfFilterCols > 0 || pRuntimeEnv->pTSBuf != NULL) && pQuery->limit.offset > 0 &&
|
||||
pQuery->interpoType == TSDB_INTERPO_NONE) { // maxOutput <= 0, means current query does not generate any results
|
||||
// todo handle offset, in case of top/bottom interval query
|
||||
if (maxOutput > 0) {
|
||||
pQuery->limit.offset--;
|
||||
}
|
||||
} else {
|
||||
pQuery->pointsRead += maxOutput;
|
||||
forwardCtxOutputBuf(pRuntimeEnv, maxOutput);
|
||||
pQuery->interpoType == TSDB_INTERPO_NONE) {
|
||||
// maxOutput <= 0, means current query does not generate any results
|
||||
int32_t numOfClosed = numOfClosedTimeWindow(&pRuntimeEnv->windowResInfo);
|
||||
|
||||
int32_t c = MIN(numOfClosed, pQuery->limit.offset);
|
||||
clearFirstNTimeWindow(pRuntimeEnv, c);
|
||||
pQuery->limit.offset -= c;
|
||||
}
|
||||
|
||||
if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK)) {
|
||||
if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK | QUERY_COMPLETED)) {
|
||||
break;
|
||||
}
|
||||
|
||||
forwardIntervalQueryRange(pSupporter, pRuntimeEnv);
|
||||
if (Q_STATUS_EQUAL(pQuery->over, QUERY_COMPLETED|QUERY_RESBUF_FULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* the scan limitation mechanism is upon here,
|
||||
* 1. since there is only one(k) record is generated in one scan operation
|
||||
* 2. remain space is not sufficient for next query output, abort
|
||||
*/
|
||||
if ((pQuery->pointsRead % pQuery->pointsToRead == 0 && pQuery->pointsRead != 0) ||
|
||||
((pQuery->pointsRead + maxOutput) > pQuery->pointsToRead)) {
|
||||
setQueryStatus(pQuery, QUERY_RESBUF_FULL);
|
||||
// load the data block for the next retrieve
|
||||
loadRequiredBlockIntoMem(pRuntimeEnv, &pRuntimeEnv->nextPos);
|
||||
if (Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1142,7 +1123,7 @@ static void vnodeSingleTableIntervalProcessor(SQInfo *pQInfo) {
|
|||
SQuery * pQuery = &(pQInfo->query);
|
||||
SMeterObj *pMeterObj = pQInfo->pObj;
|
||||
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv;
|
||||
|
||||
int32_t numOfInterpo = 0;
|
||||
|
@ -1151,6 +1132,14 @@ static void vnodeSingleTableIntervalProcessor(SQInfo *pQInfo) {
|
|||
resetCtxOutputBuf(pRuntimeEnv);
|
||||
vnodeSingleMeterIntervalMainLooper(pSupporter, pRuntimeEnv);
|
||||
|
||||
if (pQuery->intervalTime > 0) {
|
||||
pSupporter->subgroupIdx = 0; // always start from 0
|
||||
pQuery->pointsRead = 0;
|
||||
copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult);
|
||||
|
||||
clearFirstNTimeWindow(pRuntimeEnv, pSupporter->subgroupIdx);
|
||||
}
|
||||
|
||||
// the offset is handled at prepare stage if no interpolation involved
|
||||
if (pQuery->interpoType == TSDB_INTERPO_NONE) {
|
||||
doRevisedResultsByLimit(pQInfo);
|
||||
|
@ -1177,11 +1166,13 @@ static void vnodeSingleTableIntervalProcessor(SQInfo *pQInfo) {
|
|||
pQuery->pointsRead = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (isGroupbyNormalCol(pQuery->pGroupbyExpr) || (pQuery->slidingTime > 0 && pQuery->nAggTimeInterval > 0)) {
|
||||
pQInfo->pMeterQuerySupporter->subgroupIdx = 0;
|
||||
|
||||
// all data scanned, the group by normal column can return
|
||||
if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) {//todo refactor with merge interval time result
|
||||
pSupporter->subgroupIdx = 0;
|
||||
pQuery->pointsRead = 0;
|
||||
copyFromGroupBuf(pQInfo, pRuntimeEnv->swindowResInfo.pResult);
|
||||
copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult);
|
||||
clearFirstNTimeWindow(pRuntimeEnv, pSupporter->subgroupIdx);
|
||||
}
|
||||
|
||||
pQInfo->pointsRead += pQuery->pointsRead;
|
||||
|
@ -1195,7 +1186,7 @@ static void vnodeSingleTableIntervalProcessor(SQInfo *pQInfo) {
|
|||
void vnodeSingleTableQuery(SSchedMsg *pMsg) {
|
||||
SQInfo *pQInfo = (SQInfo *)pMsg->ahandle;
|
||||
|
||||
if (pQInfo == NULL || pQInfo->pMeterQuerySupporter == NULL) {
|
||||
if (pQInfo == NULL || pQInfo->pTableQuerySupporter == NULL) {
|
||||
dTrace("%p freed abort query", pQInfo);
|
||||
return;
|
||||
}
|
||||
|
@ -1203,21 +1194,22 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) {
|
|||
if (pQInfo->killed) {
|
||||
dTrace("QInfo:%p it is already killed, abort", pQInfo);
|
||||
vnodeDecRefCount(pQInfo);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pQInfo->refCount >= 1);
|
||||
|
||||
SQuery * pQuery = &pQInfo->query;
|
||||
SMeterObj *pMeterObj = pQInfo->pObj;
|
||||
SQuery * pQuery = &pQInfo->query;
|
||||
SMeterObj * pMeterObj = pQInfo->pObj;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
SQueryRuntimeEnv * pRuntimeEnv = &pSupporter->runtimeEnv;
|
||||
|
||||
assert(pRuntimeEnv->pMeterObj == pMeterObj);
|
||||
|
||||
dTrace("vid:%d sid:%d id:%s, query thread is created, numOfQueries:%d, QInfo:%p", pMeterObj->vnode, pMeterObj->sid,
|
||||
pMeterObj->meterId, pMeterObj->numOfQueries, pQInfo);
|
||||
|
||||
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->pMeterQuerySupporter->runtimeEnv;
|
||||
assert(pRuntimeEnv->pMeterObj == pMeterObj);
|
||||
|
||||
if (vnodeHasRemainResults(pQInfo)) {
|
||||
/*
|
||||
* There are remain results that are not returned due to result interpolation
|
||||
|
@ -1249,12 +1241,18 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) {
|
|||
// here we have scan all qualified data in both data file and cache
|
||||
if (Q_STATUS_EQUAL(pQuery->over, QUERY_NO_DATA_TO_CHECK | QUERY_COMPLETED)) {
|
||||
// continue to get push data from the group result
|
||||
if (isGroupbyNormalCol(pQuery->pGroupbyExpr)) {
|
||||
if (isGroupbyNormalCol(pQuery->pGroupbyExpr) ||
|
||||
(pQuery->intervalTime > 0 && pQInfo->pointsReturned < pQuery->limit.limit)) {
|
||||
//todo limit the output for interval query?
|
||||
pQuery->pointsRead = 0;
|
||||
if (pQInfo->pMeterQuerySupporter->subgroupIdx > 0) {
|
||||
copyFromGroupBuf(pQInfo, pQInfo->pMeterQuerySupporter->pResult);
|
||||
pSupporter->subgroupIdx = 0; // always start from 0
|
||||
|
||||
if (pRuntimeEnv->windowResInfo.size > 0) {
|
||||
copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult);
|
||||
pQInfo->pointsRead += pQuery->pointsRead;
|
||||
|
||||
clearFirstNTimeWindow(pRuntimeEnv, pSupporter->subgroupIdx);
|
||||
|
||||
if (pQuery->pointsRead > 0) {
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, %d points returned %d from group results, totalRead:%d totalReturn:%d",
|
||||
pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->pointsRead, pQInfo->pointsRead,
|
||||
|
@ -1262,19 +1260,19 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) {
|
|||
|
||||
sem_post(&pQInfo->dataReady);
|
||||
vnodeDecRefCount(pQInfo);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pQInfo->over = 1;
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, query over, %d points are returned", pQInfo,
|
||||
pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQInfo->pointsRead);
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, query over, %d points are returned", pQInfo, pMeterObj->vnode, pMeterObj->sid,
|
||||
pMeterObj->meterId, pQInfo->pointsRead);
|
||||
|
||||
vnodePrintQueryStatistics(pQInfo->pMeterQuerySupporter);
|
||||
vnodePrintQueryStatistics(pSupporter);
|
||||
sem_post(&pQInfo->dataReady);
|
||||
|
||||
|
||||
vnodeDecRefCount(pQInfo);
|
||||
return;
|
||||
}
|
||||
|
@ -1286,7 +1284,7 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) {
|
|||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
// group by normal column, sliding window query, interval query are handled by interval query processor
|
||||
if (pQuery->nAggTimeInterval != 0 || isGroupbyNormalCol(pQuery->pGroupbyExpr)) { // interval (down sampling operation)
|
||||
if (pQuery->intervalTime != 0 || isGroupbyNormalCol(pQuery->pGroupbyExpr)) { // interval (down sampling operation)
|
||||
assert(pQuery->checkBufferInLoop == 0 && pQuery->pointsOffset == pQuery->pointsToRead);
|
||||
vnodeSingleTableIntervalProcessor(pQInfo);
|
||||
} else {
|
||||
|
@ -1307,8 +1305,8 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) {
|
|||
dTrace("QInfo:%p query is killed", pQInfo);
|
||||
pQInfo->over = 1;
|
||||
} else {
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, meter query thread completed, %d points are returned",
|
||||
pQInfo, pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->pointsRead);
|
||||
dTrace("QInfo:%p vid:%d sid:%d id:%s, meter query thread completed, %d points are returned", pQInfo,
|
||||
pMeterObj->vnode, pMeterObj->sid, pMeterObj->meterId, pQuery->pointsRead);
|
||||
}
|
||||
|
||||
sem_post(&pQInfo->dataReady);
|
||||
|
@ -1318,7 +1316,7 @@ void vnodeSingleTableQuery(SSchedMsg *pMsg) {
|
|||
void vnodeMultiMeterQuery(SSchedMsg *pMsg) {
|
||||
SQInfo *pQInfo = (SQInfo *)pMsg->ahandle;
|
||||
|
||||
if (pQInfo == NULL || pQInfo->pMeterQuerySupporter == NULL) {
|
||||
if (pQInfo == NULL || pQInfo->pTableQuerySupporter == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1334,12 +1332,12 @@ void vnodeMultiMeterQuery(SSchedMsg *pMsg) {
|
|||
pQuery->pointsRead = 0;
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
if (pQuery->nAggTimeInterval > 0 ||
|
||||
if (pQuery->intervalTime > 0 ||
|
||||
(isFixedOutputQuery(pQuery) && (!isPointInterpoQuery(pQuery)) && !isGroupbyNormalCol(pQuery->pGroupbyExpr))) {
|
||||
assert(pQuery->checkBufferInLoop == 0);
|
||||
vnodeMultiMeterQueryProcessor(pQInfo);
|
||||
} else {
|
||||
assert((pQuery->checkBufferInLoop == 1 && pQuery->nAggTimeInterval == 0) || isPointInterpoQuery(pQuery) ||
|
||||
assert((pQuery->checkBufferInLoop == 1 && pQuery->intervalTime == 0) || isPointInterpoQuery(pQuery) ||
|
||||
isGroupbyNormalCol(pQuery->pGroupbyExpr));
|
||||
|
||||
vnodeSTableSeqProcessor(pQInfo);
|
||||
|
@ -1349,10 +1347,10 @@ void vnodeMultiMeterQuery(SSchedMsg *pMsg) {
|
|||
pQInfo->useconds += (taosGetTimestampUs() - st);
|
||||
pQInfo->over = isQueryKilled(pQuery) ? 1 : 0;
|
||||
|
||||
taosInterpoSetStartInfo(&pQInfo->pMeterQuerySupporter->runtimeEnv.interpoInfo, pQuery->pointsRead,
|
||||
taosInterpoSetStartInfo(&pQInfo->pTableQuerySupporter->runtimeEnv.interpoInfo, pQuery->pointsRead,
|
||||
pQInfo->query.interpoType);
|
||||
|
||||
SMeterQuerySupportObj *pSupporter = pQInfo->pMeterQuerySupporter;
|
||||
STableQuerySupportObj *pSupporter = pQInfo->pTableQuerySupporter;
|
||||
|
||||
if (pQuery->pointsRead == 0) {
|
||||
pQInfo->over = 1;
|
||||
|
|
|
@ -266,7 +266,7 @@ static SQInfo *vnodeAllocateQInfoEx(SQueryMeterMsg *pQueryMsg, SSqlGroupbyExpr *
|
|||
}
|
||||
|
||||
pQuery->pGroupbyExpr = pGroupbyExpr;
|
||||
pQuery->nAggTimeInterval = pQueryMsg->nAggTimeInterval;
|
||||
pQuery->intervalTime = pQueryMsg->intervalTime;
|
||||
pQuery->slidingTime = pQueryMsg->slidingTime;
|
||||
pQuery->interpoType = pQueryMsg->interpoType;
|
||||
pQuery->intervalTimeUnit = pQueryMsg->intervalTimeUnit;
|
||||
|
@ -648,7 +648,7 @@ void *vnodeQueryOnSingleTable(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE
|
|||
goto _error;
|
||||
}
|
||||
|
||||
SMeterQuerySupportObj *pSupporter = (SMeterQuerySupportObj *)calloc(1, sizeof(SMeterQuerySupportObj));
|
||||
STableQuerySupportObj *pSupporter = (STableQuerySupportObj *)calloc(1, sizeof(STableQuerySupportObj));
|
||||
pSupporter->numOfMeters = 1;
|
||||
|
||||
pSupporter->pMetersHashTable = taosInitHashTable(pSupporter->numOfMeters, taosIntHash_32, false);
|
||||
|
@ -659,7 +659,7 @@ void *vnodeQueryOnSingleTable(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE
|
|||
pSupporter->subgroupIdx = -1;
|
||||
pSupporter->pMeterSidExtInfo = NULL;
|
||||
|
||||
pQInfo->pMeterQuerySupporter = pSupporter;
|
||||
pQInfo->pTableQuerySupporter = pSupporter;
|
||||
|
||||
STSBuf *pTSBuf = NULL;
|
||||
if (pQueryMsg->tsLen > 0) {
|
||||
|
@ -670,7 +670,7 @@ void *vnodeQueryOnSingleTable(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE
|
|||
tsBufNextPos(pTSBuf);
|
||||
}
|
||||
|
||||
if (((*code) = vnodeQuerySingleMeterPrepare(pQInfo, pQInfo->pObj, pSupporter, pTSBuf)) != TSDB_CODE_SUCCESS) {
|
||||
if (((*code) = vnodeQueryTablePrepare(pQInfo, pQInfo->pObj, pSupporter, pTSBuf)) != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
|
@ -739,7 +739,7 @@ void *vnodeQueryOnMultiMeters(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE
|
|||
|
||||
SSchedMsg schedMsg = {0};
|
||||
|
||||
SMeterQuerySupportObj *pSupporter = (SMeterQuerySupportObj *)calloc(1, sizeof(SMeterQuerySupportObj));
|
||||
STableQuerySupportObj *pSupporter = (STableQuerySupportObj *)calloc(1, sizeof(STableQuerySupportObj));
|
||||
pSupporter->numOfMeters = pQueryMsg->numOfSids;
|
||||
|
||||
pSupporter->pMetersHashTable = taosInitHashTable(pSupporter->numOfMeters, taosIntHash_32, false);
|
||||
|
@ -784,7 +784,7 @@ void *vnodeQueryOnMultiMeters(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE
|
|||
(SSchema *)pQueryMsg->pTagSchema, pQueryMsg->numOfTagsCols, NULL, 0);
|
||||
}
|
||||
|
||||
pQInfo->pMeterQuerySupporter = pSupporter;
|
||||
pQInfo->pTableQuerySupporter = pSupporter;
|
||||
|
||||
STSBuf *pTSBuf = NULL;
|
||||
if (pQueryMsg->tsLen > 0) {
|
||||
|
@ -794,7 +794,7 @@ void *vnodeQueryOnMultiMeters(SMeterObj **pMetersObj, SSqlGroupbyExpr *pGroupbyE
|
|||
tsBufResetPos(pTSBuf);
|
||||
}
|
||||
|
||||
if (((*code) = vnodeMultiMeterQueryPrepare(pQInfo, pQuery, pTSBuf)) != TSDB_CODE_SUCCESS) {
|
||||
if (((*code) = vnodeSTableQueryPrepare(pQInfo, pQuery, pTSBuf)) != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
|
@ -898,8 +898,8 @@ int vnodeSaveQueryResult(void *handle, char *data, int32_t *size) {
|
|||
|
||||
SSchedMsg schedMsg = {0};
|
||||
|
||||
if (pQInfo->pMeterQuerySupporter != NULL) {
|
||||
if (pQInfo->pMeterQuerySupporter->pSidSet == NULL) {
|
||||
if (pQInfo->pTableQuerySupporter != NULL) {
|
||||
if (pQInfo->pTableQuerySupporter->pSidSet == NULL) {
|
||||
schedMsg.fp = vnodeSingleTableQuery;
|
||||
} else { // group by tag
|
||||
schedMsg.fp = vnodeMultiMeterQuery;
|
||||
|
@ -920,8 +920,8 @@ int vnodeSaveQueryResult(void *handle, char *data, int32_t *size) {
|
|||
}
|
||||
|
||||
static int32_t validateQueryMeterMsg(SQueryMeterMsg *pQueryMsg) {
|
||||
if (pQueryMsg->nAggTimeInterval < 0) {
|
||||
dError("qmsg:%p illegal value of aggTimeInterval %" PRId64 "", pQueryMsg, pQueryMsg->nAggTimeInterval);
|
||||
if (pQueryMsg->intervalTime < 0) {
|
||||
dError("qmsg:%p illegal value of aggTimeInterval %" PRId64 "", pQueryMsg, pQueryMsg->intervalTime);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -975,7 +975,7 @@ int32_t vnodeConvertQueryMeterMsg(SQueryMeterMsg *pQueryMsg) {
|
|||
|
||||
pQueryMsg->queryType = htons(pQueryMsg->queryType);
|
||||
|
||||
pQueryMsg->nAggTimeInterval = htobe64(pQueryMsg->nAggTimeInterval);
|
||||
pQueryMsg->intervalTime = htobe64(pQueryMsg->intervalTime);
|
||||
pQueryMsg->slidingTime = htobe64(pQueryMsg->slidingTime);
|
||||
|
||||
pQueryMsg->numOfTagsCols = htons(pQueryMsg->numOfTagsCols);
|
||||
|
@ -1146,7 +1146,7 @@ int32_t vnodeConvertQueryMeterMsg(SQueryMeterMsg *pQueryMsg) {
|
|||
"offset:%" PRId64,
|
||||
pQueryMsg, pQueryMsg->numOfSids, pQueryMsg->skey, pQueryMsg->ekey, pQueryMsg->numOfGroupCols,
|
||||
pQueryMsg->numOfTagsCols, pQueryMsg->order, pQueryMsg->orderType, pQueryMsg->orderByIdx,
|
||||
pQueryMsg->numOfOutputCols, pQueryMsg->numOfCols, pQueryMsg->nAggTimeInterval, pQueryMsg->interpoType,
|
||||
pQueryMsg->numOfOutputCols, pQueryMsg->numOfCols, pQueryMsg->intervalTime, pQueryMsg->interpoType,
|
||||
pQueryMsg->tsLen, pQueryMsg->limit, pQueryMsg->offset);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -446,8 +446,8 @@ void vnodeExecuteRetrieveReq(SSchedMsg *pSched) {
|
|||
// buffer size for progress information, including meter count,
|
||||
// and for each meter, including 'uid' and 'TSKEY'.
|
||||
int progressSize = 0;
|
||||
if (pQInfo->pMeterQuerySupporter != NULL)
|
||||
progressSize = pQInfo->pMeterQuerySupporter->numOfMeters * (sizeof(int64_t) + sizeof(TSKEY)) + sizeof(int32_t);
|
||||
if (pQInfo->pTableQuerySupporter != NULL)
|
||||
progressSize = pQInfo->pTableQuerySupporter->numOfMeters * (sizeof(int64_t) + sizeof(TSKEY)) + sizeof(int32_t);
|
||||
else if (pQInfo->pObj != NULL)
|
||||
progressSize = sizeof(int64_t) + sizeof(TSKEY) + sizeof(int32_t);
|
||||
|
||||
|
@ -486,13 +486,13 @@ void vnodeExecuteRetrieveReq(SSchedMsg *pSched) {
|
|||
// write the progress information of each meter to response
|
||||
// this is required by subscriptions
|
||||
if (pQInfo != NULL ) {
|
||||
if (pQInfo->pMeterQuerySupporter != NULL && pQInfo->pMeterQuerySupporter->pMeterSidExtInfo != NULL) {
|
||||
*((int32_t *)pMsg) = htonl(pQInfo->pMeterQuerySupporter->numOfMeters);
|
||||
if (pQInfo->pTableQuerySupporter != NULL && pQInfo->pTableQuerySupporter->pMeterSidExtInfo != NULL) {
|
||||
*((int32_t *)pMsg) = htonl(pQInfo->pTableQuerySupporter->numOfMeters);
|
||||
pMsg += sizeof(int32_t);
|
||||
for (int32_t i = 0; i < pQInfo->pMeterQuerySupporter->numOfMeters; i++) {
|
||||
*((int64_t *)pMsg) = htobe64(pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[i]->uid);
|
||||
for (int32_t i = 0; i < pQInfo->pTableQuerySupporter->numOfMeters; i++) {
|
||||
*((int64_t *)pMsg) = htobe64(pQInfo->pTableQuerySupporter->pMeterSidExtInfo[i]->uid);
|
||||
pMsg += sizeof(int64_t);
|
||||
*((TSKEY *)pMsg) = htobe64(pQInfo->pMeterQuerySupporter->pMeterSidExtInfo[i]->key);
|
||||
*((TSKEY *)pMsg) = htobe64(pQInfo->pTableQuerySupporter->pMeterSidExtInfo[i]->key);
|
||||
pMsg += sizeof(TSKEY);
|
||||
}
|
||||
} else if (pQInfo->pObj != NULL) {
|
||||
|
|
|
@ -372,18 +372,22 @@ void vnodeUpdateFilterColumnIndex(SQuery* pQuery) {
|
|||
}
|
||||
|
||||
// set the column index in buffer for arithmetic operation
|
||||
if (pQuery->pSelectExpr != NULL) {
|
||||
for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) {
|
||||
SSqlBinaryExprInfo* pBinExprInfo = &pQuery->pSelectExpr[i].pBinExprInfo;
|
||||
if (pBinExprInfo->pBinExpr != NULL) {
|
||||
for (int16_t j = 0; j < pBinExprInfo->numOfCols; ++j) {
|
||||
for (int32_t k = 0; k < pQuery->numOfCols; ++k) {
|
||||
if (pBinExprInfo->pReqColumns[j].colId == pQuery->colList[k].data.colId) {
|
||||
pBinExprInfo->pReqColumns[j].colIdxInBuf = pQuery->colList[k].colIdxInBuf;
|
||||
assert(pQuery->colList[k].colIdxInBuf == k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pQuery->pSelectExpr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) {
|
||||
SSqlBinaryExprInfo* pBinExprInfo = &pQuery->pSelectExpr[i].pBinExprInfo;
|
||||
if (pBinExprInfo->pBinExpr == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int16_t j = 0; j < pBinExprInfo->numOfCols; ++j) {
|
||||
for (int32_t k = 0; k < pQuery->numOfCols; ++k) {
|
||||
if (pBinExprInfo->pReqColumns[j].colId == pQuery->colList[k].data.colId) {
|
||||
pBinExprInfo->pReqColumns[j].colIdxInBuf = pQuery->colList[k].colIdxInBuf;
|
||||
assert(pQuery->colList[k].colIdxInBuf == k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -340,10 +340,6 @@ static void doAddToHashTable(HashObj *pObj, SHashNode *pNode) {
|
|||
|
||||
pEntry->num++;
|
||||
pObj->size++;
|
||||
|
||||
// char key[512] = {0};
|
||||
// memcpy(key, pNode->key, MIN(512, pNode->keyLen));
|
||||
// pTrace("key:%s %p add to hash table", key, pNode);
|
||||
}
|
||||
|
||||
int32_t taosNumElemsInHashTable(HashObj *pObj) {
|
||||
|
@ -525,29 +521,3 @@ int32_t taosGetHashMaxOverflowLength(HashObj* pObj) {
|
|||
|
||||
return num;
|
||||
}
|
||||
|
||||
int32_t taosCheckHashTable(HashObj *pObj) {
|
||||
for(int32_t i = 0; i < pObj->capacity; ++i) {
|
||||
SHashEntry *pEntry = pObj->hashList[i];
|
||||
|
||||
SHashNode* pNode = pEntry->next;
|
||||
if (pNode != NULL) {
|
||||
assert(pEntry == pNode->prev1);
|
||||
int32_t num = 1;
|
||||
|
||||
SHashNode* pNext = pNode->next;
|
||||
|
||||
while(pNext) {
|
||||
assert(pNext->prev == pNode);
|
||||
|
||||
pNode = pNext;
|
||||
pNext = pNext->next;
|
||||
num ++;
|
||||
}
|
||||
|
||||
assert(num == pEntry->num);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -468,8 +468,8 @@ int32_t compare_a(tOrderDescriptor *pDescriptor, int32_t numOfRows1, int32_t s1,
|
|||
return ret;
|
||||
}
|
||||
} else {
|
||||
SSchema *pSchema = &pDescriptor->pColumnModel->pFields[colIdx];
|
||||
int32_t ret = columnValueAscendingComparator(f1, f2, pSchema->type, pSchema->bytes);
|
||||
SSchemaEx *pSchema = &pDescriptor->pColumnModel->pFields[colIdx];
|
||||
int32_t ret = columnValueAscendingComparator(f1, f2, pSchema->field.type, pSchema->field.bytes);
|
||||
if (ret == 0) {
|
||||
continue;
|
||||
} else {
|
||||
|
@ -500,8 +500,8 @@ int32_t compare_d(tOrderDescriptor *pDescriptor, int32_t numOfRows1, int32_t s1,
|
|||
return ret;
|
||||
}
|
||||
} else {
|
||||
SSchema *pSchema = &pDescriptor->pColumnModel->pFields[colIdx];
|
||||
int32_t ret = columnValueAscendingComparator(f1, f2, pSchema->type, pSchema->bytes);
|
||||
SSchemaEx *pSchema = &pDescriptor->pColumnModel->pFields[colIdx];
|
||||
int32_t ret = columnValueAscendingComparator(f1, f2, pSchema->field.type, pSchema->field.bytes);
|
||||
if (ret == 0) {
|
||||
continue;
|
||||
} else {
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "textbuffer.h"
|
||||
|
@ -47,7 +44,7 @@ int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t timeRange, char
|
|||
char** tzname = _tzname;
|
||||
#endif
|
||||
|
||||
int64_t t = (precision == TSDB_TIME_PRECISION_MILLI)?MILLISECOND_PER_SECOND:MILLISECOND_PER_SECOND*1000L;
|
||||
int64_t t = (precision == TSDB_TIME_PRECISION_MILLI) ? MILLISECOND_PER_SECOND : MILLISECOND_PER_SECOND * 1000L;
|
||||
|
||||
int64_t revStartime = (startTime / timeRange) * timeRange + timezone * t;
|
||||
int64_t revEndtime = revStartime + timeRange - 1;
|
||||
|
@ -78,14 +75,14 @@ void taosInitInterpoInfo(SInterpolationInfo* pInterpoInfo, int32_t order, int64_
|
|||
}
|
||||
|
||||
// the SInterpolationInfo itself will not be released
|
||||
void taosDestoryInterpoInfo(SInterpolationInfo *pInterpoInfo) {
|
||||
void taosDestoryInterpoInfo(SInterpolationInfo* pInterpoInfo) {
|
||||
if (pInterpoInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
tfree(pInterpoInfo->prevValues);
|
||||
tfree(pInterpoInfo->nextValues);
|
||||
|
||||
|
||||
tfree(pInterpoInfo->pTags);
|
||||
}
|
||||
|
||||
|
@ -94,7 +91,7 @@ void taosInterpoSetStartInfo(SInterpolationInfo* pInterpoInfo, int32_t numOfRawD
|
|||
return;
|
||||
}
|
||||
|
||||
pInterpoInfo->rowIdx = 0;//INTERPOL_IS_ASC_INTERPOL(pInterpoInfo) ? 0 : numOfRawDataInRows - 1;
|
||||
pInterpoInfo->rowIdx = 0; // INTERPOL_IS_ASC_INTERPOL(pInterpoInfo) ? 0 : numOfRawDataInRows - 1;
|
||||
pInterpoInfo->numOfRawDataInRows = numOfRawDataInRows;
|
||||
}
|
||||
|
||||
|
@ -118,14 +115,9 @@ int32_t taosGetNumOfResWithoutLimit(SInterpolationInfo* pInterpoInfo, int64_t* p
|
|||
if (numOfAvailRawData > 0) {
|
||||
int32_t finalNumOfResult = 0;
|
||||
|
||||
// if (pInterpoInfo->order == TSQL_SO_ASC) {
|
||||
// get last timestamp, calculate the result size
|
||||
int64_t lastKey = pPrimaryKeyArray[pInterpoInfo->numOfRawDataInRows - 1];
|
||||
finalNumOfResult = (int32_t)(labs(lastKey - pInterpoInfo->startTimestamp) / nInterval) + 1;
|
||||
// } else { // todo error less than one!!!
|
||||
// TSKEY lastKey = pPrimaryKeyArray[0];
|
||||
// finalNumOfResult = (int32_t)((pInterpoInfo->startTimestamp - lastKey) / nInterval) + 1;
|
||||
// }
|
||||
// get last timestamp, calculate the result size
|
||||
int64_t lastKey = pPrimaryKeyArray[pInterpoInfo->numOfRawDataInRows - 1];
|
||||
finalNumOfResult = (int32_t)(labs(lastKey - pInterpoInfo->startTimestamp) / nInterval) + 1;
|
||||
|
||||
assert(finalNumOfResult >= numOfAvailRawData);
|
||||
return finalNumOfResult;
|
||||
|
@ -140,7 +132,9 @@ int32_t taosGetNumOfResWithoutLimit(SInterpolationInfo* pInterpoInfo, int64_t* p
|
|||
}
|
||||
}
|
||||
|
||||
bool taosHasRemainsDataForInterpolation(SInterpolationInfo* pInterpoInfo) { return taosNumOfRemainPoints(pInterpoInfo) > 0; }
|
||||
bool taosHasRemainsDataForInterpolation(SInterpolationInfo* pInterpoInfo) {
|
||||
return taosNumOfRemainPoints(pInterpoInfo) > 0;
|
||||
}
|
||||
|
||||
int32_t taosNumOfRemainPoints(SInterpolationInfo* pInterpoInfo) {
|
||||
if (pInterpoInfo->rowIdx == -1 || pInterpoInfo->numOfRawDataInRows == 0) {
|
||||
|
@ -197,28 +191,22 @@ int taosDoLinearInterpolation(int32_t type, SPoint* point1, SPoint* point2, SPoi
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char* getPos(char* data, int32_t bytes, int32_t order, int32_t capacity, int32_t index) {
|
||||
// if (order == TSQL_SO_ASC) {
|
||||
return data + index * bytes;
|
||||
// } else {
|
||||
// return data + (capacity - index - 1) * bytes;
|
||||
// }
|
||||
}
|
||||
static char* getPos(char* data, int32_t bytes, int32_t index) { return data + index * bytes; }
|
||||
|
||||
static void setTagsValueInInterpolation(tFilePage** data, char** pTags, SColumnModel* pModel, int32_t order, int32_t start,
|
||||
int32_t capacity, int32_t num) {
|
||||
static void setTagsValueInInterpolation(tFilePage** data, char** pTags, SColumnModel* pModel, int32_t order,
|
||||
int32_t start, int32_t capacity, int32_t num) {
|
||||
for (int32_t j = 0, i = start; i < pModel->numOfCols; ++i, ++j) {
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, order, capacity, num);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, num);
|
||||
assignVal(val1, pTags[j], pSchema->bytes, pSchema->type);
|
||||
}
|
||||
}
|
||||
|
||||
static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interpoType, tFilePage** data,
|
||||
SColumnModel* pModel, int32_t* num, char** srcData, int64_t nInterval, int64_t* defaultVal,
|
||||
int64_t currentTimestamp, int32_t capacity, int32_t numOfTags, char** pTags,
|
||||
bool outOfBound) {
|
||||
SColumnModel* pModel, int32_t* num, char** srcData, int64_t nInterval,
|
||||
int64_t* defaultVal, int64_t currentTimestamp, int32_t capacity, int32_t numOfTags,
|
||||
char** pTags, bool outOfBound) {
|
||||
char** prevValues = &pInterpoInfo->prevValues;
|
||||
char** nextValues = &pInterpoInfo->nextValues;
|
||||
|
||||
|
@ -226,7 +214,7 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp
|
|||
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pInterpoInfo->order);
|
||||
|
||||
char* val = getPos(data[0]->data, TSDB_KEYSIZE, pInterpoInfo->order, capacity, *num);
|
||||
char* val = getPos(data[0]->data, TSDB_KEYSIZE, *num);
|
||||
*(TSKEY*)val = pInterpoInfo->startTimestamp;
|
||||
|
||||
int32_t numOfValCols = pModel->numOfCols - numOfTags;
|
||||
|
@ -237,9 +225,9 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp
|
|||
if (pInterpolationData != NULL) {
|
||||
for (int32_t i = 1; i < numOfValCols; ++i) {
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||
int16_t offset = getColumnModelOffset(pModel, i);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num);
|
||||
int16_t offset = getColumnModelOffset(pModel, i);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, *num);
|
||||
|
||||
if (isNull(pInterpolationData + offset, pSchema->type)) {
|
||||
setNull(val1, pSchema->type, pSchema->bytes);
|
||||
|
@ -250,8 +238,8 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp
|
|||
} else { /* no prev value yet, set the value for null */
|
||||
for (int32_t i = 1; i < numOfValCols; ++i) {
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, *num);
|
||||
setNull(val1, pSchema->type, pSchema->bytes);
|
||||
}
|
||||
}
|
||||
|
@ -262,10 +250,10 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp
|
|||
if (*prevValues != NULL && !outOfBound) {
|
||||
for (int32_t i = 1; i < numOfValCols; ++i) {
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||
int16_t offset = getColumnModelOffset(pModel, i);
|
||||
|
||||
int16_t offset = getColumnModelOffset(pModel, i);
|
||||
|
||||
int16_t type = pSchema->type;
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num);
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, *num);
|
||||
|
||||
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BOOL) {
|
||||
setNull(val1, type, pSchema->bytes);
|
||||
|
@ -283,8 +271,8 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp
|
|||
} else {
|
||||
for (int32_t i = 1; i < numOfValCols; ++i) {
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, *num);
|
||||
setNull(val1, pSchema->type, pSchema->bytes);
|
||||
}
|
||||
|
||||
|
@ -293,8 +281,8 @@ static void doInterpoResultImpl(SInterpolationInfo* pInterpoInfo, int16_t interp
|
|||
} else { /* default value interpolation */
|
||||
for (int32_t i = 1; i < numOfValCols; ++i) {
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, capacity, *num);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, *num);
|
||||
assignVal(val1, (char*)&defaultVal[i], pSchema->bytes, pSchema->type);
|
||||
}
|
||||
|
||||
|
@ -344,9 +332,9 @@ int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoTyp
|
|||
if (*nextValues == NULL) {
|
||||
*nextValues = calloc(1, pModel->rowSize);
|
||||
for (int i = 1; i < pModel->numOfCols; i++) {
|
||||
int16_t offset = getColumnModelOffset(pModel, i);
|
||||
int16_t offset = getColumnModelOffset(pModel, i);
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||
|
||||
|
||||
setNull(*nextValues + offset, pSchema->type, pSchema->bytes);
|
||||
}
|
||||
}
|
||||
|
@ -354,33 +342,36 @@ int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoTyp
|
|||
int32_t offset = pInterpoInfo->rowIdx;
|
||||
for (int32_t tlen = 0, i = 0; i < pModel->numOfCols - numOfTags; ++i) {
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||
|
||||
|
||||
memcpy(*nextValues + tlen, srcData[i] + offset * pSchema->bytes, pSchema->bytes);
|
||||
tlen += pSchema->bytes;
|
||||
}
|
||||
}
|
||||
|
||||
while (((pInterpoInfo->startTimestamp < currentTimestamp && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) ||
|
||||
(pInterpoInfo->startTimestamp > currentTimestamp && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) &&
|
||||
num < outputRows) {
|
||||
doInterpoResultImpl(pInterpoInfo, interpoType, data, pModel, &num, srcData, nInterval, defaultVal,
|
||||
currentTimestamp, bufSize, numOfTags, pTags, false);
|
||||
}
|
||||
if (((pInterpoInfo->startTimestamp < currentTimestamp && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) ||
|
||||
(pInterpoInfo->startTimestamp > currentTimestamp && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) &&
|
||||
num < outputRows) {
|
||||
while (((pInterpoInfo->startTimestamp < currentTimestamp && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) ||
|
||||
(pInterpoInfo->startTimestamp > currentTimestamp && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) &&
|
||||
num < outputRows) {
|
||||
doInterpoResultImpl(pInterpoInfo, interpoType, data, pModel, &num, srcData, nInterval, defaultVal,
|
||||
currentTimestamp, bufSize, numOfTags, pTags, false);
|
||||
}
|
||||
|
||||
/* output buffer is full, abort */
|
||||
if ((num == outputRows && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) ||
|
||||
(num < 0 && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) {
|
||||
pInterpoInfo->numOfTotalInterpo += pInterpoInfo->numOfCurrentInterpo;
|
||||
return outputRows;
|
||||
}
|
||||
|
||||
if (pInterpoInfo->startTimestamp == currentTimestamp) {
|
||||
/* output buffer is full, abort */
|
||||
if ((num == outputRows && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) ||
|
||||
(num < 0 && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo))) {
|
||||
pInterpoInfo->numOfTotalInterpo += pInterpoInfo->numOfCurrentInterpo;
|
||||
return outputRows;
|
||||
}
|
||||
} else {
|
||||
// if (pInterpoInfo->startTimestamp == currentTimestamp) {
|
||||
if (*prevValues == NULL) {
|
||||
*prevValues = calloc(1, pModel->rowSize);
|
||||
for (int i = 1; i < pModel->numOfCols; i++) {
|
||||
int16_t offset = getColumnModelOffset(pModel, i);
|
||||
int16_t offset = getColumnModelOffset(pModel, i);
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||
|
||||
|
||||
setNull(*prevValues + offset, pSchema->type, pSchema->bytes);
|
||||
}
|
||||
}
|
||||
|
@ -388,17 +379,16 @@ int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoTyp
|
|||
// assign rows to dst buffer
|
||||
int32_t i = 0;
|
||||
for (int32_t tlen = 0; i < pModel->numOfCols - numOfTags; ++i) {
|
||||
int16_t offset = getColumnModelOffset(pModel, i);
|
||||
int16_t offset = getColumnModelOffset(pModel, i);
|
||||
SSchema* pSchema = getColumnModelSchema(pModel, i);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, pInterpoInfo->order, bufSize, num);
|
||||
|
||||
char* val1 = getPos(data[i]->data, pSchema->bytes, num);
|
||||
|
||||
if (i == 0 ||
|
||||
(functionIDs[i] != TSDB_FUNC_COUNT &&
|
||||
!isNull(srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes, pSchema->type)) ||
|
||||
(functionIDs[i] == TSDB_FUNC_COUNT &&
|
||||
*(int64_t*)(srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes) != 0)) {
|
||||
|
||||
assignVal(val1, srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes, pSchema->bytes, pSchema->type);
|
||||
memcpy(*prevValues + tlen, srcData[i] + pInterpoInfo->rowIdx * pSchema->bytes, pSchema->bytes);
|
||||
} else { // i > 0 and isNULL, do interpolation
|
||||
|
@ -416,11 +406,11 @@ int32_t taosDoInterpoResult(SInterpolationInfo* pInterpoInfo, int16_t interpoTyp
|
|||
/* set the tag value for final result */
|
||||
setTagsValueInInterpolation(data, pTags, pModel, pInterpoInfo->order, pModel->numOfCols - numOfTags, bufSize,
|
||||
num);
|
||||
}
|
||||
|
||||
pInterpoInfo->startTimestamp += (nInterval * step);
|
||||
pInterpoInfo->rowIdx += 1;
|
||||
num += 1;
|
||||
pInterpoInfo->startTimestamp += (nInterval * step);
|
||||
pInterpoInfo->rowIdx += 1;
|
||||
num += 1;
|
||||
}
|
||||
|
||||
if ((pInterpoInfo->rowIdx >= pInterpoInfo->numOfRawDataInRows && INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) ||
|
||||
(pInterpoInfo->rowIdx < 0 && !INTERPOL_IS_ASC_INTERPOL(pInterpoInfo)) || num >= outputRows) {
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
#define DEFAULT_INTERN_BUF_SIZE 16384L
|
||||
|
||||
int32_t createResultBuf(SQueryResultBuf** pResultBuf, int32_t size, int32_t rowSize) {
|
||||
SQueryResultBuf* pResBuf = calloc(1, sizeof(SQueryResultBuf));
|
||||
int32_t createDiskbasedResultBuffer(SQueryDiskbasedResultBuf** pResultBuf, int32_t size, int32_t rowSize) {
|
||||
SQueryDiskbasedResultBuf* pResBuf = calloc(1, sizeof(SQueryDiskbasedResultBuf));
|
||||
pResBuf->numOfRowsPerPage = (DEFAULT_INTERN_BUF_SIZE - sizeof(tFilePage)) / rowSize;
|
||||
pResBuf->numOfPages = size;
|
||||
|
||||
|
@ -50,17 +50,17 @@ int32_t createResultBuf(SQueryResultBuf** pResultBuf, int32_t size, int32_t rowS
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tFilePage* getResultBufferPageById(SQueryResultBuf* pResultBuf, int32_t id) {
|
||||
tFilePage* getResultBufferPageById(SQueryDiskbasedResultBuf* pResultBuf, int32_t id) {
|
||||
assert(id < pResultBuf->numOfPages && id >= 0);
|
||||
|
||||
return (tFilePage*)(pResultBuf->pBuf + DEFAULT_INTERN_BUF_SIZE * id);
|
||||
}
|
||||
|
||||
int32_t getNumOfResultBufGroupId(SQueryResultBuf* pResultBuf) { return taosNumElemsInHashTable(pResultBuf->idsTable); }
|
||||
int32_t getNumOfResultBufGroupId(SQueryDiskbasedResultBuf* pResultBuf) { return taosNumElemsInHashTable(pResultBuf->idsTable); }
|
||||
|
||||
int32_t getResBufSize(SQueryResultBuf* pResultBuf) { return pResultBuf->totalBufSize; }
|
||||
int32_t getResBufSize(SQueryDiskbasedResultBuf* pResultBuf) { return pResultBuf->totalBufSize; }
|
||||
|
||||
static int32_t extendDiskFileSize(SQueryResultBuf* pResultBuf, int32_t numOfPages) {
|
||||
static int32_t extendDiskFileSize(SQueryDiskbasedResultBuf* pResultBuf, int32_t numOfPages) {
|
||||
assert(pResultBuf->numOfPages * DEFAULT_INTERN_BUF_SIZE == pResultBuf->totalBufSize);
|
||||
|
||||
int32_t ret = munmap(pResultBuf->pBuf, pResultBuf->totalBufSize);
|
||||
|
@ -88,11 +88,11 @@ static int32_t extendDiskFileSize(SQueryResultBuf* pResultBuf, int32_t numOfPage
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool noMoreAvailablePages(SQueryResultBuf* pResultBuf) {
|
||||
static bool noMoreAvailablePages(SQueryDiskbasedResultBuf* pResultBuf) {
|
||||
return (pResultBuf->allocateId == pResultBuf->numOfPages - 1);
|
||||
}
|
||||
|
||||
static int32_t getGroupIndex(SQueryResultBuf* pResultBuf, int32_t groupId) {
|
||||
static int32_t getGroupIndex(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId) {
|
||||
assert(pResultBuf != NULL);
|
||||
|
||||
char* p = taosGetDataFromHashTable(pResultBuf->idsTable, (const char*)&groupId, sizeof(int32_t));
|
||||
|
@ -106,7 +106,7 @@ static int32_t getGroupIndex(SQueryResultBuf* pResultBuf, int32_t groupId) {
|
|||
return slot;
|
||||
}
|
||||
|
||||
static int32_t addNewGroupId(SQueryResultBuf* pResultBuf, int32_t groupId) {
|
||||
static int32_t addNewGroupId(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId) {
|
||||
int32_t num = getNumOfResultBufGroupId(pResultBuf); // the num is the newest allocated group id slot
|
||||
|
||||
if (pResultBuf->numOfAllocGroupIds <= num) {
|
||||
|
@ -148,7 +148,7 @@ static int32_t doRegisterId(SIDList* pList, int32_t id) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void registerPageId(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t pageId) {
|
||||
static void registerPageId(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t pageId) {
|
||||
int32_t slot = getGroupIndex(pResultBuf, groupId);
|
||||
if (slot < 0) {
|
||||
slot = addNewGroupId(pResultBuf, groupId);
|
||||
|
@ -158,7 +158,7 @@ static void registerPageId(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t
|
|||
doRegisterId(pList, pageId);
|
||||
}
|
||||
|
||||
tFilePage* getNewDataBuf(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t* pageId) {
|
||||
tFilePage* getNewDataBuf(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId, int32_t* pageId) {
|
||||
if (noMoreAvailablePages(pResultBuf)) {
|
||||
if (extendDiskFileSize(pResultBuf, pResultBuf->incStep) != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
|
@ -177,9 +177,9 @@ tFilePage* getNewDataBuf(SQueryResultBuf* pResultBuf, int32_t groupId, int32_t*
|
|||
return page;
|
||||
}
|
||||
|
||||
int32_t getNumOfRowsPerPage(SQueryResultBuf* pResultBuf) { return pResultBuf->numOfRowsPerPage; }
|
||||
int32_t getNumOfRowsPerPage(SQueryDiskbasedResultBuf* pResultBuf) { return pResultBuf->numOfRowsPerPage; }
|
||||
|
||||
SIDList getDataBufPagesIdList(SQueryResultBuf* pResultBuf, int32_t groupId) {
|
||||
SIDList getDataBufPagesIdList(SQueryDiskbasedResultBuf* pResultBuf, int32_t groupId) {
|
||||
SIDList list = {0};
|
||||
int32_t slot = getGroupIndex(pResultBuf, groupId);
|
||||
if (slot < 0) {
|
||||
|
@ -189,7 +189,7 @@ SIDList getDataBufPagesIdList(SQueryResultBuf* pResultBuf, int32_t groupId) {
|
|||
}
|
||||
}
|
||||
|
||||
void destroyResultBuf(SQueryResultBuf* pResultBuf) {
|
||||
void destroyResultBuf(SQueryDiskbasedResultBuf* pResultBuf) {
|
||||
if (pResultBuf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue