Merge pull request #21378 from taosdata/fix/nodisk
fix(query): do some internal refactor, and fix the bug when calender duration exists in sliding and offset.
This commit is contained in:
commit
200c1a367b
|
@ -23,7 +23,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TIME_IS_VAR_DURATION(_t) ((_t) == 'n' || (_t) == 'y' || (_t) == 'N' || (_t) == 'Y')
|
||||
#define IS_CALENDAR_TIME_DURATION(_t) ((_t) == 'n' || (_t) == 'y' || (_t) == 'N' || (_t) == 'Y')
|
||||
|
||||
#define TIME_UNIT_NANOSECOND 'b'
|
||||
#define TIME_UNIT_MICROSECOND 'u'
|
||||
|
@ -74,7 +74,7 @@ static FORCE_INLINE int64_t taosGetTimestampToday(int32_t precision) {
|
|||
|
||||
int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision);
|
||||
|
||||
int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision);
|
||||
int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval);
|
||||
int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision);
|
||||
|
||||
int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* ts, char* unit, int32_t timePrecision);
|
||||
|
|
|
@ -186,7 +186,17 @@ int32_t qSerializeTaskStatus(qTaskInfo_t tinfo, char** pOutput, int32_t* len);
|
|||
|
||||
int32_t qDeserializeTaskStatus(qTaskInfo_t tinfo, const char* pInput, int32_t len);
|
||||
|
||||
STimeWindow getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key);
|
||||
void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order);
|
||||
void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery);
|
||||
STimeWindow getAlignQueryTimeWindow(const SInterval* pInterval, int64_t key);
|
||||
/**
|
||||
* return the scan info, in the form of tuple of two items, including table uid and current timestamp
|
||||
* @param tinfo
|
||||
* @param uid
|
||||
* @param ts
|
||||
* @return
|
||||
*/
|
||||
int32_t qGetStreamScanStatus(qTaskInfo_t tinfo, uint64_t* uid, int64_t* ts);
|
||||
|
||||
SArray* qGetQueriedTableListInfo(qTaskInfo_t tinfo);
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ static int32_t parseLocaltime(char* timestr, int32_t len, int64_t* utime, int32_
|
|||
static int32_t parseLocaltimeDst(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim);
|
||||
static char* forwardToTimeStringEnd(char* str);
|
||||
static bool checkTzPresent(const char* str, int32_t len);
|
||||
static int32_t parseTimezone(char* str, int64_t* tzOffset);
|
||||
|
||||
static int32_t (*parseLocaltimeFp[])(char* timestr, int32_t len, int64_t* utime, int32_t timePrec, char delim) = {
|
||||
parseLocaltime, parseLocaltimeDst};
|
||||
|
@ -713,16 +714,12 @@ int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision) {
|
|||
return t;
|
||||
}
|
||||
|
||||
if (unit != 'n' && unit != 'y') {
|
||||
if (!IS_CALENDAR_TIME_DURATION(unit)) {
|
||||
return t + duration;
|
||||
}
|
||||
|
||||
// The following code handles the y/n time duration
|
||||
int64_t numOfMonth = duration;
|
||||
if (unit == 'y') {
|
||||
numOfMonth *= 12;
|
||||
}
|
||||
|
||||
int64_t numOfMonth = (unit == 'y')? duration*12:duration;
|
||||
int64_t fraction = t % TSDB_TICK_PER_SECOND(precision);
|
||||
|
||||
struct tm tm;
|
||||
|
@ -764,13 +761,16 @@ int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char
|
|||
return (emon - smon) / (int32_t)interval;
|
||||
}
|
||||
|
||||
int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision) {
|
||||
int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval) {
|
||||
if (pInterval->sliding == 0 && pInterval->interval == 0) {
|
||||
return t;
|
||||
return ts;
|
||||
}
|
||||
|
||||
int64_t start = t;
|
||||
if (pInterval->slidingUnit == 'n' || pInterval->slidingUnit == 'y') {
|
||||
int64_t start = ts;
|
||||
int32_t precision = pInterval->precision;
|
||||
|
||||
if (IS_CALENDAR_TIME_DURATION(pInterval->slidingUnit)) {
|
||||
|
||||
start /= (int64_t)(TSDB_TICK_PER_SECOND(precision));
|
||||
struct tm tm;
|
||||
time_t tt = (time_t)start;
|
||||
|
@ -792,7 +792,33 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio
|
|||
|
||||
start = (int64_t)(taosMktime(&tm) * TSDB_TICK_PER_SECOND(precision));
|
||||
} else {
|
||||
int64_t delta = t - pInterval->interval;
|
||||
if (IS_CALENDAR_TIME_DURATION(pInterval->intervalUnit)) {
|
||||
int64_t news = (ts / pInterval->sliding) * pInterval->sliding;
|
||||
ASSERT(news <= ts);
|
||||
|
||||
if (news <= ts) {
|
||||
int64_t prev = news;
|
||||
int64_t newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
|
||||
if (newe < ts) { // move towards the greater endpoint
|
||||
while(newe < ts && news < ts) {
|
||||
news += pInterval->sliding;
|
||||
newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
}
|
||||
|
||||
prev = news;
|
||||
} else {
|
||||
while (newe >= ts) {
|
||||
prev = news;
|
||||
news -= pInterval->sliding;
|
||||
newe = taosTimeAdd(news, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
} else {
|
||||
int64_t delta = ts - pInterval->interval;
|
||||
int32_t factor = (delta >= 0) ? 1 : -1;
|
||||
|
||||
start = (delta / pInterval->sliding + factor) * pInterval->sliding;
|
||||
|
@ -804,7 +830,8 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio
|
|||
*/
|
||||
// todo refactor to extract function that is available for Linux/Windows/Mac platform
|
||||
#if defined(WINDOWS) && _MSC_VER >= 1900
|
||||
// see https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019
|
||||
// see
|
||||
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019
|
||||
int64_t timezone = _timezone;
|
||||
int32_t daylight = _daylight;
|
||||
char** tzname = _tzname;
|
||||
|
@ -818,7 +845,7 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio
|
|||
// not enough time range
|
||||
if (start < 0 || INT64_MAX - start > pInterval->interval - 1) {
|
||||
end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
while (end < t) { // move forward to the correct time window
|
||||
while (end < ts) { // move forward to the correct time window
|
||||
start += pInterval->sliding;
|
||||
|
||||
if (start < 0 || INT64_MAX - start > pInterval->interval - 1) {
|
||||
|
@ -832,6 +859,7 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio
|
|||
end = INT64_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(pInterval->offset >= 0);
|
||||
|
||||
|
@ -841,10 +869,10 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio
|
|||
// try to move current window to the left-hande-side, due to the offset effect.
|
||||
int64_t end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
|
||||
int64_t newEnd = end;
|
||||
while (newEnd >= t) {
|
||||
end = newEnd;
|
||||
newEnd = taosTimeAdd(newEnd, -pInterval->sliding, pInterval->slidingUnit, precision);
|
||||
int64_t newe = end;
|
||||
while (newe >= ts) {
|
||||
end = newe;
|
||||
newe = taosTimeAdd(newe, -pInterval->sliding, pInterval->slidingUnit, precision);
|
||||
}
|
||||
|
||||
start = taosTimeAdd(end, -pInterval->interval, pInterval->intervalUnit, precision) + 1;
|
||||
|
|
|
@ -182,4 +182,7 @@ int32_t isQualifiedTable(STableKeyInfo* info, SNode* pTagCond, void* metaHandle,
|
|||
|
||||
void printDataBlock(SSDataBlock* pBlock, const char* flag);
|
||||
|
||||
void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order);
|
||||
void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery);
|
||||
|
||||
#endif // TDENGINE_QUERYUTIL_H
|
||||
|
|
|
@ -1742,12 +1742,12 @@ int32_t convertFillType(int32_t mode) {
|
|||
return type;
|
||||
}
|
||||
|
||||
static void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery) {
|
||||
void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindow* w, bool ascQuery) {
|
||||
if (ascQuery) {
|
||||
*w = getAlignQueryTimeWindow(pInterval, pInterval->precision, ts);
|
||||
*w = getAlignQueryTimeWindow(pInterval, ts);
|
||||
} else {
|
||||
// the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
|
||||
*w = getAlignQueryTimeWindow(pInterval, pInterval->precision, ts);
|
||||
*w = getAlignQueryTimeWindow(pInterval, ts);
|
||||
|
||||
int64_t key = w->skey;
|
||||
while (key < ts) { // moving towards end
|
||||
|
@ -1764,7 +1764,7 @@ static void getInitialStartTimeWindow(SInterval* pInterval, TSKEY ts, STimeWindo
|
|||
static STimeWindow doCalculateTimeWindow(int64_t ts, SInterval* pInterval) {
|
||||
STimeWindow w = {0};
|
||||
|
||||
w.skey = taosTimeTruncate(ts, pInterval, pInterval->precision);
|
||||
w.skey = taosTimeTruncate(ts, pInterval);
|
||||
w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
return w;
|
||||
}
|
||||
|
@ -1798,6 +1798,7 @@ STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowI
|
|||
if (pRow) {
|
||||
w = pRow->win;
|
||||
}
|
||||
|
||||
// in case of typical time window, we can calculate time window directly.
|
||||
if (w.skey > ts || w.ekey < ts) {
|
||||
w = doCalculateTimeWindow(ts, pInterval);
|
||||
|
@ -1812,6 +1813,34 @@ STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowI
|
|||
return w;
|
||||
}
|
||||
|
||||
void getNextTimeWindow(const SInterval* pInterval, STimeWindow* tw, int32_t order) {
|
||||
int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
if (!IS_CALENDAR_TIME_DURATION(pInterval->slidingUnit)) {
|
||||
tw->skey += pInterval->sliding * factor;
|
||||
tw->ekey = taosTimeAdd(tw->skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// convert key to second
|
||||
int64_t key = convertTimePrecision(tw->skey, pInterval->precision, TSDB_TIME_PRECISION_MILLI) / 1000;
|
||||
|
||||
int64_t duration = pInterval->sliding;
|
||||
if (pInterval->slidingUnit == 'y') {
|
||||
duration *= 12;
|
||||
}
|
||||
|
||||
struct tm tm;
|
||||
time_t t = (time_t) key;
|
||||
taosLocalTime(&t, &tm, NULL);
|
||||
|
||||
int mon = (int)(tm.tm_year * 12 + tm.tm_mon + duration * factor);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision);
|
||||
|
||||
tw->ekey = taosTimeAdd(tw->skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
}
|
||||
|
||||
bool hasLimitOffsetInfo(SLimitInfo* pLimitInfo) {
|
||||
return (pLimitInfo->limit.limit != -1 || pLimitInfo->limit.offset != -1 || pLimitInfo->slimit.limit != -1 ||
|
||||
pLimitInfo->slimit.offset != -1);
|
||||
|
|
|
@ -442,15 +442,15 @@ void setBlockSMAInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock* pB
|
|||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
STimeWindow getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key) {
|
||||
STimeWindow getAlignQueryTimeWindow(const SInterval* pInterval, int64_t key) {
|
||||
STimeWindow win = {0};
|
||||
win.skey = taosTimeTruncate(key, pInterval, precision);
|
||||
win.skey = taosTimeTruncate(key, pInterval);
|
||||
|
||||
/*
|
||||
* if the realSkey > INT64_MAX - pInterval->interval, the query duration between
|
||||
* realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges.
|
||||
*/
|
||||
win.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
win.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1;
|
||||
if (win.ekey < win.skey) {
|
||||
win.ekey = INT64_MAX;
|
||||
}
|
||||
|
|
|
@ -255,10 +255,10 @@ static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t
|
|||
const char* id, SInterval* pInterval, int32_t fillType, int32_t order) {
|
||||
SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfCols, pNotFillExpr, numOfNotFillCols, pValNode);
|
||||
|
||||
STimeWindow w = {0};
|
||||
int64_t startKey = (order == TSDB_ORDER_ASC) ? win.skey : win.ekey;
|
||||
STimeWindow w = getAlignQueryTimeWindow(pInterval, pInterval->precision, startKey);
|
||||
w = getFirstQualifiedTimeWindow(startKey, &w, pInterval, order);
|
||||
|
||||
getInitialStartTimeWindow(pInterval, startKey, &w, order);
|
||||
pInfo->pFillInfo = taosCreateFillInfo(w.skey, numOfCols, numOfNotFillCols, capacity, pInterval, fillType, pColInfo,
|
||||
pInfo->primaryTsCol, order, id);
|
||||
|
||||
|
@ -400,13 +400,13 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode*
|
|||
|
||||
TSKEY getNextWindowTs(TSKEY ts, SInterval* pInterval) {
|
||||
STimeWindow win = {.skey = ts, .ekey = ts};
|
||||
getNextIntervalWindow(pInterval, &win, TSDB_ORDER_ASC);
|
||||
getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC);
|
||||
return win.skey;
|
||||
}
|
||||
|
||||
TSKEY getPrevWindowTs(TSKEY ts, SInterval* pInterval) {
|
||||
STimeWindow win = {.skey = ts, .ekey = ts};
|
||||
getNextIntervalWindow(pInterval, &win, TSDB_ORDER_DESC);
|
||||
getNextTimeWindow(pInterval, &win, TSDB_ORDER_DESC);
|
||||
return win.skey;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,39 +84,6 @@ static void switchCtxOrder(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
|
|||
}
|
||||
}
|
||||
|
||||
static void getNextTimeWindow(SInterval* pInterval, STimeWindow* tw, int32_t order) {
|
||||
int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
if (pInterval->intervalUnit != 'n' && pInterval->intervalUnit != 'y') {
|
||||
tw->skey += pInterval->sliding * factor;
|
||||
tw->ekey = tw->skey + pInterval->interval - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t key = tw->skey, interval = pInterval->interval;
|
||||
// convert key to second
|
||||
key = convertTimePrecision(key, pInterval->precision, TSDB_TIME_PRECISION_MILLI) / 1000;
|
||||
|
||||
if (pInterval->intervalUnit == 'y') {
|
||||
interval *= 12;
|
||||
}
|
||||
|
||||
struct tm tm;
|
||||
time_t t = (time_t)key;
|
||||
taosLocalTime(&t, &tm, NULL);
|
||||
|
||||
int mon = (int)(tm.tm_year * 12 + tm.tm_mon + interval * factor);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision);
|
||||
|
||||
mon = (int)(mon + interval);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->ekey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, pInterval->precision);
|
||||
|
||||
tw->ekey -= 1;
|
||||
}
|
||||
|
||||
static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockInfo, int32_t order) {
|
||||
STimeWindow w = {0};
|
||||
|
||||
|
@ -126,7 +93,7 @@ static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockIn
|
|||
}
|
||||
|
||||
if (order == TSDB_ORDER_ASC) {
|
||||
w = getAlignQueryTimeWindow(pInterval, pInterval->precision, pBlockInfo->window.skey);
|
||||
w = getAlignQueryTimeWindow(pInterval, pBlockInfo->window.skey);
|
||||
ASSERT(w.ekey >= pBlockInfo->window.skey);
|
||||
|
||||
if (w.ekey < pBlockInfo->window.ekey) {
|
||||
|
@ -145,7 +112,7 @@ static bool overlapWithTimeWindow(SInterval* pInterval, SDataBlockInfo* pBlockIn
|
|||
}
|
||||
}
|
||||
} else {
|
||||
w = getAlignQueryTimeWindow(pInterval, pInterval->precision, pBlockInfo->window.ekey);
|
||||
w = getAlignQueryTimeWindow(pInterval, pBlockInfo->window.ekey);
|
||||
ASSERT(w.skey <= pBlockInfo->window.ekey);
|
||||
|
||||
if (w.skey > pBlockInfo->window.skey) {
|
||||
|
|
|
@ -519,7 +519,7 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey)
|
|||
|
||||
pFillInfo->end = endKey;
|
||||
if (!FILL_IS_ASC_FILL(pFillInfo)) {
|
||||
pFillInfo->end = taosTimeTruncate(endKey, &pFillInfo->interval, pFillInfo->interval.precision);
|
||||
pFillInfo->end = taosTimeTruncate(endKey, &pFillInfo->interval);
|
||||
}
|
||||
|
||||
pFillInfo->index = 0;
|
||||
|
|
|
@ -270,43 +270,6 @@ int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimary
|
|||
return num;
|
||||
}
|
||||
|
||||
static void getNextTimeWindow(SInterval* pInterval, int32_t precision, int32_t order, STimeWindow* tw) {
|
||||
int32_t factor = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
if (pInterval->intervalUnit != 'n' && pInterval->intervalUnit != 'y') {
|
||||
tw->skey += pInterval->sliding * factor;
|
||||
tw->ekey = tw->skey + pInterval->interval - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t key = tw->skey, interval = pInterval->interval;
|
||||
// convert key to second
|
||||
key = convertTimePrecision(key, precision, TSDB_TIME_PRECISION_MILLI) / 1000;
|
||||
|
||||
if (pInterval->intervalUnit == 'y') {
|
||||
interval *= 12;
|
||||
}
|
||||
|
||||
struct tm tm;
|
||||
time_t t = (time_t)key;
|
||||
taosLocalTime(&t, &tm, NULL);
|
||||
|
||||
int mon = (int)(tm.tm_year * 12 + tm.tm_mon + interval * factor);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->skey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, precision);
|
||||
|
||||
mon = (int)(mon + interval);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->ekey = convertTimePrecision((int64_t)taosMktime(&tm) * 1000LL, TSDB_TIME_PRECISION_MILLI, precision);
|
||||
|
||||
tw->ekey -= 1;
|
||||
}
|
||||
|
||||
void getNextIntervalWindow(SInterval* pInterval, STimeWindow* tw, int32_t order) {
|
||||
getNextTimeWindow(pInterval, pInterval->precision, order, tw);
|
||||
}
|
||||
|
||||
void doTimeWindowInterpolation(SArray* pPrevValues, SArray* pDataBlock, TSKEY prevTs, int32_t prevRowIndex, TSKEY curTs,
|
||||
int32_t curRowIndex, TSKEY windowKey, int32_t type, SExprSupp* pSup) {
|
||||
SqlFunctionCtx* pCtx = pSup->pCtx;
|
||||
|
@ -462,7 +425,7 @@ static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext,
|
|||
bool ascQuery = (order == TSDB_ORDER_ASC);
|
||||
|
||||
int32_t precision = pInterval->precision;
|
||||
getNextTimeWindow(pInterval, precision, order, pNext);
|
||||
getNextTimeWindow(pInterval, pNext, order);
|
||||
|
||||
// next time window is not in current block
|
||||
if ((pNext->skey > pDataBlockInfo->window.ekey && order == TSDB_ORDER_ASC) ||
|
||||
|
@ -507,7 +470,7 @@ static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext,
|
|||
if (ascQuery && primaryKeys[startPos] > pNext->ekey) {
|
||||
TSKEY next = primaryKeys[startPos];
|
||||
if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
|
||||
pNext->skey = taosTimeTruncate(next, pInterval, precision);
|
||||
pNext->skey = taosTimeTruncate(next, pInterval);
|
||||
pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
} else {
|
||||
pNext->ekey += ((next - pNext->ekey + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
|
||||
|
@ -516,7 +479,7 @@ static int32_t getNextQualifiedWindow(SInterval* pInterval, STimeWindow* pNext,
|
|||
} else if ((!ascQuery) && primaryKeys[startPos] < pNext->skey) {
|
||||
TSKEY next = primaryKeys[startPos];
|
||||
if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
|
||||
pNext->skey = taosTimeTruncate(next, pInterval, precision);
|
||||
pNext->skey = taosTimeTruncate(next, pInterval);
|
||||
pNext->ekey = taosTimeAdd(pNext->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1;
|
||||
} else {
|
||||
pNext->skey -= ((pNext->skey - next + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding;
|
||||
|
@ -1377,7 +1340,7 @@ static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDa
|
|||
|
||||
do {
|
||||
if (!inCalSlidingWindow(pInterval, &win, calStTsCols[i], calEnTsCols[i])) {
|
||||
getNextTimeWindow(pInterval, pInterval->precision, TSDB_ORDER_ASC, &win);
|
||||
getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC);
|
||||
continue;
|
||||
}
|
||||
uint64_t winGpId = pGpDatas[i];
|
||||
|
@ -1389,7 +1352,7 @@ static void doDeleteWindows(SOperatorInfo* pOperator, SInterval* pInterval, SSDa
|
|||
if (pUpdatedMap) {
|
||||
tSimpleHashRemove(pUpdatedMap, &winRes, sizeof(SWinKey));
|
||||
}
|
||||
getNextTimeWindow(pInterval, pInterval->precision, TSDB_ORDER_ASC, &win);
|
||||
getNextTimeWindow(pInterval, &win, TSDB_ORDER_ASC);
|
||||
} while (win.ekey <= endTsCols[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include "taos.h"
|
||||
#include "thash.h"
|
||||
#include "tsimplehash.h"
|
||||
#include "executor.h"
|
||||
#include "ttime.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
|
||||
namespace {
|
||||
SInterval createInterval(int64_t interval, int64_t sliding, int64_t offset, char intervalUnit, char slidingUnit,
|
||||
char offsetUnit, int8_t precision) {
|
||||
SInterval v = {0};
|
||||
v.interval = interval;
|
||||
v.intervalUnit = intervalUnit;
|
||||
v.sliding = sliding;
|
||||
v.slidingUnit = slidingUnit;
|
||||
v.offset = offset;
|
||||
v.offsetUnit = offsetUnit;
|
||||
v.precision = precision;
|
||||
return v;
|
||||
}
|
||||
|
||||
void printTimeWindow(STimeWindow* pWindow, int8_t precision, int64_t ts) {
|
||||
char buf[64] = {0};
|
||||
char bufs[64] = {0};
|
||||
char bufe[64] = {0};
|
||||
|
||||
taosFormatUtcTime(buf, tListLen(buf), ts, precision);
|
||||
|
||||
taosFormatUtcTime(bufs, tListLen(bufs), pWindow->skey, precision);
|
||||
taosFormatUtcTime(bufe, tListLen(bufe), pWindow->ekey, precision);
|
||||
|
||||
printf("%s [%s - %s]\n", buf, bufs, bufe);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(testCase, timewindow_gen) {
|
||||
// set correct time zone
|
||||
osSetTimezone("UTC");
|
||||
int32_t precision = TSDB_TIME_PRECISION_MILLI;
|
||||
|
||||
SInterval interval =
|
||||
createInterval(10 * 86400 * 1000, 10 * 86400 * 1000, 0, 'd', 'd', 'd', precision);
|
||||
|
||||
int64_t key = 1659312000L * 1000; // 2022-8-1 00:00:00 // UTC+8 (ms)
|
||||
|
||||
STimeWindow w = {0};
|
||||
getInitialStartTimeWindow(&interval, key, &w, true);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&interval, &w, TSDB_ORDER_ASC);
|
||||
printf("next\n");
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
printf("---------------------------------------------------\n");
|
||||
SInterval monthInterval =
|
||||
createInterval(1, 1, 0, 'n', 'n', 'd', TSDB_TIME_PRECISION_MILLI);
|
||||
getInitialStartTimeWindow(&monthInterval, key, &w, true);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&monthInterval, &w, TSDB_ORDER_ASC);
|
||||
printf("next\n");
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
printf("----------------------------------------------------------\n");
|
||||
SInterval slidingInterval = createInterval(1, 10*86400*1000, 0, 'n', 'd', 'd', TSDB_TIME_PRECISION_MILLI);
|
||||
getInitialStartTimeWindow(&slidingInterval, key, &w, true);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printf("next\n");
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&slidingInterval, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
printf("-----------------calendar_interval_1n_sliding_1d-------\n");
|
||||
SInterval calendar_interval_1n = createInterval(1, 1*86400*1000, 0, 'n', 'd', 'd', TSDB_TIME_PRECISION_MILLI);
|
||||
int64_t k1 = 1664409600 * 1000L;
|
||||
getInitialStartTimeWindow(&calendar_interval_1n, k1, &w, true);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
printf("next\n");
|
||||
|
||||
getNextTimeWindow(&calendar_interval_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&calendar_interval_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&calendar_interval_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
getNextTimeWindow(&calendar_interval_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, key);
|
||||
|
||||
printf("----------------interval_1d_clendar_sliding_1n---------\n");
|
||||
SInterval interval_1d_calendar_sliding_1n = createInterval(1*86400*1000L, 1, 0, 'd', 'n', 'd', TSDB_TIME_PRECISION_MILLI);
|
||||
|
||||
k1 = 1664409600 * 1000L;
|
||||
getInitialStartTimeWindow(&interval_1d_calendar_sliding_1n, k1, &w, true);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
printf("next time window:\n");
|
||||
getNextTimeWindow(&interval_1d_calendar_sliding_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
getNextTimeWindow(&interval_1d_calendar_sliding_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
getNextTimeWindow(&interval_1d_calendar_sliding_1n, &w, TSDB_ORDER_ASC);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
printf("----------------interval_1d_sliding_1d_calendar_offset_1n---------\n");
|
||||
SInterval offset_1n = createInterval(10*86400*1000L, 10*86400*1000L, 1, 'd', 'd', 'n', TSDB_TIME_PRECISION_MILLI);
|
||||
getInitialStartTimeWindow(&offset_1n, k1, &w, true);
|
||||
printTimeWindow(&w, precision, k1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
|
@ -3183,7 +3183,7 @@ static int32_t checkFill(STranslateContext* pCxt, SFillNode* pFill, SValueNode*
|
|||
|
||||
int64_t timeRange = TABS(pFill->timeRange.skey - pFill->timeRange.ekey);
|
||||
int64_t intervalRange = 0;
|
||||
if (TIME_IS_VAR_DURATION(pInterval->unit)) {
|
||||
if (IS_CALENDAR_TIME_DURATION(pInterval->unit)) {
|
||||
int64_t f = 1;
|
||||
if (pInterval->unit == 'n') {
|
||||
f = 30LL * MILLISECOND_PER_DAY;
|
||||
|
@ -3264,7 +3264,7 @@ static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode*
|
|||
uint8_t precision = ((SColumnNode*)pInterval->pCol)->node.resType.precision;
|
||||
|
||||
SValueNode* pInter = (SValueNode*)pInterval->pInterval;
|
||||
bool valInter = TIME_IS_VAR_DURATION(pInter->unit);
|
||||
bool valInter = IS_CALENDAR_TIME_DURATION(pInter->unit);
|
||||
if (pInter->datum.i <= 0 || (!valInter && pInter->datum.i < tsMinIntervalTime)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_VALUE_TOO_SMALL, tsMinIntervalTime,
|
||||
getPrecisionStr(precision));
|
||||
|
@ -3278,7 +3278,7 @@ static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode*
|
|||
if (pInter->unit == 'n' && pOffset->unit == 'y') {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_OFFSET_UNIT);
|
||||
}
|
||||
bool fixed = !TIME_IS_VAR_DURATION(pOffset->unit) && !valInter;
|
||||
bool fixed = !IS_CALENDAR_TIME_DURATION(pOffset->unit) && !valInter;
|
||||
if ((fixed && pOffset->datum.i >= pInter->datum.i) ||
|
||||
(!fixed && getMonthsFromTimeVal(pOffset->datum.i, precision, pOffset->unit) >=
|
||||
getMonthsFromTimeVal(pInter->datum.i, precision, pInter->unit))) {
|
||||
|
@ -3294,7 +3294,7 @@ static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode*
|
|||
const static int32_t INTERVAL_SLIDING_FACTOR = 100;
|
||||
|
||||
SValueNode* pSliding = (SValueNode*)pInterval->pSliding;
|
||||
if (TIME_IS_VAR_DURATION(pSliding->unit)) {
|
||||
if (IS_CALENDAR_TIME_DURATION(pSliding->unit)) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SLIDING_UNIT);
|
||||
}
|
||||
if ((pSliding->datum.i < convertTimePrecision(tsMinSlidingTime, TSDB_TIME_PRECISION_MILLI, precision)) ||
|
||||
|
|
|
@ -1342,8 +1342,8 @@ static bool smaIndexOptEqualInterval(SScanLogicNode* pScan, SWindowLogicNode* pW
|
|||
.sliding = pIndex->sliding,
|
||||
.slidingUnit = pIndex->slidingUnit,
|
||||
.precision = pScan->node.precision};
|
||||
return (pScan->scanRange.skey == taosTimeTruncate(pScan->scanRange.skey, &interval, pScan->node.precision)) &&
|
||||
(pScan->scanRange.ekey + 1 == taosTimeTruncate(pScan->scanRange.ekey + 1, &interval, pScan->node.precision));
|
||||
return (pScan->scanRange.skey == taosTimeTruncate(pScan->scanRange.skey, &interval)) &&
|
||||
(pScan->scanRange.ekey + 1 == taosTimeTruncate(pScan->scanRange.ekey + 1, &interval));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue