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

taosdata / TDengine / #5011

03 Apr 2026 03:59PM UTC coverage: 72.3% (+0.008%) from 72.292%
#5011

push

travis-ci

web-flow
merge: from main to 3.0 branch #35067

4053 of 5985 new or added lines in 68 files covered. (67.72%)

732 existing lines in 143 files now uncovered.

257430 of 356056 relevant lines covered (72.3%)

131834103.52 hits per line

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

79.89
/source/libs/planner/src/planUtil.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 "functionMgt.h"
17
#include "planInt.h"
18
#include "scalar.h"
19
#include "filter.h"
20

21
static char* getUsageErrFormat(int32_t errCode) {
257,831✔
22
  switch (errCode) {
257,831✔
23
    case TSDB_CODE_PLAN_EXPECTED_TS_EQUAL:
×
24
      return "primary timestamp equal condition is expected in join conditions";
×
25
    case TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN:
5,994✔
26
      return "not support cross join";
5,994✔
27
    case TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND:
82,559✔
28
      return "Not supported join conditions";
82,559✔
29
    case TSDB_CODE_PAR_NOT_SUPPORT_JOIN:
169,278✔
30
      return "Not supported join since '%s'";
169,278✔
31
    case TSDB_CODE_PLAN_SLOT_NOT_FOUND:
×
32
      return "not found slot id by slot key";
×
33
    case TSDB_CODE_PLAN_INVALID_TABLE_TYPE:
×
34
      return "Planner invalid table type";
×
35
    case TSDB_CODE_PLAN_INVALID_DYN_CTRL_TYPE:
×
36
      return "Planner invalid query control plan type";
×
NEW
37
    case TSDB_CODE_PLAN_INVALID_WINDOW_TYPE:
×
NEW
38
      return "Planner invalid window type";
×
39
    default:
×
40
      break;
×
41
  }
42
  return "Unknown error";
×
43
}
44

45
int32_t generateUsageErrMsg(char* pBuf, int32_t len, int32_t errCode, ...) {
257,831✔
46
  va_list vArgList;
257,831✔
47
  va_start(vArgList, errCode);
257,831✔
48
  (void)vsnprintf(pBuf, len, getUsageErrFormat(errCode), vArgList);
257,831✔
49
  va_end(vArgList);
257,831✔
50
  return errCode;
257,831✔
51
}
52

53
typedef struct SCreateColumnCxt {
54
  int32_t    errCode;
55
  SNodeList* pList;
56
} SCreateColumnCxt;
57

58
static EDealRes doCreateColumn(SNode* pNode, void* pContext) {
1,960,245,806✔
59
  SCreateColumnCxt* pCxt = (SCreateColumnCxt*)pContext;
1,960,245,806✔
60
  switch (nodeType(pNode)) {
1,960,245,806✔
61
    case QUERY_NODE_COLUMN: {
1,481,087,562✔
62
      SNode* pCol = NULL;
1,481,087,562✔
63
      pCxt->errCode = nodesCloneNode(pNode, &pCol);
1,481,087,671✔
64
      if (NULL == pCol) {
1,481,092,996✔
65
        return DEAL_RES_ERROR;
×
66
      }
67
      return (TSDB_CODE_SUCCESS == nodesListAppend(pCxt->pList, pCol) ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
1,481,092,996✔
68
    }
69
    case QUERY_NODE_VALUE:
426,035,326✔
70
    case QUERY_NODE_OPERATOR:
71
    case QUERY_NODE_LOGIC_CONDITION:
72
    case QUERY_NODE_FUNCTION:
73
    case QUERY_NODE_CASE_WHEN: 
74
    case QUERY_NODE_REMOTE_VALUE: {
75
      SExprNode*   pExpr = (SExprNode*)pNode;
426,035,326✔
76
      SColumnNode* pCol = NULL;
426,035,326✔
77
      pCxt->errCode = nodesMakeNode(QUERY_NODE_COLUMN, (SNode**)&pCol);
426,033,002✔
78
      if (NULL == pCol) {
426,038,780✔
79
        return DEAL_RES_ERROR;
×
80
      }
81
      pCol->node.resType = pExpr->resType;
426,038,780✔
82
      tstrncpy(pCol->colName, pExpr->aliasName, TSDB_COL_NAME_LEN);
426,037,898✔
83
      if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
426,037,232✔
84
        SFunctionNode* pFunc = (SFunctionNode*)pNode;
413,578,952✔
85
        if (pFunc->funcType == FUNCTION_TYPE_TBNAME) {
413,578,952✔
86
          SValueNode* pVal = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 0);
29,463,865✔
87
          if (NULL != pVal) {
29,463,952✔
88
            tstrncpy(pCol->tableAlias, pVal->literal, TSDB_TABLE_NAME_LEN);
588,681✔
89
            tstrncpy(pCol->tableName, pVal->literal, TSDB_TABLE_NAME_LEN);
588,681✔
90
          }
91
        }
92
      }
93
      pCol->node.relatedTo = pExpr->relatedTo;
426,037,805✔
94
      return (TSDB_CODE_SUCCESS == nodesListStrictAppend(pCxt->pList, (SNode*)pCol) ? DEAL_RES_IGNORE_CHILD
426,037,739✔
95
                                                                                    : DEAL_RES_ERROR);
426,036,217✔
96
    }
97
    default:
53,124,048✔
98
      break;
53,124,048✔
99
  }
100

101
  return DEAL_RES_CONTINUE;
53,124,048✔
102
}
103

104
int32_t createColumnByRewriteExprs(SNodeList* pExprs, SNodeList** pList) {
1,133,655,582✔
105
  SCreateColumnCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pList = *pList};
1,133,655,582✔
106
  if (!cxt.pList) {
1,133,656,103✔
107
    int32_t code = nodesMakeList(&cxt.pList);
691,354,262✔
108
    if (TSDB_CODE_SUCCESS != code) {
691,392,030✔
109
      return code;
×
110
    }
111
  }
112

113
  nodesWalkExprs(pExprs, doCreateColumn, &cxt);
1,133,693,871✔
114
  if (TSDB_CODE_SUCCESS != cxt.errCode) {
1,133,774,380✔
115
    nodesDestroyList(cxt.pList);
×
116
    return cxt.errCode;
×
117
  }
118
  if (NULL == *pList) {
1,133,777,121✔
119
    *pList = cxt.pList;
691,404,068✔
120
  }
121
  return cxt.errCode;
1,133,776,221✔
122
}
123

124
int32_t createColumnByRewriteExpr(SNode* pExpr, SNodeList** pList) {
17,654,485✔
125
  SCreateColumnCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pList = *pList};
17,654,485✔
126
  if (!cxt.pList) {
17,654,485✔
127
    int32_t code = nodesMakeList(&cxt.pList);
2,016,629✔
128
    if (TSDB_CODE_SUCCESS != code) {
2,016,629✔
129
      return code;
×
130
    }
131
  }
132

133
  nodesWalkExpr(pExpr, doCreateColumn, &cxt);
17,654,485✔
134
  if (TSDB_CODE_SUCCESS != cxt.errCode) {
17,654,485✔
135
    nodesDestroyList(cxt.pList);
×
136
    return cxt.errCode;
×
137
  }
138
  if (NULL == *pList) {
17,654,485✔
139
    *pList = cxt.pList;
2,016,629✔
140
  }
141
  return cxt.errCode;
17,654,485✔
142
}
143

144
int32_t replaceLogicNode(SLogicSubplan* pSubplan, SLogicNode* pOld, SLogicNode* pNew) {
347,048,879✔
145
  pNew->stmtRoot = pOld->stmtRoot;
347,048,879✔
146
  if (NULL == pOld->pParent) {
347,047,315✔
147
    pSubplan->pNode = (SLogicNode*)pNew;
203,475,457✔
148
    pNew->pParent = NULL;
203,475,705✔
149
    return TSDB_CODE_SUCCESS;
203,473,333✔
150
  }
151

152
  SNode* pNode;
153
  FOREACH(pNode, pOld->pParent->pChildren) {
173,614,983✔
154
    if (nodesEqualNode(pNode, (SNode*)pOld)) {
173,669,615✔
155
      REPLACE_NODE(pNew);
143,623,624✔
156
      pNew->pParent = pOld->pParent;
143,623,624✔
157
      return TSDB_CODE_SUCCESS;
143,623,663✔
158
    }
159
  }
160
  return TSDB_CODE_PLAN_INTERNAL_ERROR;
×
161
}
162

163
SLogicNode* getLogicNodeRootNode(SLogicNode* pCurr) {
26,849,323✔
164
  while (pCurr) {
62,141,723✔
165
    if (pCurr->stmtRoot || NULL == pCurr->pParent) {
62,152,472✔
166
      return pCurr;
26,860,072✔
167
    }
168

169
    pCurr = pCurr->pParent;
35,292,400✔
170
  }
171

172
  return NULL;
×
173
}
174

175

176
static int32_t adjustScanDataRequirement(SScanLogicNode* pScan, EDataOrderLevel requirement) {
448,312,033✔
177
  if ((SCAN_TYPE_TABLE != pScan->scanType && SCAN_TYPE_TABLE_MERGE != pScan->scanType) ||
448,312,033✔
178
      DATA_ORDER_LEVEL_GLOBAL == pScan->node.requireDataOrder) {
426,779,306✔
179
    return TSDB_CODE_SUCCESS;
21,517,627✔
180
  }
181
  // The lowest sort level of scan output data is DATA_ORDER_LEVEL_IN_BLOCK
182
  if (requirement < DATA_ORDER_LEVEL_IN_BLOCK) {
426,794,603✔
183
    requirement = DATA_ORDER_LEVEL_IN_BLOCK;
354,381,426✔
184
  }
185
  if (DATA_ORDER_LEVEL_IN_BLOCK == requirement || pScan->placeholderType == SP_PARTITION_TBNAME || pScan->placeholderType == SP_PARTITION_ROWS) {
426,794,603✔
186
    pScan->scanType = SCAN_TYPE_TABLE;
355,497,352✔
187
  } else if (TSDB_SUPER_TABLE == pScan->tableType) {
71,296,741✔
188
    pScan->scanType = SCAN_TYPE_TABLE_MERGE;
22,822,380✔
189
    pScan->filesetDelimited = true;
22,822,380✔
190
  }
191

192
  if (TSDB_NORMAL_TABLE != pScan->tableType && TSDB_CHILD_TABLE != pScan->tableType) {
426,794,434✔
193
    pScan->node.resultDataOrder = requirement;
117,831,668✔
194
  }
195
  return TSDB_CODE_SUCCESS;
426,794,448✔
196
}
197

198
static int32_t adjustJoinDataRequirement(SJoinLogicNode* pJoin, EDataOrderLevel requirement) {
23,533,932✔
199
  // The lowest sort level of join input and output data is DATA_ORDER_LEVEL_GLOBAL
200
  int32_t code = TSDB_CODE_SUCCESS;
23,533,932✔
201
  if (!pJoin->leftConstPrimGot) {
23,533,932✔
202
    code = adjustLogicNodeDataRequirement((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0),
23,531,340✔
203
                                          pJoin->node.requireDataOrder);
204
  } else {
205
    code =
206
        adjustScanDataRequirement((SScanLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0), DATA_ORDER_LEVEL_NONE);
3,688✔
207
  }
208
  if (TSDB_CODE_SUCCESS == code && pJoin->node.pChildren->length > 1) {
23,534,508✔
209
    if (!pJoin->rightConstPrimGot) {
23,534,681✔
210
      code = adjustLogicNodeDataRequirement((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1),
23,532,729✔
211
                                            pJoin->node.requireDataOrder);
212
    } else {
213
      code =
214
          adjustScanDataRequirement((SScanLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1), DATA_ORDER_LEVEL_NONE);
3,688✔
215
    }
216
  }
217
  if (code != TSDB_CODE_SUCCESS) {
23,534,525✔
218
    planError("adjust join input data requirement failed, err:%s", tstrerror(code));
×
219
  }
220
  return code;
23,534,879✔
221
}
222

223
static int32_t adjustAggDataRequirement(SAggLogicNode* pAgg, EDataOrderLevel requirement) {
143,345,873✔
224
  // The sort level of agg with group by output data can only be DATA_ORDER_LEVEL_NONE
225
  /* agg could meet the requirement when the primary key is const like function, so this check may be failed
226
  if (requirement > DATA_ORDER_LEVEL_NONE && (NULL != pAgg->pGroupKeys || !pAgg->onlyHasKeepOrderFunc)) {
227
    planError(
228
        "The output of aggregate cannot meet the requirements(%s) of the upper operator. "
229
        "Illegal statement, should be intercepted in parser",
230
        dataOrderStr(requirement));
231
    return TSDB_CODE_PLAN_INTERNAL_ERROR;
232
  }
233
  */
234
  pAgg->node.resultDataOrder = requirement;
143,345,873✔
235
  if (pAgg->hasTimeLineFunc) {
143,346,032✔
236
    pAgg->node.requireDataOrder = requirement < DATA_ORDER_LEVEL_IN_GROUP ? DATA_ORDER_LEVEL_IN_GROUP : requirement;
1,934,486✔
237
  }
238
  return TSDB_CODE_SUCCESS;
143,345,217✔
239
}
240

241
static int32_t adjustProjectDataRequirement(SProjectLogicNode* pProject, EDataOrderLevel requirement) {
472,831,622✔
242
  pProject->node.resultDataOrder = requirement;
472,831,622✔
243
  pProject->node.requireDataOrder = requirement;
472,832,114✔
244
  return TSDB_CODE_SUCCESS;
472,831,571✔
245
}
246

247
static int32_t adjustIntervalDataRequirement(SWindowLogicNode* pWindow, EDataOrderLevel requirement) {
17,417,987✔
248
  // The lowest sort level of interval output data is DATA_ORDER_LEVEL_IN_GROUP
249
  if (requirement < DATA_ORDER_LEVEL_IN_GROUP) {
17,417,987✔
250
    requirement = DATA_ORDER_LEVEL_IN_GROUP;
16,973,219✔
251
  }
252
  // The sort level of interval input data is always DATA_ORDER_LEVEL_IN_BLOCK
253
  pWindow->node.resultDataOrder = requirement;
17,417,987✔
254
  return TSDB_CODE_SUCCESS;
17,417,987✔
255
}
256

257
static int32_t adjustExternalDataRequirement(SWindowLogicNode* pWindow, EDataOrderLevel requirement) {
208,873✔
258
  // The lowest sort level of interval output data is DATA_ORDER_LEVEL_IN_GROUP
259
  if (requirement < DATA_ORDER_LEVEL_IN_GROUP) {
208,873✔
260
    requirement = DATA_ORDER_LEVEL_IN_GROUP;
208,873✔
261
  }
262
  // The sort level of interval input data is always DATA_ORDER_LEVEL_IN_BLOCK
263
  pWindow->node.resultDataOrder = requirement;
208,873✔
264
  return TSDB_CODE_SUCCESS;
208,873✔
265
}
266

267
static int32_t adjustSessionDataRequirement(SWindowLogicNode* pWindow, EDataOrderLevel requirement) {
5,318,593✔
268
  if (requirement <= pWindow->node.resultDataOrder) {
5,318,593✔
269
    return TSDB_CODE_SUCCESS;
5,319,428✔
270
  }
271
  pWindow->node.resultDataOrder = requirement;
×
272
  pWindow->node.requireDataOrder = requirement;
×
273
  return TSDB_CODE_SUCCESS;
×
274
}
275

276
static int32_t adjustStateDataRequirement(SWindowLogicNode* pWindow, EDataOrderLevel requirement) {
4,378,667✔
277
  if (requirement <= pWindow->node.resultDataOrder) {
4,378,667✔
278
    return TSDB_CODE_SUCCESS;
4,379,611✔
279
  }
280
  pWindow->node.resultDataOrder = requirement;
×
281
  pWindow->node.requireDataOrder = requirement;
×
282
  return TSDB_CODE_SUCCESS;
×
283
}
284

285
static int32_t adjustEventDataRequirement(SWindowLogicNode* pWindow, EDataOrderLevel requirement) {
3,880,010✔
286
  if (requirement <= pWindow->node.resultDataOrder) {
3,880,010✔
287
    return TSDB_CODE_SUCCESS;
3,880,621✔
288
  }
289
  pWindow->node.resultDataOrder = requirement;
×
290
  pWindow->node.requireDataOrder = requirement;
×
291
  return TSDB_CODE_SUCCESS;
×
292
}
293

294
static int32_t adjustCountDataRequirement(SWindowLogicNode* pWindow, EDataOrderLevel requirement) {
3,531,145✔
295
  if (requirement <= pWindow->node.resultDataOrder) {
3,531,145✔
296
    return TSDB_CODE_SUCCESS;
3,532,077✔
297
  }
298
  pWindow->node.resultDataOrder = requirement;
×
299
  pWindow->node.requireDataOrder = requirement;
×
300
  return TSDB_CODE_SUCCESS;
×
301
}
302

303
static int32_t adjustAnomalyDataRequirement(SWindowLogicNode* pWindow, EDataOrderLevel requirement) {
×
304
  if (requirement <= pWindow->node.resultDataOrder) {
×
305
    return TSDB_CODE_SUCCESS;
×
306
  }
307
  pWindow->node.resultDataOrder = requirement;
×
308
  pWindow->node.requireDataOrder = requirement;
×
309
  return TSDB_CODE_SUCCESS;
×
310
}
311

312
static int32_t adjustWindowDataRequirement(SWindowLogicNode* pWindow, EDataOrderLevel requirement) {
34,728,015✔
313
  switch (pWindow->winType) {
34,728,015✔
314
    case WINDOW_TYPE_INTERVAL:
17,416,672✔
315
      return adjustIntervalDataRequirement(pWindow, requirement);
17,416,672✔
316
    case WINDOW_TYPE_SESSION:
5,318,258✔
317
      return adjustSessionDataRequirement(pWindow, requirement);
5,318,258✔
318
    case WINDOW_TYPE_STATE:
4,379,009✔
319
      return adjustStateDataRequirement(pWindow, requirement);
4,379,009✔
320
    case WINDOW_TYPE_EVENT:
3,880,438✔
321
      return adjustEventDataRequirement(pWindow, requirement);
3,880,438✔
322
    case WINDOW_TYPE_COUNT:
3,531,593✔
323
      return adjustCountDataRequirement(pWindow, requirement);
3,531,593✔
324
    case WINDOW_TYPE_ANOMALY:
×
325
      return adjustAnomalyDataRequirement(pWindow, requirement);
×
326
    case WINDOW_TYPE_EXTERNAL:
208,873✔
327
      return adjustExternalDataRequirement(pWindow, requirement);
208,873✔
328
    default:
×
329
      break;
×
330
  }
331
  return TSDB_CODE_PLAN_INTERNAL_ERROR;
×
332
}
333

334
static int32_t adjustFillDataRequirement(SFillLogicNode* pFill, EDataOrderLevel requirement) {
435,868✔
335
  if (requirement <= pFill->node.requireDataOrder) {
435,868✔
336
    return TSDB_CODE_SUCCESS;
435,868✔
337
  }
338
  pFill->node.resultDataOrder = requirement;
×
339
  pFill->node.requireDataOrder = requirement;
×
340
  return TSDB_CODE_SUCCESS;
×
341
}
342

343
static int32_t adjustSortDataRequirement(SSortLogicNode* pSort, EDataOrderLevel requirement) {
90,122,602✔
344
  return TSDB_CODE_SUCCESS;
90,122,602✔
345
}
346

347
static int32_t adjustPartitionDataRequirement(SPartitionLogicNode* pPart, EDataOrderLevel requirement) {
40,571,721✔
348
  if (DATA_ORDER_LEVEL_GLOBAL == requirement) {
40,571,721✔
349
    planError(
×
350
        "The output of partition cannot meet the requirements(%s) of the upper operator. "
351
        "Illegal statement, should be intercepted in parser",
352
        dataOrderStr(requirement));
353
    return TSDB_CODE_PLAN_INTERNAL_ERROR;
×
354
  }
355
  pPart->node.resultDataOrder = requirement;
40,571,721✔
356
  pPart->node.requireDataOrder = requirement;
40,571,721✔
357
  return TSDB_CODE_SUCCESS;
40,571,721✔
358
}
359

360
static int32_t adjustIndefRowsDataRequirement(SIndefRowsFuncLogicNode* pIndef, EDataOrderLevel requirement) {
7,239,369✔
361
  if (requirement <= pIndef->node.resultDataOrder) {
7,239,369✔
362
    return TSDB_CODE_SUCCESS;
7,238,142✔
363
  }
364
  pIndef->node.resultDataOrder = requirement;
1,227✔
365
  pIndef->node.requireDataOrder = requirement;
1,227✔
366
  return TSDB_CODE_SUCCESS;
1,227✔
367
}
368

369
static int32_t adjustInterpDataRequirement(SInterpFuncLogicNode* pInterp, EDataOrderLevel requirement) {
3,691,630✔
370
  if (requirement <= pInterp->node.requireDataOrder) {
3,691,630✔
371
    return TSDB_CODE_SUCCESS;
3,692,062✔
372
  }
373
  pInterp->node.resultDataOrder = requirement;
×
374
  pInterp->node.requireDataOrder = requirement;
×
375
  return TSDB_CODE_SUCCESS;
×
376
}
377

378
static int32_t adjustForecastDataRequirement(SForecastFuncLogicNode* pForecast, EDataOrderLevel requirement) {
×
379
  if (requirement <= pForecast->node.requireDataOrder) {
×
380
    return TSDB_CODE_SUCCESS;
×
381
  }
382
  pForecast->node.resultDataOrder = requirement;
×
383
  pForecast->node.requireDataOrder = requirement;
×
384
  return TSDB_CODE_SUCCESS;
×
385
}
386

387
int32_t adjustLogicNodeDataRequirement(SLogicNode* pNode, EDataOrderLevel requirement) {
1,824,222,211✔
388
  int32_t code = TSDB_CODE_SUCCESS;
1,824,222,211✔
389
  switch (nodeType(pNode)) {
1,824,222,211✔
390
    case QUERY_NODE_LOGIC_PLAN_SCAN:
448,320,241✔
391
      code = adjustScanDataRequirement((SScanLogicNode*)pNode, requirement);
448,320,241✔
392
      break;
448,302,162✔
393
    case QUERY_NODE_LOGIC_PLAN_JOIN:
23,535,719✔
394
      code = adjustJoinDataRequirement((SJoinLogicNode*)pNode, requirement);
23,535,719✔
395
      return code;
23,534,971✔
396
    case QUERY_NODE_LOGIC_PLAN_AGG:
143,363,280✔
397
      code = adjustAggDataRequirement((SAggLogicNode*)pNode, requirement);
143,363,280✔
398
      break;
143,348,925✔
399
    case QUERY_NODE_LOGIC_PLAN_PROJECT:
472,848,626✔
400
      code = adjustProjectDataRequirement((SProjectLogicNode*)pNode, requirement);
472,848,626✔
401
      break;
472,833,170✔
402
    case QUERY_NODE_LOGIC_PLAN_VNODE_MODIFY:
547,542,195✔
403
    case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
404
    case QUERY_NODE_LOGIC_PLAN_MERGE:
405
      break;
547,542,195✔
406
    case QUERY_NODE_LOGIC_PLAN_WINDOW:
34,738,340✔
407
      code = adjustWindowDataRequirement((SWindowLogicNode*)pNode, requirement);
34,738,340✔
408
      break;
34,738,192✔
409
    case QUERY_NODE_LOGIC_PLAN_FILL:
435,868✔
410
      code = adjustFillDataRequirement((SFillLogicNode*)pNode, requirement);
435,868✔
411
      break;
435,868✔
412
    case QUERY_NODE_LOGIC_PLAN_SORT:
90,124,213✔
413
      code = adjustSortDataRequirement((SSortLogicNode*)pNode, requirement);
90,124,213✔
414
      break;
90,125,010✔
415
    case QUERY_NODE_LOGIC_PLAN_PARTITION:
40,577,796✔
416
      code = adjustPartitionDataRequirement((SPartitionLogicNode*)pNode, requirement);
40,577,796✔
417
      break;
40,572,608✔
418
    case QUERY_NODE_LOGIC_PLAN_INDEF_ROWS_FUNC:
7,239,369✔
419
      code = adjustIndefRowsDataRequirement((SIndefRowsFuncLogicNode*)pNode, requirement);
7,239,369✔
420
      break;
7,239,369✔
421
    case QUERY_NODE_LOGIC_PLAN_INTERP_FUNC:
3,691,198✔
422
      code = adjustInterpDataRequirement((SInterpFuncLogicNode*)pNode, requirement);
3,691,198✔
423
      break;
3,691,630✔
424
    case QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC:
19,905✔
425
    case QUERY_NODE_LOGIC_PLAN_ANALYSIS_FUNC:
426
      code = adjustForecastDataRequirement((SForecastFuncLogicNode*)pNode, requirement);
19,905✔
427
      break;
×
428
    default:
11,805,687✔
429
      break;
11,805,687✔
430
  }
431
  if (TSDB_CODE_SUCCESS == code) {
1,800,634,816✔
432
    SNode* pChild = NULL;
1,800,656,920✔
433
    FOREACH(pChild, pNode->pChildren) {
2,147,483,647✔
434
      code = adjustLogicNodeDataRequirement((SLogicNode*)pChild, pNode->requireDataOrder);
842,502,613✔
435
      if (TSDB_CODE_SUCCESS != code) {
842,511,563✔
436
        break;
×
437
      }
438
    }
439
  }
440
  return code;
1,800,634,192✔
441
}
442

443
static bool stbNotSystemScan(SLogicNode* pNode) {
381,018✔
444
  if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) {
381,018✔
445
    return SCAN_TYPE_SYSTEM_TABLE != ((SScanLogicNode*)pNode)->scanType;
343,525✔
446
  } else if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode)) {
37,493✔
447
    return stbNotSystemScan((SLogicNode*)nodesListGetNode(pNode->pChildren, 0));
×
448
  } else {
449
    return true;
37,493✔
450
  }
451
}
452

453
bool keysHasTbname(SNodeList* pKeys) {
109,589,894✔
454
  if (NULL == pKeys) {
109,589,894✔
455
    return false;
27,908,894✔
456
  }
457
  SNode* pPartKey = NULL;
81,681,000✔
458
  FOREACH(pPartKey, pKeys) {
144,699,266✔
459
    if (QUERY_NODE_GROUPING_SET == nodeType(pPartKey)) {
91,294,523✔
460
      pPartKey = nodesListGetNode(((SGroupingSetNode*)pPartKey)->pParameterList, 0);
50,496,108✔
461
    }
462
    if ((QUERY_NODE_FUNCTION == nodeType(pPartKey) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPartKey)->funcType) ||
91,294,783✔
463
        (QUERY_NODE_COLUMN == nodeType(pPartKey) && COLUMN_TYPE_TBNAME == ((SColumnNode*)pPartKey)->colType)) {
82,466,323✔
464
      return true;
28,276,517✔
465
    }
466
  }
467
  return false;
53,404,212✔
468
}
469

470
static SNodeList* stbGetPartKeys(SLogicNode* pNode) {
44,092,530✔
471
  if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) {
44,092,530✔
472
    return ((SScanLogicNode*)pNode)->pGroupTags;
34,089,825✔
473
  } else if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode)) {
10,002,705✔
474
    return ((SPartitionLogicNode*)pNode)->pPartitionKeys;
1,673,732✔
475
  } else {
476
    return NULL;
8,329,013✔
477
  }
478
}
479

480
bool isPartTableAgg(SAggLogicNode* pAgg) {
50,468,969✔
481
  if (1 != LIST_LENGTH(pAgg->node.pChildren)) {
50,468,969✔
482
    return false;
×
483
  }
484
  if (NULL != pAgg->pGroupKeys) {
50,473,094✔
485
    return (pAgg->isGroupTb || keysHasTbname(pAgg->pGroupKeys)) &&
10,314,661✔
486
           stbNotSystemScan((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0));
359,059✔
487
  }
488
  return pAgg->isPartTb || keysHasTbname(stbGetPartKeys((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0)));
40,515,032✔
489
}
490

491
static bool stbHasPartTag(SNodeList* pPartKeys) {
4,634,367✔
492
  if (NULL == pPartKeys) {
4,634,367✔
493
    return false;
3,019,869✔
494
  }
495
  SNode* pPartKey = NULL;
1,614,498✔
496
  FOREACH(pPartKey, pPartKeys) {
3,219,689✔
497
    if (QUERY_NODE_GROUPING_SET == nodeType(pPartKey)) {
2,326,440✔
498
      pPartKey = nodesListGetNode(((SGroupingSetNode*)pPartKey)->pParameterList, 0);
853,967✔
499
    }
500
    if ((QUERY_NODE_FUNCTION == nodeType(pPartKey) && FUNCTION_TYPE_TAGS == ((SFunctionNode*)pPartKey)->funcType) ||
2,326,440✔
501
        (QUERY_NODE_COLUMN == nodeType(pPartKey) && COLUMN_TYPE_TAG == ((SColumnNode*)pPartKey)->colType)) {
2,326,440✔
502
      return true;
721,249✔
503
    }
504
  }
505
  return false;
893,249✔
506
}
507

508
bool getBatchScanOptionFromHint(SNodeList* pList) {
27,247,203✔
509
  SNode* pNode = NULL;
27,247,203✔
510
  bool batchScan = true;
27,247,203✔
511
  FOREACH(pNode, pList) {
29,175,071✔
512
    SHintNode* pHint = (SHintNode*)pNode;
1,935,086✔
513
    if (pHint->option == HINT_BATCH_SCAN) {
1,935,086✔
514
      batchScan = true;
3,609✔
515
      break;
3,609✔
516
    } else if (pHint->option == HINT_NO_BATCH_SCAN) {
1,931,477✔
517
      batchScan = false;
3,609✔
518
      break;
3,609✔
519
    }
520
  }
521

522
  return batchScan;
27,247,203✔
523
}
524

525
bool getSortForGroupOptHint(SNodeList* pList) {
59,286✔
526
  if (!pList) return false;
59,286✔
527
  SNode* pNode;
528
  FOREACH(pNode, pList) {
60,250✔
529
    SHintNode* pHint = (SHintNode*)pNode;
59,286✔
530
    if (pHint->option == HINT_SORT_FOR_GROUP) {
59,286✔
531
      return true;
58,322✔
532
    }
533
  }
534
  return false;
964✔
535
}
536

537
bool getOptHint(SNodeList* pList, EHintOption hint) {
10,068,951✔
538
  if (!pList) return false;
10,068,951✔
539
  SNode* pNode;
540
  FOREACH(pNode, pList) {
1,096✔
541
    SHintNode* pHint = (SHintNode*)pNode;
1,096✔
542
    if (pHint->option == hint) {
1,096✔
543
      return true;
1,096✔
544
    }
545
  }
546
  return false;
×
547
}
548

549
bool getParaTablesSortOptHint(SNodeList* pList) {
413,047,272✔
550
  if (!pList) return false;
413,047,272✔
551
  SNode* pNode;
552
  FOREACH(pNode, pList) {
6,424,531✔
553
    SHintNode* pHint = (SHintNode*)pNode;
6,361,959✔
554
    if (pHint->option == HINT_PARA_TABLES_SORT) {
6,361,959✔
555
      return true;
6,296,125✔
556
    }
557
  }
558
  return false;
64,230✔
559
}
560

561
bool getSmallDataTsSortOptHint(SNodeList* pList) {
413,039,725✔
562
  if (!pList) return false;
413,039,725✔
563
  SNode* pNode;
564
  FOREACH(pNode, pList) {
12,721,856✔
565
    SHintNode* pHint = (SHintNode*)pNode;
6,361,959✔
566
    if (pHint->option == HINT_SMALLDATA_TS_SORT) {
6,361,959✔
567
      return true;
×
568
    }
569
  }
570
  return false;
6,360,355✔
571
}
572

573
bool getHashJoinOptHint(SNodeList* pList) {
23,274,905✔
574
  if (!pList) return false;
23,274,905✔
575
  SNode* pNode;
576
  FOREACH(pNode, pList) {
2,465,892✔
577
    SHintNode* pHint = (SHintNode*)pNode;
1,233,756✔
578
    if (pHint->option == HINT_HASH_JOIN) {
1,233,756✔
579
      return true;
818✔
580
    }
581
  }
582
  return false;
1,232,136✔
583
}
584

585

586
int32_t collectTableAliasFromNodes(SNode* pNode, SSHashObj** ppRes) {
238,306,971✔
587
  int32_t code = TSDB_CODE_SUCCESS;
238,306,971✔
588
  SLogicNode* pCurr = (SLogicNode*)pNode;
238,306,971✔
589
  FOREACH(pNode, pCurr->pTargets) {
828,360,552✔
590
    SColumnNode* pCol = (SColumnNode*)pNode;
590,051,575✔
591
    if (NULL == *ppRes) {
590,051,575✔
592
      *ppRes = tSimpleHashInit(5, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY));
198,365,844✔
593
      if (NULL == *ppRes) {
198,367,145✔
594
        return TSDB_CODE_OUT_OF_MEMORY;
×
595
      }
596
    }
597

598
    if(pCol->tableAlias[0] == '\0') {
590,052,876✔
599
      continue;
3,415,898✔
600
    }
601

602
    code = tSimpleHashPut(*ppRes, pCol->tableAlias, strlen(pCol->tableAlias), NULL, 0);
586,636,978✔
603
    if (TSDB_CODE_SUCCESS != code) {
586,637,683✔
604
      break;
×
605
    }
606
  }
607
  
608
  if (TSDB_CODE_SUCCESS == code) {
238,308,977✔
609
    FOREACH(pNode, pCurr->pChildren) {
254,956,313✔
610
      code = collectTableAliasFromNodes(pNode, ppRes);
16,638,241✔
611
      if (TSDB_CODE_SUCCESS != code) {
16,638,241✔
612
        break;
×
613
      }
614
    }
615
  }
616
  if (TSDB_CODE_SUCCESS != code) {
238,308,977✔
617
    tSimpleHashCleanup(*ppRes);
×
618
    *ppRes = NULL;
×
619
  }
620

621
  return code;
238,308,977✔
622
}
623

624
bool isPartTagAgg(SAggLogicNode* pAgg) {
4,634,367✔
625
  if (1 != LIST_LENGTH(pAgg->node.pChildren)) {
4,634,367✔
626
    return false;
×
627
  }
628
  if (pAgg->pGroupKeys) {
4,634,367✔
629
    return stbHasPartTag(pAgg->pGroupKeys) &&
792,224✔
630
      stbNotSystemScan((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0));
24,419✔
631
  }
632
  return stbHasPartTag(stbGetPartKeys((SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0)));
3,866,562✔
633
}
634

635
bool isPartTableWinodw(SWindowLogicNode* pWindow) {
8,234,435✔
636
  if ((pWindow->partType & WINDOW_PART_TB) || keysHasTbname(stbGetPartKeys((SLogicNode*)nodesListGetNode(pWindow->node.pChildren, 0)))) {
8,234,435✔
637
    return true;
1,196,231✔
638
  }
639
  return false;
7,038,734✔
640
}
641

642
int32_t cloneLimit(SLogicNode* pParent, SLogicNode* pChild, uint8_t cloneWhat, bool* pCloned) {
12,446,826✔
643
  SLimitNode* pLimit = NULL, *pSlimit = NULL;
12,446,826✔
644
  int32_t     code = 0;
12,446,826✔
645
  bool        cloned = false;
12,446,826✔
646
  if (pParent->pLimit && (cloneWhat & CLONE_LIMIT)) {
12,446,826✔
647
    code = nodesCloneNode(pParent->pLimit, (SNode**)&pLimit);
11,320,229✔
648
    if (TSDB_CODE_SUCCESS == code) {
11,319,572✔
649
      if (pLimit->limit && pLimit->offset) {
11,319,744✔
650
        pLimit->limit->datum.i += pLimit->offset->datum.i;
2,271,463✔
651
      }
652
      if (pLimit->offset) {
11,319,744✔
653
        pLimit->offset->datum.i = 0;
2,271,463✔
654
      }
655
      cloned = true;
11,319,744✔
656
    }
657
  }
658

659
  if (pParent->pSlimit && (cloneWhat & CLONE_SLIMIT)) {
12,446,169✔
660
    code = nodesCloneNode(pParent->pSlimit, (SNode**)&pSlimit);
933,655✔
661
    if (TSDB_CODE_SUCCESS == code) {
933,655✔
662
      if (pSlimit->limit && pSlimit->offset) {
933,655✔
663
        pSlimit->limit->datum.i += pSlimit->offset->datum.i;
138,520✔
664
      }
665
      if (pSlimit->offset) {
933,655✔
666
        pSlimit->offset->datum.i = 0;
138,520✔
667
      }
668
      cloned = true;
933,655✔
669
    }
670
  }
671
  if (TSDB_CODE_SUCCESS == code) {
12,446,169✔
672
    pChild->pLimit = (SNode*)pLimit;
12,446,739✔
673
    pChild->pSlimit = (SNode*)pSlimit;
12,446,739✔
674
    *pCloned = cloned;
12,446,739✔
675
  } else {
676
    nodesDestroyNode((SNode*)pLimit);
×
677
  }
678
  return code;
12,446,825✔
679
}
680

681
static EDealRes partTagsOptHasColImpl(SNode* pNode, void* pContext) {
378,450,553✔
682
  if (QUERY_NODE_COLUMN == nodeType(pNode)) {
378,450,553✔
683
    if (COLUMN_TYPE_TAG != ((SColumnNode*)pNode)->colType && COLUMN_TYPE_TBNAME != ((SColumnNode*)pNode)->colType) {
227,967,760✔
684
      *(bool*)pContext = true;
157,132,001✔
685
      return DEAL_RES_END;
157,132,001✔
686
    }
687
  }
688
  return DEAL_RES_CONTINUE;
221,318,552✔
689
}
690

691
bool keysHasCol(SNodeList* pKeys) {
230,130,553✔
692
  bool hasCol = false;
230,130,553✔
693
  nodesWalkExprs(pKeys, partTagsOptHasColImpl, &hasCol);
230,130,553✔
694
  return hasCol;
230,158,896✔
695
}
696

697
SFunctionNode* createGroupKeyAggFunc(SColumnNode* pGroupCol) {
37,418✔
698
  SFunctionNode* pFunc = NULL;
37,418✔
699
  int32_t code = nodesMakeNode(QUERY_NODE_FUNCTION, (SNode**)&pFunc);
37,418✔
700
  if (pFunc) {
37,418✔
701
    tstrncpy(pFunc->functionName, "_group_key", TSDB_FUNC_NAME_LEN);
37,418✔
702
    tstrncpy(pFunc->node.aliasName, pGroupCol->node.aliasName, TSDB_COL_NAME_LEN);
37,418✔
703
    tstrncpy(pFunc->node.userAlias, pGroupCol->node.userAlias, TSDB_COL_NAME_LEN);
37,418✔
704
    SNode* pNew = NULL;
37,418✔
705
    code = nodesCloneNode((SNode*)pGroupCol, &pNew);
37,418✔
706
    if (TSDB_CODE_SUCCESS == code) {
37,418✔
707
      code = nodesListMakeStrictAppend(&pFunc->pParameterList, pNew);
37,418✔
708
    }
709
    if (code == TSDB_CODE_SUCCESS) {
37,418✔
710
      code = fmGetFuncInfo(pFunc, NULL, 0);
37,418✔
711
    }
712
    if (TSDB_CODE_SUCCESS != code) {
37,418✔
713
      nodesDestroyNode((SNode*)pFunc);
×
714
      pFunc = NULL;
×
715
    }
716
    if (TSDB_CODE_SUCCESS == code) {
37,418✔
717
      char    name[TSDB_FUNC_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_POINTER_PRINT_BYTES + 1] = {0};
37,418✔
718
      int32_t len = snprintf(name, sizeof(name) - 1, "%s.%p", pFunc->functionName, pFunc);
37,418✔
719
      (void)taosHashBinary(name, len, sizeof(name));
720
      tstrncpy(pFunc->node.aliasName, name, TSDB_COL_NAME_LEN);
37,418✔
721
    }
722
  }
723
  if (TSDB_CODE_SUCCESS != code) {
37,418✔
724
    terrno = code;
×
725
    nodesDestroyNode((SNode*)pFunc);
×
726
    pFunc = NULL;
×
727
  }
728
  return pFunc;
37,418✔
729
}
730

731
int32_t getTimeRangeFromNode(SNode** pPrimaryKeyCond, STimeWindow* pTimeRange, bool* pIsStrict) {
×
732
  SNode*  pNew = NULL;
×
733
  int32_t code = scalarCalculateConstants(*pPrimaryKeyCond, &pNew);
×
734
  if (TSDB_CODE_SUCCESS == code) {
×
735
    *pPrimaryKeyCond = pNew;
×
736
    code = filterGetTimeRange(*pPrimaryKeyCond, pTimeRange, pIsStrict, NULL);
×
737
  }
738
  return code;
×
739
}
740

741

742
static EDealRes tagScanNodeHasTbnameFunc(SNode* pNode, void* pContext) {
16,853,498✔
743
  if (QUERY_NODE_FUNCTION == nodeType(pNode) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pNode)->funcType ||
16,853,498✔
744
        (QUERY_NODE_COLUMN == nodeType(pNode) && COLUMN_TYPE_TBNAME == ((SColumnNode*)pNode)->colType)) {
16,836,765✔
745
    *(bool*)pContext = true;
16,733✔
746
    return DEAL_RES_END;
16,733✔
747
  }
748
  return DEAL_RES_CONTINUE;
16,836,765✔
749
}
750

751
static bool tagScanNodeListHasTbname(SNodeList* pCols) {
5,311,585✔
752
  bool hasTbname = false;
5,311,585✔
753
  nodesWalkExprs(pCols, tagScanNodeHasTbnameFunc, &hasTbname);
5,311,585✔
754
  return hasTbname;
5,311,747✔
755
}
756

757
static bool tagScanNodeHasTbname(SNode* pKeys) {
×
758
  bool hasTbname = false;
×
759
  nodesWalkExpr(pKeys, tagScanNodeHasTbnameFunc, &hasTbname);
×
760
  return hasTbname;
×
761
}
762

763

764

765
int32_t tagScanSetExecutionMode(SScanLogicNode* pScan) {
9,903,358✔
766
  pScan->onlyMetaCtbIdx = false;
9,903,358✔
767

768
  if (pScan->tableType != TSDB_SUPER_TABLE) {
9,903,358✔
769
    pScan->onlyMetaCtbIdx = false;
4,592,571✔
770
    return TSDB_CODE_SUCCESS;
4,592,571✔
771
  }
772

773
  if (tagScanNodeListHasTbname(pScan->pScanPseudoCols)) {
5,310,787✔
774
    pScan->onlyMetaCtbIdx = false;
16,733✔
775
    return TSDB_CODE_SUCCESS;
16,733✔
776
  }
777

778
  if (pScan->node.pConditions == NULL) {
5,295,083✔
779
    pScan->onlyMetaCtbIdx = true;
5,295,383✔
780
    return TSDB_CODE_SUCCESS;
5,295,383✔
781
  }
782

783
  SNode* pCond = NULL;
×
784
  int32_t code = nodesCloneNode(pScan->node.pConditions, &pCond);
×
785
  if (TSDB_CODE_SUCCESS != code) {
×
786
    return code;
×
787
  }
788
  SNode* pTagCond = NULL;
×
789
  SNode* pTagIndexCond = NULL;
×
790
  code = filterPartitionCond(&pCond, NULL, &pTagIndexCond, &pTagCond, NULL);
×
791
  if (TSDB_CODE_SUCCESS == code) {
×
792
    if (pTagIndexCond || tagScanNodeHasTbname(pTagCond)) {
×
793
      pScan->onlyMetaCtbIdx = false;
×
794
    } else {
795
      pScan->onlyMetaCtbIdx = true;
×
796
    }
797
  }
798
  nodesDestroyNode(pCond);
×
799
  nodesDestroyNode(pTagIndexCond);
×
800
  nodesDestroyNode(pTagCond);
×
UNCOV
801
  return TSDB_CODE_SUCCESS;
×
802
}
803

804
bool isColRefExpr(const SColumnNode* pCol, const SExprNode* pExpr) {
890,410,508✔
805
  if (pCol->projRefIdx > 0) return pCol->projRefIdx == pExpr->projIdx;
890,410,508✔
806

807
  return 0 == strcmp(pCol->colName, pExpr->aliasName);
66,538,251✔
808
}
809

810
void rewriteTargetsWithResId(SNodeList* pTargets) {
142,072,477✔
811
  SNode* pNode;
812
  FOREACH(pNode, pTargets) {
450,042,629✔
813
    SColumnNode* pCol = (SColumnNode*)pNode;
307,970,584✔
814
    pCol->resIdx = pCol->projRefIdx;
307,970,584✔
815
  }
816
}
142,072,909✔
817

818
bool checkScanLogicNode(SLogicNode* pNode) {
16,015,345✔
819
  if (NULL == pNode) {
16,015,345✔
820
    return false;
×
821
  }
822

823
  if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) {
16,015,345✔
824
    return true;
15,527,880✔
825
  }
826

827
  SNode* node = NULL;
487,510✔
828
  FOREACH(node, pNode->pChildren) {
487,510✔
829
    if (checkScanLogicNode((SLogicNode*)node)) {
482,309✔
830
      return true;
482,309✔
831
    }
832
  }
833

834
  return false;
6,464✔
835
}
836

837
bool inStreamCalcClause(SPlanContext* pCxt) {
2,147,483,647✔
838
  return pCxt->streamCxt.isCalc;
2,147,483,647✔
839
}
840

841
bool inStreamTriggerClause(SPlanContext* pCxt) {
1,063,409,019✔
842
  return pCxt->streamCxt.isTrigger;
1,063,409,019✔
843
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc