• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #5078

17 May 2026 01:15AM UTC coverage: 73.443% (+0.04%) from 73.407%
#5078

push

travis-ci

web-flow
feat (TDgpt): Dynamic Model Synchronization Enhancements (#35344)

* refactor: do some internal refactor.

* fix: fix multiprocess sync issue.

* feat: add dynamic anomaly detection and forecasting services

* fix: log error message for undeploying model in exception handling

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: handle undeploy when model exists only on disk

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/286aafa0-c3ce-4c27-b803-2707571e9dc1

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: guard dynamic registry concurrent access

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: tighten service list locking scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: restore prophet support and update tests per review feedback

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: improve test name and move copy inside lock scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* Potential fix for pull request finding

Co-au... (continued)

281871 of 383795 relevant lines covered (73.44%)

135968015.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.63
/source/libs/executor/src/countwindowoperator.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#include "executorInt.h"
17
#include "filter.h"
18
#include "function.h"
19
#include "functionMgt.h"
20
#include "operator.h"
21
#include "querytask.h"
22
#include "tcommon.h"
23
#include "tcompare.h"
24
#include "tdatablock.h"
25
#include "ttime.h"
26

27
typedef struct SCountWindowResult {
28
  int32_t    winRows;
29
  TSKEY      winSKey;
30
  SResultRow row;
31
} SCountWindowResult;
32

33
typedef struct SCountWindowSupp {
34
  SArray* pWinStates;
35
  int32_t stateIndex;
36
  int32_t curStateIndex;
37
  TSKEY   lastTs; // this ts is used to record the last timestamp, so that we can know whether the new row's ts is duplicated
38
} SCountWindowSupp;
39

40
typedef struct SCountWindowOperatorInfo {
41
  SOptrBasicInfo     binfo;
42
  SAggSupporter      aggSup;
43
  SExprSupp          scalarSup;
44
  int32_t            tsSlotId;  // primary timestamp column slot id
45
  STimeWindowAggSupp twAggSup;
46
  uint64_t           groupId;  // current group id, used to identify the data block from different groups
47
  SResultRow*        pRow;
48
  int32_t            windowCount;
49
  int32_t            windowSliding;
50
  SCountWindowSupp   countSup;
51
  SSDataBlock*       pPreDataBlock;
52
  int32_t            preStateIndex;
53
  bool               indefRowsMode;
54
  SIndefRowsRuntime  indefRows;
55
  struct SOperatorInfo* pOperator;
56
} SCountWindowOperatorInfo;
57

58
void destroyCountWindowOperatorInfo(void* param) {
294,776✔
59
  SCountWindowOperatorInfo* pInfo = (SCountWindowOperatorInfo*)param;
294,776✔
60
  if (pInfo == NULL) {
294,776✔
61
    return;
×
62
  }
63
  cleanupBasicInfo(&pInfo->binfo);
294,776✔
64
  colDataDestroy(&pInfo->twAggSup.timeWindowData);
294,776✔
65
  cleanupIndefRowsRuntime(&pInfo->indefRows, pInfo->pOperator);
294,776✔
66

67
  cleanupAggSup(&pInfo->aggSup);
294,776✔
68
  cleanupExprSupp(&pInfo->scalarSup);
294,776✔
69
  taosArrayDestroy(pInfo->countSup.pWinStates);
294,776✔
70
  taosMemoryFreeClear(param);
294,776✔
71
}
72

73
static int32_t countWindowAggregateNext(SOperatorInfo* pOperator, SSDataBlock** ppRes);
74

75
static void clearWinStateBuff(SCountWindowResult* pBuff) {
134,851,732✔
76
  pBuff->winRows = 0;
134,851,732✔
77
  pBuff->winSKey = 0;
134,851,732✔
78
}
134,851,732✔
79

80
static SCountWindowResult* getCountWinStateInfo(SCountWindowSupp* pCountSup) {
137,713,402✔
81
  SCountWindowResult* pBuffInfo = taosArrayGet(pCountSup->pWinStates, pCountSup->stateIndex);
137,713,402✔
82
  pCountSup->curStateIndex = pCountSup->stateIndex;
137,713,402✔
83
  if (!pBuffInfo) {
137,713,402✔
84
    terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
85
    qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
×
86
    return NULL;
×
87
  }
88
  int32_t size = taosArrayGetSize(pCountSup->pWinStates);
137,713,402✔
89
  if (size == 0) {
137,713,402✔
90
    terrno = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
91
    qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
×
92
    return NULL;
×
93
  }
94
  pCountSup->stateIndex = (pCountSup->stateIndex + 1) % size;
137,713,402✔
95
  return pBuffInfo;
137,713,402✔
96
}
97

98
static int32_t setCountWindowOutputBuff(SExprSupp* pExprSup, SCountWindowSupp* pCountSup, SResultRow** pResult,
137,623,554✔
99
                                        SCountWindowResult** ppResBuff) {
100
  int32_t             code = TSDB_CODE_SUCCESS;
137,623,554✔
101
  int32_t             lino = 0;
137,623,554✔
102
  SCountWindowResult* pBuff = getCountWinStateInfo(pCountSup);
137,623,554✔
103
  QUERY_CHECK_NULL(pBuff, code, lino, _end, terrno);
137,623,554✔
104
  (*pResult) = &pBuff->row;
137,623,554✔
105
  code = setResultRowInitCtx(*pResult, pExprSup->pCtx, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset);
137,623,554✔
106
  (*ppResBuff) = pBuff;
137,623,554✔
107

108
_end:
137,623,554✔
109
  if (code != TSDB_CODE_SUCCESS) {
137,623,554✔
110
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
111
  }
112
  return code;
137,623,554✔
113
}
114

115
static int32_t updateCountWindowInfo(int32_t start, int32_t blockRows, int32_t countWinRows, int32_t* pCurrentRows) {
137,142,935✔
116
  int32_t rows = TMIN(countWinRows - (*pCurrentRows), blockRows - start);
137,142,935✔
117
  (*pCurrentRows) += rows;
137,142,935✔
118
  return rows;
137,142,935✔
119
}
120

121
void doCountWindowAggImpl(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
3,086,447✔
122
  int32_t                   code = TSDB_CODE_SUCCESS;
3,086,447✔
123
  int32_t                   lino = 0;
3,086,447✔
124
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
3,086,447✔
125
  SExprSupp*                pExprSup = &pOperator->exprSupp;
3,086,447✔
126
  SCountWindowOperatorInfo* pInfo = pOperator->info;
3,086,447✔
127
  SSDataBlock*              pRes = pInfo->binfo.pRes;
3,086,447✔
128
  SColumnInfoData*          pColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->tsSlotId);
3,086,447✔
129
  QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
3,086,447✔
130
  TSKEY* tsCols = (TSKEY*)pColInfoData->pData;
3,086,447✔
131
  int32_t numOfBuff = taosArrayGetSize(pInfo->countSup.pWinStates);
3,086,447✔
132
  if (numOfBuff == 0) {
3,086,447✔
133
    code = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
×
134
    qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
×
135
    T_LONG_JMP(pTaskInfo->env, code);
×
136
  }
137
  pInfo->countSup.stateIndex = (pInfo->preStateIndex + 1) % numOfBuff;
3,086,447✔
138

139
  int32_t newSize = pRes->info.rows + pBlock->info.rows / pInfo->windowSliding + 1;
3,086,447✔
140
  if (!pInfo->indefRowsMode && newSize > pRes->info.capacity) {
3,086,447✔
141
    code = blockDataEnsureCapacity(pRes, newSize);
×
142
    QUERY_CHECK_CODE(code, lino, _end);
×
143
  }
144

145
  for (int32_t i = 0; i < pBlock->info.rows; i++) {
2,147,483,647✔
146
    if (pBlock->info.scanFlag != PRE_SCAN) {
2,147,483,647✔
147
      if (pInfo->countSup.lastTs == INT64_MIN) {
2,147,483,647✔
148
        pInfo->countSup.lastTs = tsCols[i];
362,977✔
149
      } else {
150
        if (tsCols[i] == pInfo->countSup.lastTs) {
2,147,483,647✔
151
          qError("duplicate timestamp found in count window operator" PRId64 ", timestamp: %" PRId64, tsCols[i]);
12,225✔
152
          code = TSDB_CODE_QRY_WINDOW_DUP_TIMESTAMP;
12,225✔
153
          QUERY_CHECK_CODE(code, lino, _end);
12,225✔
154
        } else {
155
          pInfo->countSup.lastTs = tsCols[i];
2,147,483,647✔
156
        }
157
      }
158
    }
159
  }
160

161
  for (int32_t i = 0; i < pBlock->info.rows;) {
140,217,157✔
162
    SCountWindowResult* pBuffInfo = NULL;
137,142,935✔
163
    if (!pInfo->indefRowsMode) {
137,142,935✔
164
      code = setCountWindowOutputBuff(pExprSup, &pInfo->countSup, &pInfo->pRow, &pBuffInfo);
137,081,271✔
165
      if (code != TSDB_CODE_SUCCESS) {
137,081,271✔
166
        qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
167
        T_LONG_JMP(pTaskInfo->env, code);
×
168
      }
169
    } else {
170
      pBuffInfo = getCountWinStateInfo(&pInfo->countSup);
61,664✔
171
      QUERY_CHECK_NULL(pBuffInfo, code, lino, _end, terrno);
61,664✔
172
    }
173
    int32_t prevRows = pBuffInfo->winRows;
137,142,935✔
174
    int32_t num = updateCountWindowInfo(i, pBlock->info.rows, pInfo->windowCount, &pBuffInfo->winRows);
137,142,935✔
175
    int32_t step = num;
137,142,935✔
176
    if (prevRows == 0) {
137,142,935✔
177
      pBuffInfo->winSKey = tsCols[i];
134,849,812✔
178
      if (!pInfo->indefRowsMode) {
134,849,812✔
179
        pInfo->pRow->win.skey = tsCols[i];
134,788,148✔
180
      }
181
    }
182
    STimeWindow win = {.skey = pBuffInfo->winSKey, .ekey = tsCols[num + i - 1]};
137,142,935✔
183
    if (pInfo->indefRowsMode) {
137,142,935✔
184
      SIndefRowsWindowState* pState = NULL;
61,664✔
185
      code = applyIndefRowsFuncOnWindowState(pOperator, &pInfo->indefRows, &pState, pInfo->binfo.pRes,
61,664✔
186
                                             pBlock->info.id.groupId, &win, pBlock, i, num, pInfo->binfo.inputTsOrder,
187
                                             pInfo->aggSup.resultRowSize);
188
      QUERY_CHECK_CODE(code, lino, _end);
61,664✔
189
    } else {
190
      pInfo->pRow->win.ekey = win.ekey;
137,081,271✔
191
      updateTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pInfo->pRow->win, 0);
137,081,271✔
192
      code = applyAggFunctionOnPartialTuples(pTaskInfo, pExprSup->pCtx, &pInfo->twAggSup.timeWindowData, i, num,
274,162,542✔
193
                                             pBlock->info.rows, pExprSup->numOfExprs);
137,081,271✔
194
      QUERY_CHECK_CODE(code, lino, _end);
137,081,271✔
195
    }
196
    if (pInfo->windowCount != pInfo->windowSliding) {
137,142,935✔
197
      if (prevRows <= pInfo->windowSliding) {
52,601✔
198
        if (pBuffInfo->winRows > pInfo->windowSliding) {
52,601✔
199
          step = pInfo->windowSliding - prevRows;
43,254✔
200
        } else {
201
          step = pInfo->windowSliding;
9,347✔
202
        }
203
      } else {
204
        step = 0;
×
205
      }
206
    }
207
    if (pBuffInfo->winRows == pInfo->windowCount) {
137,142,935✔
208
      if (pInfo->indefRowsMode) {
134,551,328✔
209
        SIndefRowsWindowState* pState = findIndefRowsWindowState(&pInfo->indefRows, pBlock->info.id.groupId,
44,710✔
210
                                                                 pBuffInfo->winSKey);
44,710✔
211
        QUERY_CHECK_NULL(pState, code, lino, _end, TSDB_CODE_QRY_WINDOW_STATE_NOT_EXIST);
44,710✔
212
        code = closeIndefRowsWindowState(pOperator, &pInfo->indefRows, pState);
44,710✔
213
        QUERY_CHECK_CODE(code, lino, _end);
44,710✔
214
      } else {
215
        doUpdateNumOfRows(pExprSup->pCtx, pInfo->pRow, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset);
134,506,618✔
216
        code = copyResultrowToDataBlock(pExprSup->pExprInfo, pExprSup->numOfExprs, pInfo->pRow, pExprSup->pCtx, pRes,
134,506,618✔
217
                                        pExprSup->rowEntryInfoOffset, pTaskInfo);
134,506,618✔
218
        QUERY_CHECK_CODE(code, lino, _end);
134,506,618✔
219
        pRes->info.rows += pInfo->pRow->numOfRows;
134,506,618✔
220
      }
221
      clearWinStateBuff(pBuffInfo);
134,551,328✔
222
      pInfo->preStateIndex = pInfo->countSup.curStateIndex;
134,551,328✔
223
      if (!pInfo->indefRowsMode) {
134,551,328✔
224
        clearResultRowInitFlag(pExprSup->pCtx, pExprSup->numOfExprs);
134,506,618✔
225
      }
226
    }
227
    i += step;
137,142,935✔
228
  }
229

230
  if (!pInfo->indefRowsMode) {
3,074,222✔
231
    code = doFilter(pRes, pOperator->exprSupp.pFilterInfo, NULL, NULL);
3,051,867✔
232
    QUERY_CHECK_CODE(code, lino, _end);
3,051,867✔
233
  }
234

235
_end:
3,074,222✔
236
  if (code != TSDB_CODE_SUCCESS) {
3,086,447✔
237
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
12,225✔
238
    pTaskInfo->code = code;
12,225✔
239
    T_LONG_JMP(pTaskInfo->env, code);
12,225✔
240
  }
241
}
3,074,222✔
242

243
static void buildCountResult(SOperatorInfo* pOperator, SCountWindowOperatorInfo* pInfo, uint64_t groupId, SSDataBlock* pBlock) {
507,263✔
244
  SExprSupp*        pExprSup = &pOperator->exprSupp;
507,263✔
245
  SCountWindowSupp* pCountSup = &pInfo->countSup;
507,263✔
246
  SExecTaskInfo*    pTaskInfo = pOperator->pTaskInfo;
507,263✔
247
  SFilterInfo*      pFilterInfo = pOperator->exprSupp.pFilterInfo;
507,263✔
248
  SResultRow* pResultRow = NULL;
507,263✔
249
  int32_t     code = TSDB_CODE_SUCCESS;
507,263✔
250
  int32_t     lino = 0;
507,263✔
251
  int32_t     numOfBuff = taosArrayGetSize(pCountSup->pWinStates);
507,263✔
252
  int32_t     newSize = pBlock->info.rows + numOfBuff;
507,263✔
253
  if (!pInfo->indefRowsMode && newSize > pBlock->info.capacity) {
507,263✔
254
    code = blockDataEnsureCapacity(pBlock, newSize);
×
255
    QUERY_CHECK_CODE(code, lino, _end);
×
256
  }
257
  pCountSup->stateIndex = (pInfo->preStateIndex + 1) % numOfBuff;
507,263✔
258
  for (int32_t i = 0; i < numOfBuff; i++) {
1,077,730✔
259
    SCountWindowResult* pBuff = NULL;
570,467✔
260
    if (!pInfo->indefRowsMode) {
570,467✔
261
      code = setCountWindowOutputBuff(pExprSup, pCountSup, &pResultRow, &pBuff);
542,283✔
262
      QUERY_CHECK_CODE(code, lino, _end);
542,283✔
263
    } else {
264
      pBuff = getCountWinStateInfo(pCountSup);
28,184✔
265
      QUERY_CHECK_NULL(pBuff, code, lino, _end, terrno);
28,184✔
266
    }
267
    if (pBuff->winRows == 0) {
570,467✔
268
      continue;
271,983✔
269
    }
270
    if (pInfo->indefRowsMode) {
298,484✔
271
      SIndefRowsWindowState* pState = findIndefRowsWindowState(&pInfo->indefRows, groupId, pBuff->winSKey);
16,954✔
272
      QUERY_CHECK_NULL(pState, code, lino, _end, TSDB_CODE_QRY_WINDOW_STATE_NOT_EXIST);
16,954✔
273
      code = closeIndefRowsWindowState(pOperator, &pInfo->indefRows, pState);
16,954✔
274
      QUERY_CHECK_CODE(code, lino, _end);
16,954✔
275
    } else {
276
      doUpdateNumOfRows(pExprSup->pCtx, pResultRow, pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset);
281,530✔
277
      code = copyResultrowToDataBlock(pExprSup->pExprInfo, pExprSup->numOfExprs, pResultRow, pExprSup->pCtx, pBlock,
281,530✔
278
                                      pExprSup->rowEntryInfoOffset, pTaskInfo);
281,530✔
279
      QUERY_CHECK_CODE(code, lino, _end);
281,530✔
280
      pBlock->info.rows += pResultRow->numOfRows;
281,530✔
281
    }
282
    clearWinStateBuff(pBuff);
298,484✔
283
    if (!pInfo->indefRowsMode) {
298,484✔
284
      clearResultRowInitFlag(pExprSup->pCtx, pExprSup->numOfExprs);
281,530✔
285
    }
286
  }
287
  if (!pInfo->indefRowsMode) {
507,263✔
288
    code = doFilter(pBlock, pFilterInfo, NULL, NULL);
479,079✔
289
    QUERY_CHECK_CODE(code, lino, _end);
479,079✔
290
  }
291

292
_end:
507,263✔
293
  if (code != TSDB_CODE_SUCCESS) {
507,263✔
294
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
295
    T_LONG_JMP(pTaskInfo->env, code);
×
296
  }
297
}
507,263✔
298

299
static int32_t countWindowAggregateNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
581,294✔
300
  int32_t                   code = TSDB_CODE_SUCCESS;
581,294✔
301
  int32_t                   lino = 0;
581,294✔
302
  SCountWindowOperatorInfo* pInfo = pOperator->info;
581,294✔
303
  SExecTaskInfo*            pTaskInfo = pOperator->pTaskInfo;
581,294✔
304
  SExprSupp*                pExprSup = &pOperator->exprSupp;
581,294✔
305
  int32_t                   order = pInfo->binfo.inputTsOrder;
581,294✔
306
  SSDataBlock*              pRes = pInfo->binfo.pRes;
581,294✔
307

308
  if (pOperator->status == OP_EXEC_DONE) {
581,294✔
309
    *ppRes = NULL;
×
310
    return code;
×
311
  }
312

313
  if (pInfo->indefRowsMode) {
581,294✔
314
    (*ppRes) = getNextIndefRowsResultBlock(&pInfo->indefRows, pOperator);
74,346✔
315
    if ((*ppRes) != NULL) {
74,346✔
316
      return code;
22,846✔
317
    }
318
  }
319

320
  blockDataCleanup(pRes);
558,448✔
321

322
  while (1) {
3,051,867✔
323
    SSDataBlock* pBlock = NULL;
3,610,315✔
324
    if (pInfo->pPreDataBlock == NULL) { 
3,610,315✔
325
      pBlock = getNextBlockFromDownstream(pOperator, 0);
3,481,606✔
326
    } else {
327
      pBlock = pInfo->pPreDataBlock;
128,709✔
328
      pInfo->pPreDataBlock = NULL;
128,709✔
329
    }
330

331
    if (pBlock == NULL) {
3,610,315✔
332
      break;
373,162✔
333
    }
334

335
    pRes->info.scanFlag = pBlock->info.scanFlag;
3,237,153✔
336
    code = setInputDataBlock(pExprSup, pBlock, order, MAIN_SCAN, true);
3,237,153✔
337
    QUERY_CHECK_CODE(code, lino, _end);
3,237,153✔
338

339
    code = blockDataUpdateTsWindow(pBlock, pInfo->tsSlotId);
3,237,153✔
340
    QUERY_CHECK_CODE(code, lino, _end);
3,237,153✔
341

342
    // there is an scalar expression that needs to be calculated right before apply the group aggregation.
343
    if (pInfo->scalarSup.pExprInfo != NULL) {
3,237,153✔
344
      code = projectApplyFunctions(pInfo->scalarSup.pExprInfo, pBlock, pBlock, pInfo->scalarSup.pCtx,
120,762✔
345
                                   pInfo->scalarSup.numOfExprs, NULL, GET_STM_RTINFO(pOperator->pTaskInfo), pOperator->pTaskInfo);
60,381✔
346
      QUERY_CHECK_CODE(code, lino, _end);
60,381✔
347
    }
348

349
    if (pInfo->groupId == 0) {
3,220,548✔
350
      pInfo->groupId = pBlock->info.id.groupId;
2,202,858✔
351
    } else if (pInfo->groupId != pBlock->info.id.groupId) {
1,017,690✔
352
      pInfo->pPreDataBlock = pBlock;
134,101✔
353
      pRes->info.id.groupId = pInfo->groupId;
134,101✔
354
      buildCountResult(pOperator, pInfo, pInfo->groupId, pRes);
134,101✔
355
      pInfo->groupId = pBlock->info.id.groupId;
134,101✔
356
      pInfo->countSup.lastTs = INT64_MIN;
134,101✔
357
      if (pInfo->indefRowsMode) {
134,101✔
358
        (*ppRes) = getNextIndefRowsResultBlock(&pInfo->indefRows, pOperator);
11,616✔
359
        if ((*ppRes) != NULL) {
11,616✔
360
          return code;
11,616✔
361
        }
362
        continue;
×
363
      }
364
      if (pRes->info.rows > 0) {
122,485✔
365
        (*ppRes) = pRes;
122,485✔
366
        return code;
122,485✔
367
      }
368
    }
369

370
    doCountWindowAggImpl(pOperator, pBlock);
3,086,447✔
371
    if (pInfo->indefRowsMode) {
3,074,222✔
372
      (*ppRes) = getNextIndefRowsResultBlock(&pInfo->indefRows, pOperator);
22,355✔
373
      if ((*ppRes) != NULL) {
22,355✔
374
        return code;
21,864✔
375
      }
376
      continue;
491✔
377
    }
378

379
    if (pRes->info.rows >= pOperator->resultInfo.threshold) {
3,051,867✔
380
      pRes->info.id.groupId = pInfo->groupId;
491✔
381
      (*ppRes) = pRes;
491✔
382
      return code;
491✔
383
    }
384
  }
385

386
  pRes->info.id.groupId = pInfo->groupId;
373,162✔
387
  buildCountResult(pOperator, pInfo, pInfo->groupId, pRes);
373,162✔
388

389
  if (pInfo->indefRowsMode) {
373,162✔
390
    (*ppRes) = getNextIndefRowsResultBlock(&pInfo->indefRows, pOperator);
16,568✔
391
    if ((*ppRes) == NULL) {
16,568✔
392
      setOperatorCompleted(pOperator);
11,230✔
393
    }
394
    return code;
16,568✔
395
  }
396

397
_end:
356,594✔
398
  if (code != TSDB_CODE_SUCCESS) {
373,199✔
399
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
16,605✔
400
    pTaskInfo->code = code;
16,605✔
401
    T_LONG_JMP(pTaskInfo->env, code);
16,605✔
402
  }
403
  (*ppRes) = pRes->info.rows == 0 ? NULL : pRes;
356,594✔
404
  return code;
356,594✔
405
}
406

407
static int32_t resetCountWindowOperatorState(SOperatorInfo* pOper) {
1,920✔
408
  SCountWindowOperatorInfo* pCount = pOper->info;
1,920✔
409
  SExecTaskInfo*           pTaskInfo = pOper->pTaskInfo;
1,920✔
410
  SCountWindowPhysiNode* pPhynode = (SCountWindowPhysiNode*)pOper->pPhyNode;
1,920✔
411
  pOper->status = OP_NOT_OPENED;
1,920✔
412
  
413
  resetBasicOperatorState(&pCount->binfo);
1,920✔
414
  pCount->groupId = 0;
1,920✔
415
  pCount->countSup.stateIndex = 0;
1,920✔
416
  pCount->countSup.lastTs = INT64_MIN;
1,920✔
417
  pCount->pPreDataBlock = NULL;
1,920✔
418
  pCount->preStateIndex = 0;
1,920✔
419
  pCount->pRow = NULL;
1,920✔
420
  resetIndefRowsRuntime(&pCount->indefRows, pOper);
1,920✔
421
  int32_t numOfBuff = taosArrayGetSize(pCount->countSup.pWinStates);
1,920✔
422
  for (int32_t i = 0; i < numOfBuff; ++i) {
3,840✔
423
    SCountWindowResult* pBuff = taosArrayGet(pCount->countSup.pWinStates, i);
1,920✔
424
    if (pBuff != NULL) {
1,920✔
425
      clearWinStateBuff(pBuff);
1,920✔
426
      memset(&pBuff->row, 0, pCount->aggSup.resultRowSize);
1,920✔
427
    }
428
  }
429

430
  colDataDestroy(&pCount->twAggSup.timeWindowData);
1,920✔
431
  int32_t code = initExecTimeWindowInfo(&pCount->twAggSup.timeWindowData, &pTaskInfo->window);
1,920✔
432
  
433
  if (code == 0) {
1,920✔
434
    code = resetAggSup(&pOper->exprSupp, &pCount->aggSup, pTaskInfo, pPhynode->window.pFuncs, NULL,
3,840✔
435
                        sizeof(int64_t) * 2 + POINTER_BYTES, pTaskInfo->id.str, NULL,
1,920✔
436
                        &pTaskInfo->storageAPI.functionStore);
437
  }
438
  if (code == 0) {
1,920✔
439
    code = resetExprSupp(&pCount->scalarSup, pTaskInfo, pPhynode->window.pExprs, NULL,
1,920✔
440
                          &pTaskInfo->storageAPI.functionStore);
441
  }
442
  return code;
1,920✔
443
}
444

445
int32_t createCountwindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode,
294,776✔
446
                                             SExecTaskInfo* pTaskInfo, SOperatorInfo** pOptrInfo) {
447
  QRY_PARAM_CHECK(pOptrInfo);
294,776✔
448

449
  int32_t                   code = TSDB_CODE_SUCCESS;
294,776✔
450
  int32_t                   lino = 0;
294,776✔
451
  SCountWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SCountWindowOperatorInfo));
294,776✔
452
  SOperatorInfo*            pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
294,776✔
453
  if (pInfo == NULL || pOperator == NULL) {
294,776✔
454
    code = terrno;
×
455
    goto _error;
×
456
  }
457
  initOperatorCostInfo(pOperator);
294,776✔
458

459
  pOperator->pPhyNode = physiNode;
294,776✔
460
  pOperator->exprSupp.hasWindowOrGroup = true;
294,776✔
461
  pOperator->exprSupp.hasWindow = true;
294,776✔
462

463
  SCountWindowPhysiNode* pCountWindowNode = (SCountWindowPhysiNode*)physiNode;
294,776✔
464

465
  pInfo->tsSlotId = ((SColumnNode*)pCountWindowNode->window.pTspk)->slotId;
294,776✔
466

467
  if (pCountWindowNode->window.pExprs != NULL) {
294,776✔
468
    int32_t    numOfScalarExpr = 0;
71,332✔
469
    SExprInfo* pScalarExprInfo = NULL;
71,332✔
470
    code = createExprInfo(pCountWindowNode->window.pExprs, NULL, &pScalarExprInfo, &numOfScalarExpr);
71,332✔
471
    QUERY_CHECK_CODE(code, lino, _error);
71,332✔
472
    code = initExprSupp(&pInfo->scalarSup, pScalarExprInfo, numOfScalarExpr, &pTaskInfo->storageAPI.functionStore);
71,332✔
473
    QUERY_CHECK_CODE(code, lino, _error);
71,332✔
474
  }
475

476
  size_t     keyBufSize = 0;
294,776✔
477
  int32_t    num = 0;
294,776✔
478
  SExprInfo* pExprInfo = NULL;
294,776✔
479
  code = createExprInfo(pCountWindowNode->window.pFuncs, NULL, &pExprInfo, &num);
294,776✔
480
  QUERY_CHECK_CODE(code, lino, _error);
294,776✔
481

482
  initResultSizeInfo(&pOperator->resultInfo, 4096);
294,776✔
483

484
  code = initAggSup(&pOperator->exprSupp, &pInfo->aggSup, pExprInfo, num, keyBufSize, pTaskInfo->id.str,
294,776✔
485
                    NULL, &pTaskInfo->storageAPI.functionStore);
486
  QUERY_CHECK_CODE(code, lino, _error);
294,776✔
487

488
  pInfo->indefRowsMode = pCountWindowNode->window.indefRowsFunc;
294,776✔
489
  if (pInfo->indefRowsMode) {
294,776✔
490
    code = initIndefRowsRuntime(&pInfo->indefRows, pOperator->exprSupp.pCtx, num, pOperator->resultInfo.capacity);
12,682✔
491
    QUERY_CHECK_CODE(code, lino, _error);
12,682✔
492
  }
493

494
  SSDataBlock* pResBlock = createDataBlockFromDescNode(pCountWindowNode->window.node.pOutputDataBlockDesc);
294,776✔
495
  QUERY_CHECK_NULL(pResBlock, code, lino, _error, terrno);
294,776✔
496
  initBasicInfo(&pInfo->binfo, pResBlock);
294,776✔
497

498
  code = blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity);
294,776✔
499
  QUERY_CHECK_CODE(code, lino, _error);
294,776✔
500

501
  initResultRowInfo(&pInfo->binfo.resultRowInfo);
294,776✔
502
  pInfo->binfo.inputTsOrder = physiNode->inputTsOrder;
294,776✔
503
  pInfo->binfo.outputTsOrder = physiNode->outputTsOrder;
294,776✔
504
  pInfo->windowCount = pCountWindowNode->windowCount;
294,776✔
505
  pInfo->windowSliding = pCountWindowNode->windowSliding;
294,776✔
506
  // sizeof(SCountWindowResult)
507
  int32_t itemSize = sizeof(SCountWindowResult) - sizeof(SResultRow) + pInfo->aggSup.resultRowSize;
294,776✔
508
  int32_t numOfItem = 1;
294,776✔
509
  if (pInfo->windowCount != pInfo->windowSliding) {
294,776✔
510
    numOfItem = pInfo->windowCount / pInfo->windowSliding + 1;
19,950✔
511
  }
512

513
  pInfo->countSup.pWinStates = taosArrayInit_s(itemSize, numOfItem);
294,776✔
514
  if (!pInfo->countSup.pWinStates) {
294,776✔
515
    goto _error;
×
516
  }
517

518
  pInfo->countSup.stateIndex = 0;
294,776✔
519
  pInfo->pPreDataBlock = NULL;
294,776✔
520
  pInfo->preStateIndex = 0;
294,776✔
521
  pInfo->countSup.lastTs = INT64_MIN;
294,776✔
522
  pInfo->pOperator = pOperator;
294,776✔
523

524
  code = filterInitFromNode((SNode*)pCountWindowNode->window.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0,
294,776✔
525
                            pTaskInfo->pStreamRuntimeInfo);
294,776✔
526
  QUERY_CHECK_CODE(code, lino, _error);
294,776✔
527
  filterSetExecContext(pOperator->exprSupp.pFilterInfo, pTaskInfo, isTaskKilled);
294,776✔
528

529
  code = initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
294,776✔
530
  QUERY_CHECK_CODE(code, lino, _error);
294,776✔
531

532
  setOperatorInfo(pOperator, "CountWindowOperator", QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT, true, OP_NOT_OPENED, pInfo,
294,776✔
533
                  pTaskInfo);
534
  pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, countWindowAggregateNext, NULL, destroyCountWindowOperatorInfo,
294,776✔
535
                                         optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
536
  setOperatorResetStateFn(pOperator, resetCountWindowOperatorState);                                    
294,776✔
537
  code = appendDownstream(pOperator, &downstream, 1);
294,776✔
538
  if (code != TSDB_CODE_SUCCESS) {
294,776✔
539
    goto _error;
×
540
  }
541

542
  *pOptrInfo = pOperator;
294,776✔
543
  return TSDB_CODE_SUCCESS;
294,776✔
544

545
_error:
×
546
  if (pInfo != NULL) {
×
547
    destroyCountWindowOperatorInfo(pInfo);
×
548
  }
549

550
  destroyOperatorAndDownstreams(pOperator, &downstream, 1);
×
551
  pTaskInfo->code = code;
×
552
  return code;
×
553
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc