fix interp bug
This commit is contained in:
parent
abe4052ccb
commit
ca985ec7c6
|
@ -183,6 +183,7 @@ typedef struct SQuery {
|
||||||
|
|
||||||
bool stableQuery; // super table query or not
|
bool stableQuery; // super table query or not
|
||||||
bool topBotQuery; // TODO used bitwise flag
|
bool topBotQuery; // TODO used bitwise flag
|
||||||
|
bool interpQuery; // denote if this is an interp query
|
||||||
bool groupbyColumn; // denote if this is a groupby normal column query
|
bool groupbyColumn; // denote if this is a groupby normal column query
|
||||||
bool hasTagResults; // if there are tag values in final result or not
|
bool hasTagResults; // if there are tag values in final result or not
|
||||||
bool timeWindowInterpo;// if the time window start/end required interpolation
|
bool timeWindowInterpo;// if the time window start/end required interpolation
|
||||||
|
@ -288,6 +289,8 @@ enum OPERATOR_TYPE_E {
|
||||||
OP_MultiTableAggregate = 14,
|
OP_MultiTableAggregate = 14,
|
||||||
OP_MultiTableTimeInterval = 15,
|
OP_MultiTableTimeInterval = 15,
|
||||||
OP_Having = 16,
|
OP_Having = 16,
|
||||||
|
OP_AllTimeWindow = 17,
|
||||||
|
OP_AllMultiTableTimeInterval = 18,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct SOperatorInfo {
|
typedef struct SOperatorInfo {
|
||||||
|
|
|
@ -4278,27 +4278,59 @@ static void interp_function_impl(SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no data generated yet
|
// no data generated yet
|
||||||
if (pCtx->size == 1) {
|
if (pCtx->size < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the timestamp in input buffer
|
// check the timestamp in input buffer
|
||||||
TSKEY skey = GET_TS_DATA(pCtx, 0);
|
TSKEY skey = GET_TS_DATA(pCtx, 0);
|
||||||
TSKEY ekey = GET_TS_DATA(pCtx, 1);
|
|
||||||
|
|
||||||
// no data generated yet
|
|
||||||
if (!(skey < pCtx->startTs && ekey > pCtx->startTs)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(pCtx->start.key == INT64_MIN && skey < pCtx->startTs && ekey > pCtx->startTs);
|
|
||||||
|
|
||||||
if (type == TSDB_FILL_PREV) {
|
if (type == TSDB_FILL_PREV) {
|
||||||
|
if (skey > pCtx->startTs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCtx->size > 1) {
|
||||||
|
TSKEY ekey = GET_TS_DATA(pCtx, 1);
|
||||||
|
if (ekey > skey && ekey <= pCtx->startTs) {
|
||||||
|
skey = ekey;
|
||||||
|
}
|
||||||
|
}
|
||||||
assignVal(pCtx->pOutput, pCtx->pInput, pCtx->outputBytes, pCtx->inputType);
|
assignVal(pCtx->pOutput, pCtx->pInput, pCtx->outputBytes, pCtx->inputType);
|
||||||
} else if (type == TSDB_FILL_NEXT) {
|
} else if (type == TSDB_FILL_NEXT) {
|
||||||
char* val = ((char*)pCtx->pInput) + pCtx->inputBytes;
|
TSKEY ekey = skey;
|
||||||
|
char* val = NULL;
|
||||||
|
|
||||||
|
if (ekey < pCtx->startTs) {
|
||||||
|
if (pCtx->size > 1) {
|
||||||
|
ekey = GET_TS_DATA(pCtx, 1);
|
||||||
|
if (ekey < pCtx->startTs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = ((char*)pCtx->pInput) + pCtx->inputBytes;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val = (char*)pCtx->pInput;
|
||||||
|
}
|
||||||
|
|
||||||
assignVal(pCtx->pOutput, val, pCtx->outputBytes, pCtx->inputType);
|
assignVal(pCtx->pOutput, val, pCtx->outputBytes, pCtx->inputType);
|
||||||
} else if (type == TSDB_FILL_LINEAR) {
|
} else if (type == TSDB_FILL_LINEAR) {
|
||||||
|
if (pCtx->size <= 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSKEY ekey = GET_TS_DATA(pCtx, 1);
|
||||||
|
|
||||||
|
// no data generated yet
|
||||||
|
if (!(skey < pCtx->startTs && ekey > pCtx->startTs)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(pCtx->start.key == INT64_MIN && skey < pCtx->startTs && ekey > pCtx->startTs);
|
||||||
|
|
||||||
char *start = GET_INPUT_DATA(pCtx, 0);
|
char *start = GET_INPUT_DATA(pCtx, 0);
|
||||||
char *end = GET_INPUT_DATA(pCtx, 1);
|
char *end = GET_INPUT_DATA(pCtx, 1);
|
||||||
|
|
||||||
|
|
|
@ -200,11 +200,13 @@ static SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp
|
||||||
static SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream);
|
static SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream);
|
||||||
static SOperatorInfo* createOffsetOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream);
|
static SOperatorInfo* createOffsetOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream);
|
||||||
static SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
static SOperatorInfo* createAllTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
static SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
static SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
static SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
static SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
static SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
static SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
static SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
static SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
static SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||||
static SOperatorInfo* createHavingOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
static SOperatorInfo* createHavingOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
@ -448,6 +450,37 @@ static void prepareResultListBuffer(SResultRowInfo* pResultRowInfo, SQueryRuntim
|
||||||
pResultRowInfo->capacity = (int32_t)newCapacity;
|
pResultRowInfo->capacity = (int32_t)newCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool chkResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, char *pData,
|
||||||
|
int16_t bytes, bool masterscan, uint64_t uid) {
|
||||||
|
bool existed = false;
|
||||||
|
SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid);
|
||||||
|
|
||||||
|
SResultRow **p1 =
|
||||||
|
(SResultRow **)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
|
||||||
|
|
||||||
|
// in case of repeat scan/reverse scan, no new time window added.
|
||||||
|
if (QUERY_IS_INTERVAL_QUERY(pRuntimeEnv->pQuery)) {
|
||||||
|
if (!masterscan) { // the *p1 may be NULL in case of sliding+offset exists.
|
||||||
|
return p1 != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p1 != NULL) {
|
||||||
|
for(int32_t i = pResultRowInfo->size - 1; i >= 0; --i) {
|
||||||
|
if (pResultRowInfo->pResult[i] == (*p1)) {
|
||||||
|
pResultRowInfo->curIndex = i;
|
||||||
|
existed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return existed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p1 != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static SResultRow *doPrepareResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, char *pData,
|
static SResultRow *doPrepareResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, char *pData,
|
||||||
int16_t bytes, bool masterscan, uint64_t uid) {
|
int16_t bytes, bool masterscan, uint64_t uid) {
|
||||||
bool existed = false;
|
bool existed = false;
|
||||||
|
@ -586,6 +619,42 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the correct time window according to the handled timestamp
|
||||||
|
static STimeWindow getCurrentActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t ts, SQuery *pQuery) {
|
||||||
|
STimeWindow w = {0};
|
||||||
|
|
||||||
|
if (pResultRowInfo->curIndex == -1) { // the first window, from the previous stored value
|
||||||
|
if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) {
|
||||||
|
getInitialStartTimeWindow(pQuery, ts, &w);
|
||||||
|
pResultRowInfo->prevSKey = w.skey;
|
||||||
|
} else {
|
||||||
|
w.skey = pResultRowInfo->prevSKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') {
|
||||||
|
w.ekey = taosTimeAdd(w.skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1;
|
||||||
|
} else {
|
||||||
|
w.ekey = w.skey + pQuery->interval.interval - 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int32_t slot = curTimeWindowIndex(pResultRowInfo);
|
||||||
|
SResultRow* pWindowRes = getResultRow(pResultRowInfo, slot);
|
||||||
|
w = pWindowRes->win;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* query border check, skey should not be bounded by the query time range, since the value skey will
|
||||||
|
* be used as the time window index value. So we only change ekey of time window accordingly.
|
||||||
|
*/
|
||||||
|
if (w.ekey > pQuery->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) {
|
||||||
|
w.ekey = pQuery->window.ekey;
|
||||||
|
}
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// a new buffer page for each table. Needs to opt this design
|
// a new buffer page for each table. Needs to opt this design
|
||||||
static int32_t addNewWindowResultBuf(SResultRow *pWindowRes, SDiskbasedResultBuf *pResultBuf, int32_t tid, uint32_t size) {
|
static int32_t addNewWindowResultBuf(SResultRow *pWindowRes, SDiskbasedResultBuf *pResultBuf, int32_t tid, uint32_t size) {
|
||||||
if (pWindowRes->pageId != -1) {
|
if (pWindowRes->pageId != -1) {
|
||||||
|
@ -631,6 +700,17 @@ static int32_t addNewWindowResultBuf(SResultRow *pWindowRes, SDiskbasedResultBuf
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool chkWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, STimeWindow *win,
|
||||||
|
bool masterscan, SResultRow **pResult, int64_t groupId, SQLFunctionCtx* pCtx,
|
||||||
|
int32_t numOfOutput, int32_t* rowCellInfoOffset) {
|
||||||
|
assert(win->skey <= win->ekey);
|
||||||
|
|
||||||
|
return chkResultRowFromKey(pRuntimeEnv, pResultRowInfo, (char *)&win->skey, TSDB_KEYSIZE, masterscan, groupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, STimeWindow *win,
|
static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, STimeWindow *win,
|
||||||
bool masterscan, SResultRow **pResult, int64_t groupId, SQLFunctionCtx* pCtx,
|
bool masterscan, SResultRow **pResult, int64_t groupId, SQLFunctionCtx* pCtx,
|
||||||
int32_t numOfOutput, int32_t* rowCellInfoOffset) {
|
int32_t numOfOutput, int32_t* rowCellInfoOffset) {
|
||||||
|
@ -701,7 +781,7 @@ static FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_se
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(forwardStep > 0);
|
assert(forwardStep >= 0);
|
||||||
return forwardStep;
|
return forwardStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,9 +831,9 @@ static void doUpdateResultRowIndex(SResultRowInfo*pResultRowInfo, TSKEY lastKey,
|
||||||
} else {
|
} else {
|
||||||
pResultRowInfo->curIndex = i + 1; // current not closed result object
|
pResultRowInfo->curIndex = i + 1; // current not closed result object
|
||||||
}
|
}
|
||||||
|
|
||||||
pResultRowInfo->prevSKey = pResultRowInfo->pResult[pResultRowInfo->curIndex]->win.skey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pResultRowInfo->prevSKey = pResultRowInfo->pResult[pResultRowInfo->curIndex]->win.skey;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, SQuery* pQuery, TSKEY lastKey) {
|
static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, SQuery* pQuery, TSKEY lastKey) {
|
||||||
|
@ -803,7 +883,7 @@ static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SDataBlockInfo *pDataBlo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(num > 0);
|
assert(num >= 0);
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,6 +965,11 @@ static int32_t getNextQualifiedWindow(SQuery* pQuery, STimeWindow *pNext, SDataB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* interp query with fill should not skip time window */
|
||||||
|
if (pQuery->interpQuery && pQuery->fillType != TSDB_FILL_NONE) {
|
||||||
|
return startPos;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This time window does not cover any data, try next time window,
|
* This time window does not cover any data, try next time window,
|
||||||
* this case may happen when the time window is too small
|
* this case may happen when the time window is too small
|
||||||
|
@ -1351,6 +1436,81 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul
|
||||||
updateResultRowInfoActiveIndex(pResultRowInfo, pQuery, pQuery->current->lastKey);
|
updateResultRowInfoActiveIndex(pResultRowInfo, pQuery, pQuery->current->lastKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hashAllIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResultRowInfo, SSDataBlock* pSDataBlock, int32_t groupId) {
|
||||||
|
STableIntervalOperatorInfo* pInfo = (STableIntervalOperatorInfo*) pOperatorInfo->info;
|
||||||
|
|
||||||
|
SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv;
|
||||||
|
int32_t numOfOutput = pOperatorInfo->numOfOutput;
|
||||||
|
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||||
|
|
||||||
|
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order);
|
||||||
|
bool ascQuery = QUERY_IS_ASC_QUERY(pQuery);
|
||||||
|
|
||||||
|
TSKEY* tsCols = NULL;
|
||||||
|
if (pSDataBlock->pDataBlock != NULL) {
|
||||||
|
SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, 0);
|
||||||
|
tsCols = (int64_t*) pColDataInfo->pData;
|
||||||
|
assert(tsCols[0] == pSDataBlock->info.window.skey &&
|
||||||
|
tsCols[pSDataBlock->info.rows - 1] == pSDataBlock->info.window.ekey);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t startPos = ascQuery? 0 : (pSDataBlock->info.rows - 1);
|
||||||
|
TSKEY ts = getStartTsKey(pQuery, &pSDataBlock->info.window, tsCols, pSDataBlock->info.rows);
|
||||||
|
|
||||||
|
STimeWindow win = getCurrentActiveTimeWindow(pResultRowInfo, ts, pQuery);
|
||||||
|
bool masterScan = IS_MASTER_SCAN(pRuntimeEnv);
|
||||||
|
|
||||||
|
SResultRow* pResult = NULL;
|
||||||
|
int32_t forwardStep = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// null data, failed to allocate more memory buffer
|
||||||
|
int32_t code = setWindowOutputBufByKey(pRuntimeEnv, pResultRowInfo, &win, masterScan, &pResult, groupId,
|
||||||
|
pInfo->pCtx, numOfOutput, pInfo->rowCellInfoOffset);
|
||||||
|
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||||
|
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
TSKEY ekey = reviseWindowEkey(pQuery, &win);
|
||||||
|
forwardStep = getNumOfRowsInTimeWindow(pQuery, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true);
|
||||||
|
|
||||||
|
// window start(end) key interpolation
|
||||||
|
doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->pCtx, pResult, &win, startPos, forwardStep);
|
||||||
|
doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &win, startPos, forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput);
|
||||||
|
|
||||||
|
int32_t prevEndPos = (forwardStep - 1) * step + startPos;
|
||||||
|
startPos = getNextQualifiedWindow(pQuery, &win, &pSDataBlock->info, tsCols, binarySearchForKey, prevEndPos);
|
||||||
|
if (startPos < 0) {
|
||||||
|
if (win.skey <= pQuery->window.ekey) {
|
||||||
|
int32_t code = setWindowOutputBufByKey(pRuntimeEnv, pResultRowInfo, &win, masterScan, &pResult, groupId,
|
||||||
|
pInfo->pCtx, numOfOutput, pInfo->rowCellInfoOffset);
|
||||||
|
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||||
|
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
startPos = pSDataBlock->info.rows - 1;
|
||||||
|
|
||||||
|
// window start(end) key interpolation
|
||||||
|
doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->pCtx, pResult, &win, startPos, forwardStep);
|
||||||
|
doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &win, startPos, forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pQuery->timeWindowInterpo) {
|
||||||
|
int32_t rowIndex = ascQuery? (pSDataBlock->info.rows-1):0;
|
||||||
|
saveDataBlockLastRow(pRuntimeEnv, &pSDataBlock->info, pSDataBlock->pDataBlock, rowIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateResultRowInfoActiveIndex(pResultRowInfo, pQuery, pQuery->current->lastKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pInfo, SSDataBlock *pSDataBlock) {
|
static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pInfo, SSDataBlock *pSDataBlock) {
|
||||||
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||||
STableQueryInfo* item = pRuntimeEnv->pQuery->current;
|
STableQueryInfo* item = pRuntimeEnv->pQuery->current;
|
||||||
|
@ -1788,12 +1948,24 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
|
||||||
|
|
||||||
} else if (QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
} else if (QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
||||||
if (pQuery->stableQuery) {
|
if (pQuery->stableQuery) {
|
||||||
pRuntimeEnv->proot = createMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner,
|
if (pQuery->interpQuery) {
|
||||||
pQuery->pExpr1, pQuery->numOfOutput);
|
pRuntimeEnv->proot = createAllMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner,
|
||||||
|
pQuery->pExpr1, pQuery->numOfOutput);
|
||||||
|
} else {
|
||||||
|
pRuntimeEnv->proot = createMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner,
|
||||||
|
pQuery->pExpr1, pQuery->numOfOutput);
|
||||||
|
}
|
||||||
setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot);
|
setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot);
|
||||||
} else {
|
} else {
|
||||||
pRuntimeEnv->proot =
|
if (pQuery->interpQuery) {
|
||||||
createTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput);
|
pRuntimeEnv->proot =
|
||||||
|
createAllTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
pRuntimeEnv->proot =
|
||||||
|
createTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput);
|
||||||
|
}
|
||||||
|
|
||||||
setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot);
|
setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot);
|
||||||
|
|
||||||
if (pQuery->pExpr2 != NULL) {
|
if (pQuery->pExpr2 != NULL) {
|
||||||
|
@ -1801,12 +1973,11 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
|
||||||
createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2);
|
createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pQuery->fillType != TSDB_FILL_NONE && !isPointInterpoQuery(pQuery)) {
|
if (pQuery->fillType != TSDB_FILL_NONE) {
|
||||||
SOperatorInfo* pInfo = pRuntimeEnv->proot;
|
SOperatorInfo* pInfo = pRuntimeEnv->proot;
|
||||||
pRuntimeEnv->proot = createFillOperatorInfo(pRuntimeEnv, pInfo, pInfo->pExpr, pInfo->numOfOutput);
|
pRuntimeEnv->proot = createFillOperatorInfo(pRuntimeEnv, pInfo, pInfo->pExpr, pInfo->numOfOutput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (pQuery->groupbyColumn) {
|
} else if (pQuery->groupbyColumn) {
|
||||||
pRuntimeEnv->proot =
|
pRuntimeEnv->proot =
|
||||||
createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput);
|
createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput);
|
||||||
|
@ -2666,6 +2837,8 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa
|
||||||
|
|
||||||
// check if this data block is required to load
|
// check if this data block is required to load
|
||||||
if ((*status) != BLK_DATA_ALL_NEEDED) {
|
if ((*status) != BLK_DATA_ALL_NEEDED) {
|
||||||
|
bool needFilter = true;
|
||||||
|
|
||||||
// the pCtx[i] result is belonged to previous time window since the outputBuf has not been set yet,
|
// the pCtx[i] result is belonged to previous time window since the outputBuf has not been set yet,
|
||||||
// the filter result may be incorrect. So in case of interval query, we need to set the correct time output buffer
|
// the filter result may be incorrect. So in case of interval query, we need to set the correct time output buffer
|
||||||
if (QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
if (QUERY_IS_INTERVAL_QUERY(pQuery)) {
|
||||||
|
@ -2675,18 +2848,20 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa
|
||||||
TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey;
|
TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey;
|
||||||
|
|
||||||
STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQuery);
|
STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQuery);
|
||||||
if (setWindowOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, &win, masterScan, &pResult, groupId,
|
needFilter = chkWindowOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, &win, masterScan, &pResult, groupId,
|
||||||
pTableScanInfo->pCtx, pTableScanInfo->numOfOutput,
|
pTableScanInfo->pCtx, pTableScanInfo->numOfOutput,
|
||||||
pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) {
|
pTableScanInfo->rowCellInfoOffset);
|
||||||
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
|
||||||
}
|
|
||||||
} else if (pQuery->stableQuery && (!isTsCompQuery(pQuery))) { // stable aggregate, not interval aggregate or normal column aggregate
|
} else if (pQuery->stableQuery && (!isTsCompQuery(pQuery))) { // stable aggregate, not interval aggregate or normal column aggregate
|
||||||
doSetTableGroupOutputBuf(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx,
|
doSetTableGroupOutputBuf(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx,
|
||||||
pTableScanInfo->rowCellInfoOffset, pTableScanInfo->numOfOutput,
|
pTableScanInfo->rowCellInfoOffset, pTableScanInfo->numOfOutput,
|
||||||
pQuery->current->groupIndex);
|
pQuery->current->groupIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
(*status) = doFilterByBlockTimeWindow(pTableScanInfo, pBlock);
|
if (needFilter) {
|
||||||
|
(*status) = doFilterByBlockTimeWindow(pTableScanInfo, pBlock);
|
||||||
|
} else {
|
||||||
|
(*status) = BLK_DATA_ALL_NEEDED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDataBlockInfo* pBlockInfo = &pBlock->info;
|
SDataBlockInfo* pBlockInfo = &pBlock->info;
|
||||||
|
@ -4104,6 +4279,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
|
||||||
pQuery->tsdb = tsdb;
|
pQuery->tsdb = tsdb;
|
||||||
|
|
||||||
pQuery->topBotQuery = isTopBottomQuery(pQuery);
|
pQuery->topBotQuery = isTopBottomQuery(pQuery);
|
||||||
|
pQuery->interpQuery = isPointInterpoQuery(pQuery);
|
||||||
pQuery->hasTagResults = hasTagValOutput(pQuery);
|
pQuery->hasTagResults = hasTagValOutput(pQuery);
|
||||||
pQuery->timeWindowInterpo = timeWindowInterpoRequired(pQuery);
|
pQuery->timeWindowInterpo = timeWindowInterpoRequired(pQuery);
|
||||||
pQuery->stabledev = isStabledev(pQuery);
|
pQuery->stabledev = isStabledev(pQuery);
|
||||||
|
@ -4471,7 +4647,7 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf
|
||||||
pTableScanInfo->pCtx = pAggInfo->binfo.pCtx;
|
pTableScanInfo->pCtx = pAggInfo->binfo.pCtx;
|
||||||
pTableScanInfo->pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
|
pTableScanInfo->pResultRowInfo = &pAggInfo->binfo.resultRowInfo;
|
||||||
pTableScanInfo->rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
|
pTableScanInfo->rowCellInfoOffset = pAggInfo->binfo.rowCellInfoOffset;
|
||||||
} else if (pDownstream->operatorType == OP_TimeWindow) {
|
} else if (pDownstream->operatorType == OP_TimeWindow || pDownstream->operatorType == OP_AllTimeWindow) {
|
||||||
STableIntervalOperatorInfo *pIntervalInfo = pDownstream->info;
|
STableIntervalOperatorInfo *pIntervalInfo = pDownstream->info;
|
||||||
|
|
||||||
pTableScanInfo->pCtx = pIntervalInfo->pCtx;
|
pTableScanInfo->pCtx = pIntervalInfo->pCtx;
|
||||||
|
@ -4485,7 +4661,7 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf
|
||||||
pTableScanInfo->pResultRowInfo = &pGroupbyInfo->binfo.resultRowInfo;
|
pTableScanInfo->pResultRowInfo = &pGroupbyInfo->binfo.resultRowInfo;
|
||||||
pTableScanInfo->rowCellInfoOffset = pGroupbyInfo->binfo.rowCellInfoOffset;
|
pTableScanInfo->rowCellInfoOffset = pGroupbyInfo->binfo.rowCellInfoOffset;
|
||||||
|
|
||||||
} else if (pDownstream->operatorType == OP_MultiTableTimeInterval) {
|
} else if (pDownstream->operatorType == OP_MultiTableTimeInterval || pDownstream->operatorType == OP_AllMultiTableTimeInterval) {
|
||||||
STableIntervalOperatorInfo *pInfo = pDownstream->info;
|
STableIntervalOperatorInfo *pInfo = pDownstream->info;
|
||||||
|
|
||||||
pTableScanInfo->pCtx = pInfo->pCtx;
|
pTableScanInfo->pCtx = pInfo->pCtx;
|
||||||
|
@ -4911,6 +5087,64 @@ static SSDataBlock* doIntervalAgg(void* param) {
|
||||||
return pIntervalInfo->pRes->info.rows == 0? NULL:pIntervalInfo->pRes;
|
return pIntervalInfo->pRes->info.rows == 0? NULL:pIntervalInfo->pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SSDataBlock* doAllIntervalAgg(void* param) {
|
||||||
|
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STableIntervalOperatorInfo* pIntervalInfo = pOperator->info;
|
||||||
|
|
||||||
|
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||||
|
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||||
|
toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
|
||||||
|
|
||||||
|
if (pIntervalInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pIntervalInfo->pRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||||
|
int32_t order = pQuery->order.order;
|
||||||
|
STimeWindow win = pQuery->window;
|
||||||
|
|
||||||
|
SOperatorInfo* upstream = pOperator->upstream;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
SSDataBlock* pBlock = upstream->exec(upstream);
|
||||||
|
if (pBlock == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTagValue(pOperator, pRuntimeEnv->pQuery->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
|
||||||
|
|
||||||
|
// the pDataBlock are always the same one, no need to call this again
|
||||||
|
setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQuery->order.order);
|
||||||
|
hashAllIntervalAgg(pOperator, &pIntervalInfo->resultRowInfo, pBlock, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore the value
|
||||||
|
pQuery->order.order = order;
|
||||||
|
pQuery->window = win;
|
||||||
|
|
||||||
|
pOperator->status = OP_RES_TO_RETURN;
|
||||||
|
closeAllResultRows(&pIntervalInfo->resultRowInfo);
|
||||||
|
setQueryStatus(pRuntimeEnv, QUERY_COMPLETED);
|
||||||
|
finalizeQueryResult(pOperator, pIntervalInfo->pCtx, &pIntervalInfo->resultRowInfo, pIntervalInfo->rowCellInfoOffset);
|
||||||
|
|
||||||
|
initGroupResInfo(&pRuntimeEnv->groupResInfo, &pIntervalInfo->resultRowInfo);
|
||||||
|
toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
|
||||||
|
|
||||||
|
if (pIntervalInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pIntervalInfo->pRes->info.rows == 0? NULL:pIntervalInfo->pRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static SSDataBlock* doSTableIntervalAgg(void* param) {
|
static SSDataBlock* doSTableIntervalAgg(void* param) {
|
||||||
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||||
if (pOperator->status == OP_EXEC_DONE) {
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
@ -4963,6 +5197,60 @@ static SSDataBlock* doSTableIntervalAgg(void* param) {
|
||||||
return pIntervalInfo->pRes;
|
return pIntervalInfo->pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SSDataBlock* doAllSTableIntervalAgg(void* param) {
|
||||||
|
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STableIntervalOperatorInfo* pIntervalInfo = pOperator->info;
|
||||||
|
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||||
|
|
||||||
|
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||||
|
copyToSDataBlock(pRuntimeEnv, 3000, pIntervalInfo->pRes, pIntervalInfo->rowCellInfoOffset);
|
||||||
|
if (pIntervalInfo->pRes->info.rows == 0 || !hasRemainData(&pRuntimeEnv->groupResInfo)) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pIntervalInfo->pRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||||
|
int32_t order = pQuery->order.order;
|
||||||
|
|
||||||
|
SOperatorInfo* upstream = pOperator->upstream;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
SSDataBlock* pBlock = upstream->exec(upstream);
|
||||||
|
if (pBlock == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the pDataBlock are always the same one, no need to call this again
|
||||||
|
STableQueryInfo* pTableQueryInfo = pRuntimeEnv->pQuery->current;
|
||||||
|
|
||||||
|
setTagValue(pOperator, pTableQueryInfo->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
|
||||||
|
setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQuery->order.order);
|
||||||
|
setIntervalQueryRange(pRuntimeEnv, pBlock->info.window.skey);
|
||||||
|
|
||||||
|
hashAllIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pTableQueryInfo->groupIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
pOperator->status = OP_RES_TO_RETURN;
|
||||||
|
pQuery->order.order = order; // TODO : restore the order
|
||||||
|
doCloseAllTimeWindow(pRuntimeEnv);
|
||||||
|
setQueryStatus(pRuntimeEnv, QUERY_COMPLETED);
|
||||||
|
|
||||||
|
copyToSDataBlock(pRuntimeEnv, 3000, pIntervalInfo->pRes, pIntervalInfo->rowCellInfoOffset);
|
||||||
|
if (pIntervalInfo->pRes->info.rows == 0 || !hasRemainData(&pRuntimeEnv->groupResInfo)) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pIntervalInfo->pRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static SSDataBlock* doSessionWindowAgg(void* param) {
|
static SSDataBlock* doSessionWindowAgg(void* param) {
|
||||||
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||||
if (pOperator->status == OP_EXEC_DONE) {
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
@ -5406,6 +5694,32 @@ SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp
|
||||||
return pOperator;
|
return pOperator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createAllTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||||
|
STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo));
|
||||||
|
|
||||||
|
pInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset);
|
||||||
|
pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity);
|
||||||
|
initResultRowInfo(&pInfo->resultRowInfo, 8, TSDB_DATA_TYPE_INT);
|
||||||
|
|
||||||
|
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
|
||||||
|
|
||||||
|
pOperator->name = "AllTimeIntervalAggOperator";
|
||||||
|
pOperator->operatorType = OP_AllTimeWindow;
|
||||||
|
pOperator->blockingOptr = true;
|
||||||
|
pOperator->status = OP_IN_EXECUTING;
|
||||||
|
pOperator->upstream = upstream;
|
||||||
|
pOperator->pExpr = pExpr;
|
||||||
|
pOperator->numOfOutput = numOfOutput;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||||
|
pOperator->exec = doAllIntervalAgg;
|
||||||
|
pOperator->cleanup = destroyBasicOperatorInfo;
|
||||||
|
|
||||||
|
return pOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||||
SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo));
|
SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo));
|
||||||
|
|
||||||
|
@ -5455,6 +5769,31 @@ SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRunti
|
||||||
return pOperator;
|
return pOperator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||||
|
STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo));
|
||||||
|
|
||||||
|
pInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->rowCellInfoOffset);
|
||||||
|
pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity);
|
||||||
|
initResultRowInfo(&pInfo->resultRowInfo, 8, TSDB_DATA_TYPE_INT);
|
||||||
|
|
||||||
|
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
|
||||||
|
pOperator->name = "AllMultiTableTimeIntervalOperator";
|
||||||
|
pOperator->operatorType = OP_AllMultiTableTimeInterval;
|
||||||
|
pOperator->blockingOptr = true;
|
||||||
|
pOperator->status = OP_IN_EXECUTING;
|
||||||
|
pOperator->upstream = upstream;
|
||||||
|
pOperator->pExpr = pExpr;
|
||||||
|
pOperator->numOfOutput = numOfOutput;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||||
|
|
||||||
|
pOperator->exec = doAllSTableIntervalAgg;
|
||||||
|
pOperator->cleanup = destroyBasicOperatorInfo;
|
||||||
|
|
||||||
|
return pOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||||
SGroupbyOperatorInfo* pInfo = calloc(1, sizeof(SGroupbyOperatorInfo));
|
SGroupbyOperatorInfo* pInfo = calloc(1, sizeof(SGroupbyOperatorInfo));
|
||||||
pInfo->colIndex = -1; // group by column index
|
pInfo->colIndex = -1; // group by column index
|
||||||
|
|
|
@ -55,6 +55,9 @@ while $i < $halfNum
|
||||||
endw
|
endw
|
||||||
print ====== tables created
|
print ====== tables created
|
||||||
|
|
||||||
|
sql create table ap1 (ts timestamp, pav float);
|
||||||
|
sql INSERT INTO ap1 VALUES ('2021-07-25 02:19:54.100',1) ('2021-07-25 02:19:54.200',2) ('2021-07-25 02:19:54.300',3) ('2021-07-25 02:19:56.500',4) ('2021-07-25 02:19:57.500',5) ('2021-07-25 02:19:57.600',6) ('2021-07-25 02:19:57.900',7) ('2021-07-25 02:19:58.100',8) ('2021-07-25 02:19:58.300',9) ('2021-07-25 02:19:59.100',10) ('2021-07-25 02:19:59.300',11) ('2021-07-25 02:19:59.500',12) ('2021-07-25 02:19:59.700',13) ('2021-07-25 02:19:59.900',14) ('2021-07-25 02:20:05.000', 20) ('2021-07-25 02:25:00.000', 10000);
|
||||||
|
|
||||||
run general/parser/interp_test.sim
|
run general/parser/interp_test.sim
|
||||||
|
|
||||||
print ================== restart server to commit data into disk
|
print ================== restart server to commit data into disk
|
||||||
|
@ -65,4 +68,4 @@ print ================== server restart completed
|
||||||
|
|
||||||
run general/parser/interp_test.sim
|
run general/parser/interp_test.sim
|
||||||
|
|
||||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
#system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue