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

taosdata / TDengine / #4908

30 Dec 2025 10:52AM UTC coverage: 65.386% (-0.2%) from 65.541%
#4908

push

travis-ci

web-flow
enh: drop multi-stream (#33962)

60 of 106 new or added lines in 4 files covered. (56.6%)

1330 existing lines in 113 files now uncovered.

193461 of 295877 relevant lines covered (65.39%)

115765274.47 hits per line

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

90.02
/source/libs/parser/src/parCalcConst.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 "parInt.h"
18
#include "scalar.h"
19
#include "ttime.h"
20

21
typedef struct SNodeReplaceContext {
22
  SNode* pTarget;
23
  SNode* pNew;
24
  bool   replaced;
25
} SNodeReplaceContext;
26

27
typedef struct SCalcConstContext {
28
  SParseContext*      pParseCxt;
29
  SNodeReplaceContext replaceCxt;
30
  SMsgBuf             msgBuf;
31
  int32_t             code;
32
} SCalcConstContext;
33

34
static int32_t calcConstQuery(SCalcConstContext* pCxt, SNode* pStmt, bool subquery);
35

36
static int32_t calcConstSubquery(SCalcConstContext* pCxt, STempTableNode* pTempTable) {
27,086,397✔
37
  return calcConstQuery(pCxt, pTempTable->pSubquery, true);
27,086,397✔
38
}
39

40
static int32_t calcConstNode(SNode** pNode) {
764,572,056✔
41
  if (NULL == *pNode) {
764,572,056✔
42
    return TSDB_CODE_SUCCESS;
637,092,035✔
43
  }
44

45
  SNode*  pNew = NULL;
127,480,598✔
46
  int32_t code = scalarCalculateConstants(*pNode, &pNew);
127,480,253✔
47
  if (TSDB_CODE_SUCCESS == code) {
127,480,623✔
48
    *pNode = pNew;
127,480,255✔
49
  }
50
  return code;
127,480,623✔
51
}
52

53
static int32_t calcConstList(SNodeList* pList) {
674,250,874✔
54
  SNode* pNode = NULL;
674,250,874✔
55
  FOREACH(pNode, pList) {
800,211,477✔
56
    SNode*  pNew = NULL;
125,960,603✔
57
    int32_t code = scalarCalculateConstants(pNode, &pNew);
125,960,603✔
58
    if (TSDB_CODE_SUCCESS == code) {
125,960,603✔
59
      REPLACE_NODE(pNew);
125,960,603✔
60
    } else {
61
      return code;
×
62
    }
63
  }
64
  return TSDB_CODE_SUCCESS;
674,252,195✔
65
}
66

67
static bool isCondition(const SNode* pNode) {
188,587,837✔
68
  if (QUERY_NODE_OPERATOR == nodeType(pNode)) {
188,587,837✔
69
    return nodesIsComparisonOp((const SOperatorNode*)pNode);
148,581,743✔
70
  }
71
  return (QUERY_NODE_LOGIC_CONDITION == nodeType(pNode));
40,006,094✔
72
}
73

74
static int32_t rewriteIsTrue(SNode* pSrc, SNode** pIsTrue) {
192,314✔
75
  SOperatorNode* pOp = NULL;
192,314✔
76
  int32_t        code = nodesMakeNode(QUERY_NODE_OPERATOR, (SNode**)&pOp);
192,314✔
77
  if (NULL == pOp) {
192,314✔
78
    return code;
×
79
  }
80
  pOp->opType = OP_TYPE_IS_TRUE;
192,314✔
81
  pOp->pLeft = pSrc;
192,314✔
82
  pOp->node.resType.type = TSDB_DATA_TYPE_BOOL;
192,314✔
83
  pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
192,314✔
84
  *pIsTrue = (SNode*)pOp;
192,314✔
85
  return TSDB_CODE_SUCCESS;
192,314✔
86
}
87

88
static EDealRes doRewriteCondition(SNode** pNode, void* pContext) {
556,286,203✔
89
  if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pNode)) {
556,286,203✔
90
    SNode* pParam = NULL;
39,818,339✔
91
    FOREACH(pParam, ((SLogicConditionNode*)*pNode)->pParameterList) {
136,335,273✔
92
      if (!isCondition(pParam)) {
96,516,867✔
93
        SNode* pIsTrue = NULL;
179,861✔
94
        if (TSDB_CODE_SUCCESS != rewriteIsTrue(pParam, &pIsTrue)) {
179,861✔
95
          ((SCalcConstContext*)pContext)->code = TSDB_CODE_OUT_OF_MEMORY;
×
96
          return DEAL_RES_ERROR;
×
97
        }
98
        REPLACE_NODE(pIsTrue);
179,861✔
99
      }
100
    }
101
  }
102
  return DEAL_RES_CONTINUE;
556,286,749✔
103
}
104

105
static int32_t rewriteCondition(SCalcConstContext* pCxt, SNode** pNode) {
92,070,970✔
106
  if (!isCondition(*pNode)) {
92,070,970✔
107
    return rewriteIsTrue(*pNode, pNode);
12,453✔
108
  }
109
  nodesRewriteExprPostOrder(pNode, doRewriteCondition, pCxt);
92,058,017✔
110
  return pCxt->code;
92,058,049✔
111
}
112

113
static int32_t calcConstCondition(SCalcConstContext* pCxt, SNode** pNode) {
4,192,712✔
114
  int32_t code = rewriteCondition(pCxt, pNode);
4,192,712✔
115
  if (TSDB_CODE_SUCCESS == code) {
4,192,712✔
116
    code = calcConstNode(pNode);
4,192,712✔
117
  }
118
  return code;
4,192,712✔
119
}
120

121
static EDealRes rewriteCalcConstValue(SNode** pNode, void* pContext) {
24,051,300✔
122
  int32_t                code = TSDB_CODE_SUCCESS;
24,051,300✔
123
  int32_t                lino = 0;
24,051,300✔
124
  SCalcConstContext* pCtx = (SCalcConstContext*)pContext;
24,051,300✔
125

126
  if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pNode)) {
24,051,300✔
127
    return DEAL_RES_CONTINUE;
3,601,610✔
128
  } else if (QUERY_NODE_OPERATOR == nodeType(*pNode)) {
20,449,690✔
129
    SOperatorNode* pOp = (SOperatorNode*)*pNode;
20,449,690✔
130
    if (OP_TYPE_EQUAL == pOp->opType && (TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode*)pOp->pLeft)->resType.type || TSDB_DATA_TYPE_TIMESTAMP == ((SExprNode*)pOp->pRight)->resType.type)) {
20,449,690✔
131
      code = calcConstNode(&pOp->pLeft);
16,256,978✔
132
      if (TSDB_CODE_SUCCESS == code) {
16,256,978✔
133
        code = calcConstNode(&pOp->pRight);
16,256,978✔
134
      }
135
      
136
      goto _end;
16,256,978✔
137
    }
138
  }
139

140
  if (TSDB_CODE_SUCCESS == code) {
4,192,712✔
141
    code = calcConstCondition(pCtx, pNode);
4,192,712✔
142
  }
143
  
144
_end:
×
145

146
  if (code != TSDB_CODE_SUCCESS) {
20,449,690✔
147
    qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
148
    return DEAL_RES_ERROR;
×
149
  }
150
  
151
  return DEAL_RES_IGNORE_CHILD;
20,449,690✔
152
}
153

154
static int32_t rewriteConditionForFromTable(SCalcConstContext* pCxt, SNode* pTable) {
254,024,670✔
155
  int32_t code = TSDB_CODE_SUCCESS;
254,024,670✔
156
  switch (nodeType(pTable)) {
254,024,670✔
157
    case QUERY_NODE_TEMP_TABLE: {
27,086,397✔
158
      code = calcConstSubquery(pCxt, (STempTableNode*)pTable);
27,086,397✔
159
      break;
27,086,397✔
160
    }
161
    case QUERY_NODE_JOIN_TABLE: {
16,764,390✔
162
      SJoinTableNode* pJoin = (SJoinTableNode*)pTable;
16,764,390✔
163
      SNode* pCond = NULL;
16,764,390✔
164
      code = rewriteConditionForFromTable(pCxt, pJoin->pLeft);
16,764,390✔
165
      if (TSDB_CODE_SUCCESS == code) {
16,763,963✔
166
        code = rewriteConditionForFromTable(pCxt, pJoin->pRight);
16,763,963✔
167
      }
168
      if (TSDB_CODE_SUCCESS == code && NULL != pJoin->pOnCond) {
16,763,963✔
169
        code = rewriteCondition(pCxt, &pJoin->pOnCond);
16,479,888✔
170
      }
171
      if (TSDB_CODE_SUCCESS == code && NULL != pJoin->pOnCond) {
16,763,963✔
172
        nodesRewriteExpr(&pJoin->pOnCond, rewriteCalcConstValue, pCxt);
16,479,888✔
173
      }
174

175
/*
176
      if (TSDB_CODE_SUCCESS == code && NULL != pJoin->pOnCond) {
177
        code = nodesCloneNode(pJoin->pOnCond, &pCond);
178
      }
179
      if (TSDB_CODE_SUCCESS == code && NULL != pJoin->pOnCond) {
180
        code = calcConstCondition(pCxt, &pJoin->pOnCond);
181
      }
182
      if (TSDB_CODE_SUCCESS == code && pJoin->pOnCond && QUERY_NODE_VALUE == nodeType(pJoin->pOnCond)) {
183
        nodesDestroyNode(pJoin->pOnCond);
184
        pJoin->pOnCond = pCond;
185
        pCond = NULL;
186
      }
187
      nodesDestroyNode(pCond);
188
*/
189
      // todo empty table
190
      break;
16,763,963✔
191
    }
192
    default:
210,173,916✔
193
      break;
210,173,916✔
194
  }
195
  return code;
254,024,276✔
196
}
197

198
static int32_t calcConstFromTable(SCalcConstContext* pCxt, SNode* pTable) {
220,496,744✔
199
  return rewriteConditionForFromTable(pCxt, pTable);
220,496,744✔
200
}
201

202
static void rewriteConstCondition(SNode** pCond, bool* pAlwaysFalse) {
71,396,477✔
203
  if (QUERY_NODE_VALUE != nodeType(*pCond)) {
71,396,477✔
204
    return;
68,058,424✔
205
  }
206
  if (((SValueNode*)*pCond)->datum.b) {
3,338,528✔
207
    nodesDestroyNode(*pCond);
3,310,298✔
208
    *pCond = NULL;
3,310,298✔
209
  } else {
210
    *pAlwaysFalse = true;
28,230✔
211
  }
212
}
213

214
static int32_t calcConstStmtCondition(SCalcConstContext* pCxt, SNode** pCond, bool* pAlwaysFalse) {
439,108,218✔
215
  if (NULL == *pCond) {
439,108,218✔
216
    return TSDB_CODE_SUCCESS;
367,710,275✔
217
  }
218

219
  int32_t code = rewriteCondition(pCxt, pCond);
71,397,961✔
220
  if (TSDB_CODE_SUCCESS == code) {
71,398,340✔
221
    code = calcConstNode(pCond);
71,398,340✔
222
  }
223
  if (TSDB_CODE_SUCCESS == code) {
71,396,915✔
224
    rewriteConstCondition(pCond, pAlwaysFalse);
71,396,952✔
225
  }
226
  return code;
71,396,982✔
227
}
228

229
static EDealRes doFindAndReplaceNode(SNode** pNode, void* pContext) {
×
230
  SCalcConstContext* pCxt = pContext;
×
231
  if (pCxt->replaceCxt.pTarget == *pNode) {
×
232
    char aliasName[TSDB_COL_NAME_LEN] = {0};
×
233
    tstrncpy(aliasName, ((SExprNode*)*pNode)->aliasName, TSDB_COL_NAME_LEN);
×
234
    nodesDestroyNode(*pNode);
×
235
    *pNode = NULL;
×
236
    pCxt->code = nodesCloneNode(pCxt->replaceCxt.pNew, pNode);
×
237
    if (NULL == *pNode) {
×
238
      return DEAL_RES_ERROR;
×
239
    }
240
    tstrncpy(((SExprNode*)*pNode)->aliasName, aliasName, TSDB_COL_NAME_LEN);
×
241

242
    pCxt->replaceCxt.replaced = true;
×
243
    return DEAL_RES_END;
×
244
  }
245
  return DEAL_RES_CONTINUE;
×
246
}
247

248
static int32_t findAndReplaceNode(SCalcConstContext* pCxt, SNode** pRoot, SNode* pTarget, SNode* pNew, bool strict) {
×
249
  pCxt->replaceCxt.pNew = pNew;
×
250
  pCxt->replaceCxt.pTarget = pTarget;
×
251

252
  nodesRewriteExprPostOrder(pRoot, doFindAndReplaceNode, pCxt);
×
253
  if (TSDB_CODE_SUCCESS == pCxt->code && strict && !pCxt->replaceCxt.replaced) {
×
254
    parserError("target replace node not found, %p", pTarget);
×
255
    return TSDB_CODE_PAR_INTERNAL_ERROR;
×
256
  }
257
  return pCxt->code;
×
258
}
259

260
static int32_t calcConstProject(SCalcConstContext* pCxt, SNode* pProject, bool dual, SNode** pNew) {
660,138,274✔
261
  SArray* pAssociation = NULL;
660,138,274✔
262
  
263
  if (NULL != ((SExprNode*)pProject)->pAssociation) {
660,138,274✔
264
    pAssociation = taosArrayDup(((SExprNode*)pProject)->pAssociation, NULL);
53,367,562✔
265
    if (NULL == pAssociation) {
53,367,562✔
UNCOV
266
      return terrno;
×
267
    }
268
  }
269

270
  char    aliasName[TSDB_COL_NAME_LEN] = {0}, srcTable[TSDB_TABLE_NAME_LEN] = {0};
660,139,140✔
271
  int32_t code = TSDB_CODE_SUCCESS;
660,138,210✔
272
  if (dual) {
660,138,210✔
273
    code = scalarCalculateConstantsFromDual(pProject, pNew);
2,945,610✔
274
  } else {
275
    code = scalarCalculateConstants(pProject, pNew);
657,192,600✔
276
  }
277
  if (TSDB_CODE_SUCCESS == code) {
660,138,323✔
278
    if (QUERY_NODE_VALUE == nodeType(*pNew) && NULL != pAssociation) {
660,135,072✔
279
      int32_t size = taosArrayGetSize(pAssociation);
2,306,192✔
280
      for (int32_t i = 0; i < size; ++i) {
4,616,428✔
281
        SAssociationNode* pAssNode = taosArrayGet(pAssociation, i);
2,310,236✔
282
        SNode**           pCol = pAssNode->pPlace;
2,310,236✔
283
        if (((SExprNode*)pAssNode->pAssociationNode)->joinSrc) {
2,310,236✔
284
          //((SExprNode*)pAssNode->pAssociationNode)->constValue = true;
285
          continue;
684✔
286
        }
287
        
288
        if (*pCol == pAssNode->pAssociationNode) {
2,309,552✔
289
          tstrncpy(aliasName, ((SExprNode*)*pCol)->aliasName, TSDB_COL_NAME_LEN);
2,309,552✔
290
          if (QUERY_NODE_COLUMN == nodeType(*pCol)) {
2,309,552✔
291
            tstrncpy(srcTable, ((SColumnNode*)*pCol)->tableAlias, TSDB_TABLE_NAME_LEN);
2,309,552✔
292
          }
293
          SArray* pOrigAss = NULL;
2,309,552✔
294
          TSWAP(((SExprNode*)*pCol)->pAssociation, pOrigAss);
2,309,552✔
295
          nodesDestroyNode(*pCol);
2,309,552✔
296
          *pCol = NULL;
2,309,552✔
297
          code = nodesCloneNode(*pNew, pCol);
2,309,552✔
298
          if (TSDB_CODE_SUCCESS == code) {
2,309,552✔
299
            tstrncpy(((SExprNode*)*pCol)->aliasName, aliasName, TSDB_COL_NAME_LEN);
2,309,552✔
300
            if (srcTable[0]) {
2,309,552✔
301
              tstrncpy(((SExprNode*)*pCol)->srcTable, srcTable, TSDB_TABLE_NAME_LEN);
2,309,552✔
302
            }
303
            TSWAP(pOrigAss, ((SExprNode*)*pCol)->pAssociation);
2,309,552✔
304
          }
305
          taosArrayDestroy(pOrigAss);
2,309,552✔
306
          if (TSDB_CODE_SUCCESS != code) {
2,309,552✔
307
            break;
×
308
          }
309
        } else {
310
          code = findAndReplaceNode(pCxt, pCol, pAssNode->pAssociationNode, *pNew, true);
×
311
          if (TSDB_CODE_SUCCESS != code) {
×
312
            break;
×
313
          }
314
        }
315
      }
316
    }
317
  }
318
  taosArrayDestroy(pAssociation);
660,138,340✔
319
  return code;
660,137,876✔
320
}
321

322
typedef struct SIsUselessColCtx {
323
  bool isUseless;
324
} SIsUselessColCtx;
325

326
EDealRes checkUselessCol(SNode* pNode, void* pContext) {
209,511,339✔
327
  SIsUselessColCtx* ctx = (SIsUselessColCtx*)pContext;
209,511,339✔
328
  if (QUERY_NODE_FUNCTION == nodeType(pNode) && !fmIsScalarFunc(((SFunctionNode*)pNode)->funcId) &&
209,511,339✔
329
      !fmIsPseudoColumnFunc(((SFunctionNode*)pNode)->funcId)) {
16,960,870✔
330
    ctx->isUseless = false;
14,387,993✔
331
    return DEAL_RES_END;
14,387,993✔
332
  }
333

334
  return DEAL_RES_CONTINUE;
195,123,346✔
335
}
336

337
static bool isUselessCol(SExprNode* pProj) {
172,702,651✔
338
  SIsUselessColCtx ctx = {.isUseless = true};
172,702,651✔
339
  nodesWalkExpr((SNode*)pProj, checkUselessCol, (void*)&ctx);
172,702,651✔
340
  if (!ctx.isUseless) {
172,702,651✔
341
    return false;
14,387,993✔
342
  }
343
  return NULL == ((SExprNode*)pProj)->pAssociation;
158,314,658✔
344
}
345

346
static int32_t createConstantValue(SValueNode** ppNode) {
235,723✔
347
  SValueNode* pVal = NULL;
235,723✔
348
  int32_t     code = nodesMakeNode(QUERY_NODE_VALUE, (SNode**)&pVal);
235,723✔
349
  if (NULL == pVal) {
235,723✔
350
    return code;
×
351
  }
352
  pVal->node.resType.type = TSDB_DATA_TYPE_INT;
235,723✔
353
  pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_INT].bytes;
235,723✔
354
  const int32_t val = 1;
235,723✔
355
  code = nodesSetValueNodeValue(pVal, (void*)&val);
235,723✔
356
  if (TSDB_CODE_SUCCESS == code) {
235,723✔
357
    pVal->translate = true;
235,723✔
358
    *ppNode = pVal;
235,723✔
359
  } else {
360
    nodesDestroyNode((SNode*)pVal);
×
361
  }
362
  return code;
235,723✔
363
}
364

365
static int32_t calcConstProjections(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) {
220,907,820✔
366
  SNode* pProj = NULL;
220,907,820✔
367
  WHERE_EACH(pProj, pSelect->pProjectionList) {
993,511,741✔
368
    if (subquery && !pSelect->isDistinct && !pSelect->tagScan && isUselessCol((SExprNode*)pProj) && (pSelect->pFromTable && nodeType(pSelect->pFromTable) != QUERY_NODE_VIRTUAL_TABLE)) {
772,605,177✔
369
      ERASE_NODE(pSelect->pProjectionList);
112,468,773✔
370
      continue;
112,468,773✔
371
    }
372
    SNode*  pNew = NULL;
660,136,404✔
373
    int32_t code = calcConstProject(pCxt, pProj, (NULL == pSelect->pFromTable), &pNew);
660,137,340✔
374
    if (TSDB_CODE_SUCCESS == code) {
660,139,180✔
375
      REPLACE_NODE(pNew);
660,135,954✔
376
    } else {
377
      return code;
3,263✔
378
    }
379
    WHERE_NEXT;
660,135,359✔
380
  }
381
  if (0 == LIST_LENGTH(pSelect->pProjectionList)) {
220,905,469✔
382
    SValueNode* pVal = NULL;
232,460✔
383
    int32_t     code = createConstantValue(&pVal);
231,956✔
384
    if (TSDB_CODE_SUCCESS == code) {
231,993✔
385
      return nodesListStrictAppend(pSelect->pProjectionList, (SNode*)pVal);
231,993✔
386
    }
387
  }
388
  return TSDB_CODE_SUCCESS;
220,672,484✔
389
}
390

391
static int32_t calcConstGroupBy(SCalcConstContext* pCxt, SSelectStmt* pSelect) {
218,822,719✔
392
  int32_t code = calcConstList(pSelect->pGroupByList);
218,822,719✔
393
  if (TSDB_CODE_SUCCESS == code) {
218,822,745✔
394
    SNode* pNode = NULL;
218,822,730✔
395
    FOREACH(pNode, pSelect->pGroupByList) {
247,366,204✔
396
      bool   hasNotValue = false;
28,543,474✔
397
      SNode* pGroupPara = NULL;
28,543,474✔
398
      FOREACH(pGroupPara, ((SGroupingSetNode*)pNode)->pParameterList) {
30,391,850✔
399
        if (QUERY_NODE_VALUE != nodeType(pGroupPara)) {
28,543,474✔
400
          hasNotValue = true;
26,695,098✔
401
          break;
26,695,098✔
402
        }
403
      }
404
      if (!hasNotValue) {
28,543,474✔
405
        if (pSelect->hasAggFuncs) {
1,848,376✔
406
          ERASE_NODE(pSelect->pGroupByList);
30,878✔
407
        } else {
408
          if (!cell->pPrev && !cell->pNext) continue;
1,817,498✔
409
          ERASE_NODE(pSelect->pGroupByList);
×
410
        }
411
      }
412
    }
413
  }
414
  return code;
218,823,733✔
415
}
416

417
static int32_t calcConstSelectWithoutFrom(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) {
2,084,138✔
418
  return calcConstProjections(pCxt, pSelect, subquery);
2,084,138✔
419
}
420

421
static int32_t calcConstSelectFrom(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) {
218,963,431✔
422
  int32_t code = calcConstFromTable(pCxt, pSelect->pFromTable);
218,963,431✔
423
  if (TSDB_CODE_SUCCESS == code && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
218,963,351✔
424
      ((STempTableNode*)pSelect->pFromTable)->pSubquery != NULL &&
26,834,017✔
425
      QUERY_NODE_SELECT_STMT == nodeType(((STempTableNode*)pSelect->pFromTable)->pSubquery) &&
26,834,017✔
426
      ((SSelectStmt*)((STempTableNode*)pSelect->pFromTable)->pSubquery)->isEmptyResult) {
23,242,362✔
427
    pSelect->isEmptyResult = true;
139,915✔
428
    return code;
139,915✔
429
  }
430
  if (pSelect->mixSysTableAndActualTable) {
218,823,898✔
431
    return code;
281✔
432
  }
433
  if (TSDB_CODE_SUCCESS == code) {
218,823,676✔
434
    code = calcConstProjections(pCxt, pSelect, subquery);
218,824,419✔
435
  }
436
  if (TSDB_CODE_SUCCESS == code) {
218,822,873✔
437
    code = calcConstStmtCondition(pCxt, &pSelect->pWhere, &pSelect->isEmptyResult);
218,823,616✔
438
  }
439
  if (TSDB_CODE_SUCCESS == code) {
218,822,255✔
440
    code = calcConstList(pSelect->pPartitionByList);
218,822,218✔
441
  }
442
  if (TSDB_CODE_SUCCESS == code) {
218,822,730✔
443
    code = calcConstNode(&pSelect->pWindow);
218,822,693✔
444
  }
445
  if (TSDB_CODE_SUCCESS == code) {
218,822,360✔
446
    code = calcConstGroupBy(pCxt, pSelect);
218,822,360✔
447
  }
448
  if (TSDB_CODE_SUCCESS == code) {
218,822,726✔
449
    code = calcConstStmtCondition(pCxt, &pSelect->pHaving, &pSelect->isEmptyResult);
218,823,111✔
450
  }
451
  if (TSDB_CODE_SUCCESS == code) {
218,823,093✔
452
    code = calcConstList(pSelect->pOrderByList);
218,823,093✔
453
  }
454
  if (TSDB_CODE_SUCCESS == code) {
218,822,652✔
455
    code = calcConstNode(&pSelect->pFill);
218,822,689✔
456
  }
457
  if (TSDB_CODE_SUCCESS == code) {
218,823,000✔
458
    code = calcConstNode(&pSelect->pTimeRange);
218,823,037✔
459
  }
460
  return code;
218,823,547✔
461
}
462

463

464
static bool isEmptyResultQuery(SNode* pStmt) {
215,513,493✔
465
  bool isEmptyResult = false;
215,513,493✔
466
  switch (nodeType(pStmt)) {
215,513,493✔
467
    case QUERY_NODE_SELECT_STMT:
118,258,010✔
468
      isEmptyResult = ((SSelectStmt*)pStmt)->isEmptyResult;
118,258,010✔
469
      break;
118,257,985✔
470
    case QUERY_NODE_EXPLAIN_STMT:
11,862,595✔
471
      isEmptyResult = isEmptyResultQuery(((SExplainStmt*)pStmt)->pQuery);
11,862,595✔
472
      break;
11,865,454✔
473
    case QUERY_NODE_SET_OPERATOR: {
5,856,147✔
474
      SSetOperator* pSetOp = (SSetOperator*)pStmt;
5,856,147✔
475
      isEmptyResult = isEmptyResultQuery(pSetOp->pLeft);
5,856,147✔
476
      if (isEmptyResult) {
5,856,147✔
477
        isEmptyResult = isEmptyResultQuery(pSetOp->pRight);
448✔
478
      }
479
      break;
5,856,147✔
480
    }
481
    case QUERY_NODE_DELETE_STMT:
1,465,746✔
482
      isEmptyResult = ((SDeleteStmt*)pStmt)->deleteZeroRows;
1,465,746✔
483
      break;
1,461,397✔
484
    default:
78,075,498✔
485
      break;
78,075,498✔
486
  }
487
  return isEmptyResult;
215,516,395✔
488
}
489

490
static int32_t calcSubQueries(SCalcConstContext* pCxt, SNodeList* pSubQueries) {
19,719,010✔
491
  int32_t code = TSDB_CODE_SUCCESS;
19,719,010✔
492
  SNode* pNode = NULL;
19,719,010✔
493
  FOREACH(pNode, pSubQueries) {
77,564,021✔
494
    code = calcConstQuery(pCxt, pNode, false);
57,845,011✔
495
    if (code) {
57,845,011✔
496
      break;
×
497
    }
498
/*
499
    if (isEmptyResultQuery(pNode) && nodesIsScalarSubQuery(pNode)) {
500
      // TODO
501
      parserError("%" PRIx64 " scalar subquery got empty result", pCxt->pParseCxt->requestId);
502
      code = TSDB_CODE_PAR_INVALID_SCALAR_SUBQ_RES_ROWS;
503
      break;
504
    }
505
*/
506
  }
507

508
  return code;
19,719,010✔
509
}
510

511
static int32_t calcConstSelect(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) {
221,048,031✔
512
  int32_t code = TSDB_CODE_SUCCESS;
221,048,031✔
513
  
514
  if (NULL == pSelect->pFromTable) {
221,048,031✔
515
    code = calcConstSelectWithoutFrom(pCxt, pSelect, subquery);
2,084,138✔
516
  } else {
517
    code = calcConstSelectFrom(pCxt, pSelect, subquery);
218,963,784✔
518
  }
519

520
  if (TSDB_CODE_SUCCESS == code && pSelect->pSubQueries && pSelect->pSubQueries->length > 0) {
221,047,855✔
521
    code = calcSubQueries(pCxt, pSelect->pSubQueries);
18,923,113✔
522
  }
523

524
  return code;
221,047,408✔
525
}
526

527
static int32_t calcConstDelete(SCalcConstContext* pCxt, SDeleteStmt* pDelete) {
1,461,397✔
528
  int32_t code = calcConstFromTable(pCxt, pDelete->pFromTable);
1,461,397✔
529
  if (TSDB_CODE_SUCCESS == code) {
1,461,397✔
530
    code = calcConstStmtCondition(pCxt, &pDelete->pWhere, &pDelete->deleteZeroRows);
1,461,397✔
531
  }
532
  if (code == TSDB_CODE_SUCCESS && pDelete->timeRange.skey > pDelete->timeRange.ekey) {
1,461,397✔
533
    pDelete->deleteZeroRows = true;
172,979✔
534
  }
535
  return code;
1,461,397✔
536
}
537

538
static int32_t calcConstInsert(SCalcConstContext* pCxt, SInsertStmt* pInsert) {
71,454✔
539
  int32_t code = calcConstFromTable(pCxt, pInsert->pTable);
71,454✔
540
  if (TSDB_CODE_SUCCESS == code) {
71,454✔
541
    code = calcConstQuery(pCxt, pInsert->pQuery, false);
71,454✔
542
  }
543
  return code;
71,454✔
544
}
545

546
static SNodeList* getChildProjection(SNode* pStmt) {
5,478,024✔
547
  switch (nodeType(pStmt)) {
5,478,024✔
548
    case QUERY_NODE_SELECT_STMT:
5,441,752✔
549
      return ((SSelectStmt*)pStmt)->pProjectionList;
5,441,752✔
550
    case QUERY_NODE_SET_OPERATOR:
36,272✔
551
      return ((SSetOperator*)pStmt)->pProjectionList;
36,272✔
552
    default:
×
553
      break;
×
554
  }
555
  return NULL;
×
556
}
557

558
static void eraseSetOpChildProjection(SSetOperator* pSetOp, int32_t index) {
1,368,257✔
559
  SNodeList* pLeftProjs = getChildProjection(pSetOp->pLeft);
1,368,257✔
560
  (void)nodesListErase(pLeftProjs, nodesListGetCell(pLeftProjs, index));
1,368,257✔
561
  if (QUERY_NODE_SET_OPERATOR == nodeType(pSetOp->pLeft)) {
1,368,257✔
562
    eraseSetOpChildProjection((SSetOperator*)pSetOp->pLeft, index);
17,912✔
563
  }
564
  SNodeList* pRightProjs = getChildProjection(pSetOp->pRight);
1,368,257✔
565
  (void)nodesListErase(pRightProjs, nodesListGetCell(pRightProjs, index));
1,368,257✔
566
  if (QUERY_NODE_SET_OPERATOR == nodeType(pSetOp->pRight)) {
1,368,257✔
567
    eraseSetOpChildProjection((SSetOperator*)pSetOp->pRight, index);
×
568
  }
569
}
1,368,257✔
570

571
typedef struct SNotRefByOrderByCxt {
572
  SColumnNode* pCol;
573
  bool         hasThisCol;
574
} SNotRefByOrderByCxt;
575

576
static EDealRes notRefByOrderByImpl(SNode* pNode, void* pContext) {
9,479,006✔
577
  if (QUERY_NODE_COLUMN == nodeType(pNode)) {
9,479,006✔
578
    SNotRefByOrderByCxt* pCxt = (SNotRefByOrderByCxt*)pContext;
4,739,503✔
579
    if (nodesEqualNode((SNode*)pCxt->pCol, pNode)) {
4,739,503✔
580
      pCxt->hasThisCol = true;
1,582,746✔
581
      return DEAL_RES_END;
1,582,746✔
582
    }
583
  }
584
  return DEAL_RES_CONTINUE;
7,896,260✔
585
}
586

587
static bool notRefByOrderBy(SColumnNode* pCol, SNodeList* pOrderByList) {
5,198,758✔
588
  SNotRefByOrderByCxt cxt = {.pCol = pCol, .hasThisCol = false};
5,198,758✔
589
  nodesWalkExprs(pOrderByList, notRefByOrderByImpl, &cxt);
5,198,758✔
590
  return !cxt.hasThisCol;
5,198,758✔
591
}
592

593
static bool isDistinctSubQuery(SNode* pNode) {
2,847,602✔
594
  if (NULL == pNode) {
2,847,602✔
595
    return false;
×
596
  }
597
  switch (nodeType(pNode)) {
2,847,602✔
598
    case QUERY_NODE_SELECT_STMT:
2,775,042✔
599
      return ((SSelectStmt*)pNode)->isDistinct;
2,775,042✔
600
    case QUERY_NODE_SET_OPERATOR:
72,560✔
601
      return isDistinctSubQuery((((SSetOperator*)pNode)->pLeft)) || isDistinctSubQuery((((SSetOperator*)pNode)->pLeft));
72,560✔
602
    default:
×
603
      break;
×
604
  }
605
  return false;
×
606
}
607

608
static bool isSetUselessCol(SSetOperator* pSetOp, int32_t index, SExprNode* pProj) {
3,616,012✔
609
  if (!isUselessCol(pProj)) {
3,616,012✔
610
    return false;
2,226,639✔
611
  }
612

613
  SNodeList* pLeftProjs = getChildProjection(pSetOp->pLeft);
1,389,373✔
614
  if (!isUselessCol((SExprNode*)nodesListGetNode(pLeftProjs, index)) || isDistinctSubQuery(pSetOp->pLeft)) {
1,389,373✔
615
    return false;
37,236✔
616
  }
617

618
  SNodeList* pRightProjs = getChildProjection(pSetOp->pRight);
1,352,137✔
619
  if (!isUselessCol((SExprNode*)nodesListGetNode(pRightProjs, index)) || isDistinctSubQuery(pSetOp->pLeft)) {
1,352,137✔
620
    return false;
1,792✔
621
  }
622

623
  return true;
1,350,345✔
624
}
625

626
static int32_t calcConstSetOpProjections(SCalcConstContext* pCxt, SSetOperator* pSetOp, bool subquery) {
17,783,298✔
627
  if (subquery && pSetOp->opType == SET_OP_TYPE_UNION) {
17,783,298✔
628
    return TSDB_CODE_SUCCESS;
1,767,949✔
629
  }
630
  int32_t index = 0;
16,015,349✔
631
  SNode*  pProj = NULL;
16,015,349✔
632
  WHERE_EACH(pProj, pSetOp->pProjectionList) {
40,649,081✔
633
    if (subquery && notRefByOrderBy((SColumnNode*)pProj, pSetOp->pOrderByList) &&
28,249,744✔
634
        isSetUselessCol(pSetOp, index, (SExprNode*)pProj)) {
3,616,012✔
635
      ERASE_NODE(pSetOp->pProjectionList);
1,350,345✔
636
      eraseSetOpChildProjection(pSetOp, index);
1,350,345✔
637
      continue;
1,350,345✔
638
    }
639
    ++index;
23,283,387✔
640
    WHERE_NEXT;
23,283,387✔
641
  }
642
  if (0 == LIST_LENGTH(pSetOp->pProjectionList)) {
16,015,349✔
643
    SValueNode* pVal = NULL;
3,730✔
644
    int32_t     code = createConstantValue(&pVal);
3,730✔
645
    if (TSDB_CODE_SUCCESS == code) {
3,730✔
646
      return nodesListStrictAppend(pSetOp->pProjectionList, (SNode*)pVal);
3,730✔
647
    }
648
  }
649
  return TSDB_CODE_SUCCESS;
16,011,619✔
650
}
651

652
static int32_t calcConstSetOperator(SCalcConstContext* pCxt, SSetOperator* pSetOp, bool subquery) {
17,783,298✔
653
  int32_t code = calcConstSetOpProjections(pCxt, pSetOp, subquery);
17,783,298✔
654
  if (TSDB_CODE_SUCCESS == code) {
17,783,298✔
655
    code = calcConstQuery(pCxt, pSetOp->pLeft, false);
17,783,298✔
656
  }
657
  if (TSDB_CODE_SUCCESS == code) {
17,783,298✔
658
    code = calcConstQuery(pCxt, pSetOp->pRight, false);
17,783,298✔
659
  }
660
  if (TSDB_CODE_SUCCESS == code) {
17,783,298✔
661
    code = calcConstList(pSetOp->pOrderByList);
17,783,298✔
662
  }
663
  if (TSDB_CODE_SUCCESS == code && pSetOp->pSubQueries && pSetOp->pSubQueries->length > 0) {
17,783,298✔
664
    code = calcSubQueries(pCxt, pSetOp->pSubQueries);
795,897✔
665
  }
666
  
667
  return code;
17,783,298✔
668
}
669

670
static int32_t calcConstQuery(SCalcConstContext* pCxt, SNode* pStmt, bool subquery) {
330,231,899✔
671
  int32_t code = TSDB_CODE_SUCCESS;
330,231,899✔
672
  switch (nodeType(pStmt)) {
330,231,899✔
673
    case QUERY_NODE_SELECT_STMT:
221,047,941✔
674
      code = calcConstSelect(pCxt, (SSelectStmt*)pStmt, subquery);
221,047,941✔
675
      break;
221,047,350✔
676
    case QUERY_NODE_EXPLAIN_STMT:
11,862,595✔
677
      code = calcConstQuery(pCxt, ((SExplainStmt*)pStmt)->pQuery, subquery);
11,862,595✔
678
      break;
11,863,902✔
679
    case QUERY_NODE_SET_OPERATOR: {
17,783,298✔
680
      code = calcConstSetOperator(pCxt, (SSetOperator*)pStmt, subquery);
17,783,298✔
681
      break;
17,783,298✔
682
    }
683
    case QUERY_NODE_DELETE_STMT:
1,461,397✔
684
      code = calcConstDelete(pCxt, (SDeleteStmt*)pStmt);
1,461,397✔
685
      break;
1,461,397✔
686
    case QUERY_NODE_INSERT_STMT:
74,066✔
687
      code = calcConstInsert(pCxt, (SInsertStmt*)pStmt);
74,066✔
688
      break;
71,454✔
689
    default:
78,008,197✔
690
      break;
78,008,197✔
691
  }
692
  return code;
330,235,598✔
693
}
694

695

696
static void resetProjectNullTypeImpl(SNodeList* pProjects) {
116,246,340✔
697
  SNode* pProj = NULL;
116,246,340✔
698
  FOREACH(pProj, pProjects) {
604,851,278✔
699
    SExprNode* pExpr = (SExprNode*)pProj;
488,606,034✔
700
    if (TSDB_DATA_TYPE_NULL == pExpr->resType.type) {
488,606,034✔
701
      pExpr->resType.type = TSDB_DATA_TYPE_VARCHAR;
307,677✔
702
      pExpr->resType.bytes = VARSTR_HEADER_SIZE;
307,677✔
703
      if (QUERY_NODE_VALUE == nodeType(pExpr)) {
307,677✔
704
        ((SValueNode*)pExpr)->isNull = true;
12,845✔
705
      }
706
    }
707
  }
708
}
116,245,432✔
709

710
static void resetProjectNullType(SNode* pStmt) {
207,635,737✔
711
  switch (nodeType(pStmt)) {
207,635,737✔
712
    case QUERY_NODE_SELECT_STMT:
111,325,508✔
713
      resetProjectNullTypeImpl(((SSelectStmt*)pStmt)->pProjectionList);
111,325,508✔
714
      break;
111,324,884✔
715
    case QUERY_NODE_SET_OPERATOR: {
4,929,925✔
716
      SSetOperator* pSetOp = (SSetOperator*)pStmt;
4,929,925✔
717
      resetProjectNullTypeImpl(pSetOp->pProjectionList);
4,929,925✔
718
      if (pSetOp->pLeft)
4,920,617✔
719
        resetProjectNullType(pSetOp->pLeft);
4,920,617✔
720
      if (pSetOp->pRight)
4,920,617✔
721
        resetProjectNullType(pSetOp->pRight);
4,920,617✔
722
      break;
4,920,617✔
723
    }
724
    default:
91,384,920✔
725
      break;
91,384,920✔
726
  }
727
}
207,630,421✔
728

729
static int32_t rewriteScalarSubQResValue(SParseContext* pParseCxt, SQuery* pQuery) {
197,782,984✔
730
  // TODO
731
  return TSDB_CODE_SUCCESS;
197,782,984✔
732
}
733

734
int32_t calculateConstant(SParseContext* pParseCxt, SQuery* pQuery) {
197,801,356✔
735
  SCalcConstContext cxt = {.pParseCxt = pParseCxt,
197,801,356✔
736
                           .msgBuf.buf = pParseCxt->pMsg,
197,792,830✔
737
                           .msgBuf.len = pParseCxt->msgLen,
197,802,480✔
738
                           .code = TSDB_CODE_SUCCESS};
739

740
  int32_t code = TSDB_CODE_SUCCESS;
197,791,924✔
741

742
  if (TSDB_CODE_SUCCESS == code) {
197,791,924✔
743
    code = calcConstQuery(&cxt, pQuery->pRoot, false);
197,779,124✔
744
  }
745
  if (TSDB_CODE_SUCCESS == code) {
197,790,923✔
746
    resetProjectNullType(pQuery->pRoot);
197,787,764✔
747
    if (isEmptyResultQuery(pQuery->pRoot)) {
197,781,618✔
748
      pQuery->execMode = QUERY_EXEC_MODE_EMPTY_RESULT;
470,878✔
749
    }
750
    code = rewriteScalarSubQResValue(pParseCxt, pQuery);
197,784,220✔
751
  }
752
  
753
  return code;
197,783,475✔
754
}
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