[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 "os.h"
|
||||||
#include "qAst.h"
|
#include "qAst.h"
|
||||||
#include "qExtbuffer.h"
|
|
||||||
#include "qFill.h"
|
#include "qFill.h"
|
||||||
#include "qHistogram.h"
|
#include "qHistogram.h"
|
||||||
#include "qPercentile.h"
|
#include "qPercentile.h"
|
||||||
#include "qSyntaxtreefunction.h"
|
|
||||||
#include "qTsbuf.h"
|
#include "qTsbuf.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
#include "tscompression.h"
|
|
||||||
#include "tsqlfunction.h"
|
#include "tsqlfunction.h"
|
||||||
#include "tutil.h"
|
|
||||||
#include "ttype.h"
|
#include "ttype.h"
|
||||||
|
|
||||||
#define GET_INPUT_CHAR(x) (((char *)((x)->aInputElemBuf)) + ((x)->startOffset) * ((x)->inputBytes))
|
#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) {
|
if (pCtx->preAggVals.isSet) {
|
||||||
*notNullElems = pCtx->size - pCtx->preAggVals.statis.numOfNull;
|
*notNullElems = pCtx->size - pCtx->preAggVals.statis.numOfNull;
|
||||||
assert(*notNullElems >= 0);
|
assert(*notNullElems >= 0);
|
||||||
|
|
||||||
|
if (*notNullElems == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void * tval = NULL;
|
void * tval = NULL;
|
||||||
int16_t index = 0;
|
int16_t index = 0;
|
||||||
|
|
|
@ -4498,8 +4498,9 @@ static TSKEY doSkipIntervalProcess(SQueryRuntimeEnv* pRuntimeEnv, STimeWindow* w
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
} else { // do nothing
|
} else { // do nothing
|
||||||
pQuery->window.skey = tw.skey;
|
pQuery->window.skey = tw.skey;
|
||||||
pWindowResInfo->prevSKey = tw.skey;
|
pWindowResInfo->prevSKey = tw.skey;
|
||||||
|
pTableQueryInfo->lastKey = tw.skey;
|
||||||
|
|
||||||
return tw.skey;
|
return tw.skey;
|
||||||
}
|
}
|
||||||
|
@ -4509,22 +4510,6 @@ static TSKEY doSkipIntervalProcess(SQueryRuntimeEnv* pRuntimeEnv, STimeWindow* w
|
||||||
|
|
||||||
static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) {
|
static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) {
|
||||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
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);
|
assert(*start <= pQuery->current->lastKey);
|
||||||
|
|
||||||
// if queried with value filter, do NOT forward query start position
|
// 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);
|
assert(pRuntimeEnv->windowResInfo.prevSKey == TSKEY_INITIAL_VAL);
|
||||||
|
|
||||||
STimeWindow w = TSWINDOW_INITIALIZER;
|
STimeWindow w = TSWINDOW_INITIALIZER;
|
||||||
|
bool ascQuery = QUERY_IS_ASC_QUERY(pQuery);
|
||||||
|
|
||||||
SResultRowInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo;
|
SResultRowInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo;
|
||||||
STableQueryInfo *pTableQueryInfo = pQuery->current;
|
STableQueryInfo *pTableQueryInfo = pQuery->current;
|
||||||
|
@ -4564,19 +4550,25 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) {
|
||||||
while (pQuery->limit.offset > 0) {
|
while (pQuery->limit.offset > 0) {
|
||||||
STimeWindow tw = win;
|
STimeWindow tw = win;
|
||||||
|
|
||||||
if ((win.ekey <= blockInfo.window.ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) {
|
||||||
(win.ekey >= blockInfo.window.skey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
|
||||||
pQuery->limit.offset -= 1;
|
pQuery->limit.offset -= 1;
|
||||||
pWindowResInfo->prevSKey = win.skey;
|
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) {
|
if (pQuery->limit.offset == 0) {
|
||||||
*start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
|
*start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo);
|
||||||
return true;
|
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,
|
* 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.
|
* 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
|
* 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.
|
* time window resides in current data block.
|
||||||
*/
|
*/
|
||||||
if ((tw.skey <= blockInfo.window.ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
if ((tw.skey <= blockInfo.window.ekey && ascQuery) || (tw.ekey >= blockInfo.window.skey && !ascQuery)) {
|
||||||
(tw.ekey >= blockInfo.window.skey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
|
||||||
SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pQueryHandle, NULL);
|
SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pQueryHandle, NULL);
|
||||||
SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
|
SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
|
||||||
|
|
||||||
if ((win.ekey > blockInfo.window.ekey && QUERY_IS_ASC_QUERY(pQuery)) ||
|
if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
|
||||||
(win.ekey < blockInfo.window.skey && !QUERY_IS_ASC_QUERY(pQuery))) {
|
|
||||||
pQuery->limit.offset -= 1;
|
pQuery->limit.offset -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5767,7 +5758,7 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
|
||||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||||
pQuery->current = pTableInfo;
|
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
|
// skip blocks without load the actual data block from file if no filter condition present
|
||||||
if (!pRuntimeEnv->groupbyNormalCol) {
|
if (!pRuntimeEnv->groupbyNormalCol) {
|
||||||
|
|
|
@ -244,3 +244,70 @@ if $data00 != -2.000000000 then
|
||||||
print expect -2.000000000, actual: $data00
|
print expect -2.000000000, actual: $data00
|
||||||
return -1
|
return -1
|
||||||
endi
|
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