[TD-2615]<fix>: fix limit offset query caused crash.
This commit is contained in:
parent
050e41b874
commit
5a7e631ca2
|
@ -15,19 +15,15 @@
|
|||
|
||||
#include "os.h"
|
||||
#include "qAst.h"
|
||||
#include "qExtbuffer.h"
|
||||
#include "qFill.h"
|
||||
#include "qHistogram.h"
|
||||
#include "qPercentile.h"
|
||||
#include "qSyntaxtreefunction.h"
|
||||
#include "qTsbuf.h"
|
||||
#include "taosdef.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tscLog.h"
|
||||
#include "tscSubquery.h"
|
||||
#include "tscompression.h"
|
||||
#include "tsqlfunction.h"
|
||||
#include "tutil.h"
|
||||
#include "ttype.h"
|
||||
|
||||
#define GET_INPUT_CHAR(x) (((char *)((x)->aInputElemBuf)) + ((x)->startOffset) * ((x)->inputBytes))
|
||||
|
@ -920,6 +916,10 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
|
|||
if (pCtx->preAggVals.isSet) {
|
||||
*notNullElems = pCtx->size - pCtx->preAggVals.statis.numOfNull;
|
||||
assert(*notNullElems >= 0);
|
||||
|
||||
if (*notNullElems == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
void * tval = NULL;
|
||||
int16_t index = 0;
|
||||
|
|
|
@ -4498,8 +4498,9 @@ static TSKEY doSkipIntervalProcess(SQueryRuntimeEnv* pRuntimeEnv, STimeWindow* w
|
|||
|
||||
return key;
|
||||
} else { // do nothing
|
||||
pQuery->window.skey = tw.skey;
|
||||
pQuery->window.skey = tw.skey;
|
||||
pWindowResInfo->prevSKey = tw.skey;
|
||||
pTableQueryInfo->lastKey = tw.skey;
|
||||
|
||||
return tw.skey;
|
||||
}
|
||||
|
@ -4509,22 +4510,6 @@ static TSKEY doSkipIntervalProcess(SQueryRuntimeEnv* pRuntimeEnv, STimeWindow* w
|
|||
|
||||
static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) {
|
||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||
|
||||
// get the first unclosed time window
|
||||
bool assign = false;
|
||||
for(int32_t i = 0; i < pRuntimeEnv->windowResInfo.size; ++i) {
|
||||
if (pRuntimeEnv->windowResInfo.pResult[i]->closed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assign = true;
|
||||
*start = pRuntimeEnv->windowResInfo.pResult[i]->win.skey;
|
||||
}
|
||||
|
||||
if (!assign) {
|
||||
*start = pQuery->current->lastKey;
|
||||
}
|
||||
|
||||
assert(*start <= pQuery->current->lastKey);
|
||||
|
||||
// if queried with value filter, do NOT forward query start position
|
||||
|
@ -4540,6 +4525,7 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) {
|
|||
assert(pRuntimeEnv->windowResInfo.prevSKey == TSKEY_INITIAL_VAL);
|
||||
|
||||
STimeWindow w = TSWINDOW_INITIALIZER;
|
||||
bool ascQuery = QUERY_IS_ASC_QUERY(pQuery);
|
||||
|
||||
SResultRowInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo;
|
||||
STableQueryInfo *pTableQueryInfo = pQuery->current;
|
||||
|
@ -4564,19 +4550,25 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) {
|
|||
while (pQuery->limit.offset > 0) {
|
||||
STimeWindow tw = win;
|
||||
|
||||
if ((win.ekey <= blockInfo.window.ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(win.ekey >= blockInfo.window.skey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||
if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) {
|
||||
pQuery->limit.offset -= 1;
|
||||
pWindowResInfo->prevSKey = win.skey;
|
||||
|
||||
// current time window is aligned with blockInfo.window.ekey
|
||||
// restart it from next data block by set prevSKey to be TSKEY_INITIAL_VAL;
|
||||
if ((win.ekey == blockInfo.window.ekey && ascQuery) || (win.ekey == blockInfo.window.skey && !ascQuery)) {
|
||||
pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL;
|
||||
}
|
||||
}
|
||||
|
||||
// current window does not ended in current data block, try next data block
|
||||
getNextTimeWindow(pQuery, &tw);
|
||||
if (pQuery->limit.offset == 0) {
|
||||
*start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
// current window does not ended in current data block, try next data block
|
||||
getNextTimeWindow(pQuery, &tw);
|
||||
|
||||
/*
|
||||
* If the next time window still starts from current data block,
|
||||
* load the primary timestamp column first, and then find the start position for the next queried time window.
|
||||
|
@ -4584,13 +4576,12 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) {
|
|||
* TODO: Optimize for this cases. All data blocks are not needed to be loaded, only if the first actually required
|
||||
* time window resides in current data block.
|
||||
*/
|
||||
if ((tw.skey <= blockInfo.window.ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(tw.ekey >= blockInfo.window.skey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||
SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pQueryHandle, NULL);
|
||||
if ((tw.skey <= blockInfo.window.ekey && ascQuery) || (tw.ekey >= blockInfo.window.skey && !ascQuery)) {
|
||||
|
||||
SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pQueryHandle, NULL);
|
||||
SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
|
||||
|
||||
if ((win.ekey > blockInfo.window.ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
||||
(win.ekey < blockInfo.window.skey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
||||
if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
|
||||
pQuery->limit.offset -= 1;
|
||||
}
|
||||
|
||||
|
@ -5767,7 +5758,7 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
|
|||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||
pQuery->current = pTableInfo;
|
||||
|
||||
TSKEY newStartKey = TSKEY_INITIAL_VAL;
|
||||
TSKEY newStartKey = QUERY_IS_ASC_QUERY(pQuery)? INT64_MIN:INT64_MAX;
|
||||
|
||||
// skip blocks without load the actual data block from file if no filter condition present
|
||||
if (!pRuntimeEnv->groupbyNormalCol) {
|
||||
|
|
|
@ -244,3 +244,70 @@ if $data00 != -2.000000000 then
|
|||
print expect -2.000000000, actual: $data00
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql create table tm1 (ts timestamp, k int);
|
||||
sql insert into tm1 values('2020-10-30 18:11:56.680', -1000);
|
||||
sql insert into tm1 values('2020-11-19 18:11:45.773', NULL);
|
||||
sql insert into tm1 values('2020-12-09 18:11:17.098', NULL);
|
||||
sql insert into tm1 values('2020-12-20 18:11:49.412', 1);
|
||||
sql insert into tm1 values('2020-12-23 18:11:50.412', 2);
|
||||
sql insert into tm1 values('2020-12-28 18:11:52.412', 3);
|
||||
|
||||
print =====================> td-2610
|
||||
sql select twa(k)from tm1 where ts>='2020-11-19 18:11:45.773' and ts<='2020-12-9 18:11:17.098'
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
print =====================> td-2609
|
||||
sql select apercentile(k, 50) from tm1 where ts>='2020-10-30 18:11:56.680' and ts<='2020-12-09 18:11:17.098'
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != -1000.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
sleep 1000
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
print ================== server restart completed
|
||||
sql connect
|
||||
sleep 500
|
||||
|
||||
sql use m_func_db0
|
||||
|
||||
print =====================> td-2583
|
||||
sql select min(k) from tm1 where ts>='2020-11-19 18:11:45.773' and ts<='2020-12-20 18:11:49.412'
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 1 then
|
||||
print expect 1, actual: $data00
|
||||
return -1
|
||||
endi
|
||||
|
||||
print =====================> td-2601
|
||||
sql select count(*) from tm1 where ts<='2020-6-1 00:00:00' and ts>='2020-1-1 00:00:00' interval(1n) fill(NULL)
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
print =====================> td-2615
|
||||
sql select last(ts) from tm1 interval(17a) limit 776 offset 3
|
||||
if $rows != 3 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select last(ts) from tm1 interval(17a) limit 1000 offset 4
|
||||
if $rows != 2 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select last(ts) from tm1 interval(17a) order by ts desc limit 1000 offset 0
|
||||
if $rows != 6 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
Loading…
Reference in New Issue